Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;

public abstract class AttributeInfo {
public static final String CODE = "Code";
public static final String CONST_VALUE = "ConstantValue";
public static final String EXCEPTIONS = "Exceptions";
public static final String LINE_NUM_TABLE = "LineNumberTable";
public static final String LOCAL_VAR_TABLE = "LocalVariableTable";
public static final String STACK_MAP_TABLE = "StackMapTable";
int attrNameIndex;
int attrLen ;
public AttributeInfo(int attrNameIndex, int attrLen) {

this.attrNameIndex = attrNameIndex;
this.attrLen = attrLen;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;


import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile;
import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator;

public class CodeAttr extends AttributeInfo {
private int maxStack ;
private int maxLocals ;
private int codeLen ;
private String code;
public String getCode() {
return code;
}

//private ByteCodeCommand[] cmds ;
//public ByteCodeCommand[] getCmds() {
// return cmds;
//}
private LineNumberTable lineNumTable;
private LocalVariableTable localVarTable;
private StackMapTable stackMapTable;

public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) {
super(attrNameIndex, attrLen);
this.maxStack = maxStack;
this.maxLocals = maxLocals;
this.codeLen = codeLen;
this.code = code;
//this.cmds = cmds;
}

public void setLineNumberTable(LineNumberTable t) {
this.lineNumTable = t;
}

public void setLocalVariableTable(LocalVariableTable t) {
this.localVarTable = t;
}

public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){

//回退2个字节
iter.back(ByteCodeIterator.U2);
int attrNameIndex = iter.readTwoBytesToInt();
int attrLen = iter.readFourBytesToInt();
int maxStack = iter.readTwoBytesToInt();
int maxLocal = iter.readTwoBytesToInt();
int codeLen = iter.readFourBytesToInt();
String code = iter.readBytesToString(codeLen);
CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocal, codeLen, code);

//异常表长度
int exceptionTableLen = iter.readTwoBytesToInt();
if (exceptionTableLen > 0) {
throw new RuntimeException("not impl yet");
}

//子属性个数
int attrCount = iter.readTwoBytesToInt();
for (int i = 0; i < attrCount; i++) {
attrNameIndex = iter.readTwoBytesToInt();
String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex);
if ("LineNumberTable".equals(attrName)) {
LineNumberTable lineNumberTable = LineNumberTable.parse(iter);
codeAttr.setLineNumberTable(lineNumberTable);
} else if ("LocalVariableTable".equals(attrName)) {
LocalVariableTable localVariableTable = LocalVariableTable.parse(iter);
codeAttr.setLocalVariableTable(localVariableTable);
} else if ("StackMapTable".equals(attrName)) {
StackMapTable stackMapTable = StackMapTable.parse(iter);
codeAttr.setStackMapTable(stackMapTable);
} else {
throw new RuntimeException("not impl yet");
}
}

return codeAttr;
}

private void setStackMapTable(StackMapTable t) {
this.stackMapTable = t;
}





}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;

import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator;

import java.util.ArrayList;
import java.util.List;


public class LineNumberTable extends AttributeInfo {
List<LineNumberItem> items = new ArrayList<LineNumberItem>();

private static class LineNumberItem{
int startPC;
int lineNum;
public int getStartPC() {
return startPC;
}
public void setStartPC(int startPC) {
this.startPC = startPC;
}
public int getLineNum() {
return lineNum;
}
public void setLineNum(int lineNum) {
this.lineNum = lineNum;
}
}
public void addLineNumberItem(LineNumberItem item){
this.items.add(item);
}
public LineNumberTable(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);
}

public static LineNumberTable parse(ByteCodeIterator iter){
iter.back(ByteCodeIterator.U2);
int attrNameIndex = iter.readTwoBytesToInt();
int attrLen = iter.readFourBytesToInt();
LineNumberTable lineNumberTable = new LineNumberTable(attrNameIndex, attrLen);
int itemCount = iter.readTwoBytesToInt();
for (int i = 0; i < itemCount; i++) {
LineNumberItem lineNumberItem = new LineNumberItem();
lineNumberItem.setStartPC(iter.readTwoBytesToInt());
lineNumberItem.setLineNum(iter.readTwoBytesToInt());
lineNumberTable.addLineNumberItem(lineNumberItem);
}
return lineNumberTable;
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;

public class LocalVariableItem {
private int startPC;
private int length;
private int nameIndex;
private int descIndex;
private int index;
public int getStartPC() {
return startPC;
}
public void setStartPC(int startPC) {
this.startPC = startPC;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getNameIndex() {
return nameIndex;
}
public void setNameIndex(int nameIndex) {
this.nameIndex = nameIndex;
}
public int getDescIndex() {
return descIndex;
}
public void setDescIndex(int descIndex) {
this.descIndex = descIndex;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;


import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator;

import java.util.ArrayList;
import java.util.List;

public class LocalVariableTable extends AttributeInfo{

List<LocalVariableItem> items = new ArrayList<LocalVariableItem>();

public LocalVariableTable(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);
}

public static LocalVariableTable parse(ByteCodeIterator iter){
iter.back(ByteCodeIterator.U2);
int attrNameIdex = iter.readTwoBytesToInt();
int attrLen = iter.readFourBytesToInt();
LocalVariableTable localVariableTable = new LocalVariableTable(attrNameIdex, attrLen);
int varCount = iter.readTwoBytesToInt();
for (int i = 0; i < varCount; i++) {
LocalVariableItem item = new LocalVariableItem();
item.setStartPC(iter.readTwoBytesToInt());
item.setLength(iter.readTwoBytesToInt());
item.setNameIndex(iter.readTwoBytesToInt());
item.setDescIndex(iter.readTwoBytesToInt());
item.setIndex(iter.readTwoBytesToInt());
localVariableTable.addLocalVariableItem(item);
}
return localVariableTable;
}
private void addLocalVariableItem(LocalVariableItem item) {
this.items.add(item);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.coding.mini_jvm.src.com.coderising.jvm.attr;


import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator;

public class StackMapTable extends AttributeInfo{

private String originalCode;

public StackMapTable(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);
}

public static StackMapTable parse(ByteCodeIterator iter){
iter.back(ByteCodeIterator.U2);
int index = iter.readTwoBytesToInt();
int len = iter.readFourBytesToInt();
StackMapTable t = new StackMapTable(index,len);

//后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存
String code = iter.readBytesToString(len);
t.setOriginalCode(code);
return t;
}

private void setOriginalCode(String code) {
this.originalCode = code;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,50 @@

import com.coding.mini_jvm.src.com.coderising.jvm.constant.ClassInfo;
import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool;
import com.coding.mini_jvm.src.com.coderising.jvm.field.Field;
import com.coding.mini_jvm.src.com.coderising.jvm.method.Method;

import java.util.ArrayList;
import java.util.List;

public class ClassFile {

private int minorVersion;
private int majorVersion;

private AccessFlag accessFlag;
private ClassIndex clzIndex;
private ConstantPool pool;


private List<Field> fields = new ArrayList<Field>();
private List<Method> methods = new ArrayList<Method>();

public ClassIndex getClzIndex() {
return clzIndex;
}

public AccessFlag getAccessFlag() {
return accessFlag;
}

public void setAccessFlag(AccessFlag accessFlag) {
this.accessFlag = accessFlag;
}



public void addField(Field f) {
this.fields.add(f);
}

public List<Field> getFields() {
return this.fields;
}

public void addMethod(Method m) {
this.methods.add(m);
}

public List<Method> getMethods() {
return methods;
}

public ConstantPool getConstantPool() {
return pool;
Expand All @@ -49,19 +71,12 @@ public void setClassIndex(ClassIndex clzIndex) {
this.clzIndex = clzIndex;
}




public void print(){

if(this.accessFlag.isPublicClass()){
System.out.println("Access flag : public ");
}
System.out.println("Class Name:"+ getClassName());

System.out.println("Super Class Name:"+ getSuperClassName());


}

private String getClassName(){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.coding.mini_jvm.src.com.coderising.jvm.field;


import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool;
import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator;

public class Field {
private int accessFlag;
private int nameIndex;
private int descriptorIndex;


private ConstantPool pool;

public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool pool) {
this.accessFlag = accessFlag;
this.nameIndex = nameIndex;
this.descriptorIndex = descriptorIndex;
this.pool = pool;
}


public static Field parse(ConstantPool pool,ByteCodeIterator iter){
int accessFlag = iter.readTwoBytesToInt();
int nameIndex = iter.readTwoBytesToInt();
int descIndex = iter.readTwoBytesToInt();
int attributesCount = iter.readTwoBytesToInt();
if (attributesCount > 0)
throw new RuntimeException("attributeCount of field not impl");
return new Field(accessFlag, nameIndex, descIndex, pool);
}


@Override
public String toString() {
return pool.getUTF8String(nameIndex)+":"+pool.getUTF8String(descriptorIndex);
}
}
Loading