ClassLoader

This commit is contained in:
Imgaojp 2017-02-21 19:18:15 +08:00
parent 6233862b56
commit 675d9fd807
32 changed files with 2096 additions and 101 deletions

View File

@ -14,6 +14,7 @@ import com.gabongao.jvm.classfile.MemberInfo;
import com.gabongao.jvm.instructions.*;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.Thread;
import com.gabongao.jvm.rtda.heap.Method;
/**
*            + +
@ -58,6 +59,20 @@ public class Interpreter {
}
}
public void doInterpreter(Method method) {
Thread thread = new Thread();
Frame frame = new Frame(thread, method);
thread.pushFrame(frame);
try {
loop(thread, method.getCode());
} catch (Exception e) {
e.printStackTrace();
System.out.println();
System.out.printf("LocalVars: %s\n", frame.getLocalVars());
System.out.printf("OperandStack: %s\n", frame.getOperandStack());
}
}
public void loop(Thread thread, byte[] byteCode) {
Frame frame = thread.popFrame();
BytecodeReader bytecodeReader = new BytecodeReader();
@ -65,13 +80,13 @@ public class Interpreter {
for (; ; ) {
int pc = frame.getNextPc();
thread.setPc(pc);
System.out.printf("loop: %2d\t", n);
System.out.printf("loop: %6d\t", n);
bytecodeReader.reset(byteCode, pc);
char opcode = (char) bytecodeReader.readInt8();
Instruction instruction = Factory.newInstruction((byte) opcode);
instruction.fetchOperands(bytecodeReader);
frame.setNextPc(bytecodeReader.getPc());
System.out.printf("pc:%2d\t inst:%s\n", pc, instruction.getClass().getName());
System.out.printf("pc:%3d\t inst:%s\n", pc, instruction.getClass().getName());
instruction.execute(frame);
n++;
}

View File

@ -6,6 +6,9 @@ import com.gabongao.jvm.classpath.ClassPath;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.LocalVars;
import com.gabongao.jvm.rtda.OperandStack;
import com.gabongao.jvm.rtda.heap.ClassLoader;
import com.gabongao.jvm.rtda.heap.ClassStruct;
import com.gabongao.jvm.rtda.heap.Method;
/**
*            + +
@ -52,11 +55,11 @@ public class Jvm {
/* ch02
ClassPath cp = new ClassPath();
cp.parse(cmd.jreOption, cmd.cpOption);
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.className, Arrays.asList(cmd.args));
String className = cmd.className.replace(".", "/").concat(".class");
byte[] classData = cp.readClass(className);
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.getClassName, Arrays.asList(cmd.args));
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
byte[] classData = cp.readClass(getClassName);
if (classData == null) {
System.out.printf("Could not load main class %s\n",className);
System.out.printf("Could not load main class %s\n",getClassName);
System.exit(1);
}
for (byte b:classData
@ -69,10 +72,10 @@ public class Jvm {
/* ch03
ClassPath cp = new ClassPath();
cp.parse(cmd.jreOption, cmd.cpOption);
String className = cmd.className.replace(".", "/").concat(".class");
ClassFile classFile = new ClassFile(cp.readClass(className));
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
ClassFile classFile = new ClassFile(cp.readClass(getClassName));
classFile.read();
System.out.println(cmd.className);
System.out.println(cmd.getClassName);
printClassInfo(classFile);
}
@ -95,24 +98,48 @@ public class Jvm {
}
*/
/* ch04
// ch04
/*
Frame frame = new Frame(100, 100);
testLocalVars(frame.getLocalVars());
testOperandStack(frame.getOperandStack());
*/
//ch05
// Interpreter interpreter = new Interpreter();
// ClassPath cp = new ClassPath();
// cp.parse(cmd.jreOption, cmd.cpOption);
// String className = cmd.className.replace(".", "/").concat(".class");
// ClassFile classFile = loadClass(className, cp);
// classFile.read();
// MemberInfo mainMethod = getMainMethod(classFile);
// if (mainMethod != null) {
// interpreter.doInterpreter(mainMethod);
// } else {
// System.out.printf("Main method not found in class %s\n", className);
// }
Interpreter interpreter = new Interpreter();
ClassPath cp = new ClassPath();
ClassLoader classLoader = new ClassLoader(cp);
cp.parse(cmd.jreOption, cmd.cpOption);
String className = cmd.className.replace(".", "/").concat(".class");
ClassFile classFile = loadClass(className, cp);
classFile.read();
MemberInfo mainMethod = getMainMethod(classFile);
// String className = cmd.className.replace(".", "/").concat(".class");
String className = cmd.className;
ClassStruct mainClass = classLoader.loadClass(className);
Method mainMethod = mainClass.getMainMethod();
// ClassFile classFile = loadClass(className, cp);
// classFile.read();
// MemberInfo mainMethod = getMainMethod(classFile);
if (mainMethod != null) {
interpreter.doInterpreter(mainMethod);
} else {
System.out.printf("Main method not found in class %s\n", className);
}
}
public static MemberInfo getMainMethod(ClassFile classFile) {

View File

@ -33,30 +33,30 @@ package com.gabongao.jvm.classfile;
* Created by Imgaojp on 2017/2/18.
*/
public class ClassFile {
static final int CONSTANT_Class = 7;
static final int CONSTANT_Fieldref = 9;
static final int CONSTANT_Methodref = 10;
static final int CONSTANT_InterfaceMethodref = 11;
static final int CONSTANT_String = 8;
static final int CONSTANT_Integer = 3;
static final int CONSTANT_Float = 4;
static final int CONSTANT_Long = 5;
static final int CONSTANT_Double = 6;
static final int CONSTANT_NameAndType = 12;
static final int CONSTANT_Utf8 = 1;
static final int CONSTANT_MethodHandle = 15;
static final int CONSTANT_MethodType = 16;
static final int CONSTANT_InvokeDynamic = 18;
char majorVersion;
ConstantPool constantPool;
char accessFlags;
char thisClass;
char superClass;
char[] interfaces;
MemberInfo[] fields;
MemberInfo[] methods;
AttributeInfo[] attributes;
ClassReader classReader;
private static final int CONSTANT_Class = 7;
private static final int CONSTANT_Fieldref = 9;
private static final int CONSTANT_Methodref = 10;
private static final int CONSTANT_InterfaceMethodref = 11;
private static final int CONSTANT_String = 8;
private static final int CONSTANT_Integer = 3;
private static final int CONSTANT_Float = 4;
private static final int CONSTANT_Long = 5;
private static final int CONSTANT_Double = 6;
private static final int CONSTANT_NameAndType = 12;
private static final int CONSTANT_Utf8 = 1;
private char majorVersion;
private ConstantPool constantPool;
private char accessFlags;
private char thisClass;
private char superClass;
private char[] interfaces;
private MemberInfo[] fields;
private MemberInfo[] methods;
private AttributeInfo[] attributes;
private ClassReader classReader;
private char minorVersion;
public ClassFile(byte[] classData) {
@ -107,6 +107,7 @@ public class ClassFile {
public void read() {
readAndCheckMagic();
readAndCheckVersion();
constantPool = new ConstantPool();
constantPool = readConstantPool();
accessFlags = classReader.readUint16();
thisClass = classReader.readUint16();
@ -136,16 +137,17 @@ public class ClassFile {
public ConstantPool readConstantPool() {
int cpCount = classReader.readUint16();
// constantPool.constantInfos = new ConstantInfo[cpCount];
ConstantInfo[] constantInfos = new ConstantInfo[cpCount];
// ConstantPool cp = new ConstantPool();
for (int i = 1; i < cpCount; i++) {
constantInfos[i] = readConstantInfo();
if (constantInfos[i] instanceof ConstantLongInfo || constantInfos[i] instanceof ConstantDoubleInfo) {
i++;
}
}
ConstantPool cp = new ConstantPool();
cp.setConstantInfos(constantInfos);
return cp;
constantPool.setConstantInfos(constantInfos);
return constantPool;
}
public ConstantInfo readConstantInfo() {
@ -176,7 +178,7 @@ public class ClassFile {
case CONSTANT_Methodref:
return new ConstantMethodrefInfo(constantPool);
case CONSTANT_InterfaceMethodref:
return new ConstantInterfaceMemberrefInfo(constantPool);
return new ConstantInterfaceMethodrefInfo(constantPool);
case CONSTANT_NameAndType:
return new ConstantNameAndTypeInfo();
// case CONSTANT_MethodType:
@ -223,12 +225,16 @@ public class ClassFile {
return "";
}
//todo:return null
public String[] interfaceNames() {
String[] interfaceNames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
interfaceNames[i] = constantPool.getClassName(interfaces[i]);
if ((interfaces != null)) {
String[] interfaceNames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
interfaceNames[i] = constantPool.getClassName(interfaces[i]);
}
return interfaceNames;
}
return interfaceNames;
return null;
}

View File

@ -32,8 +32,8 @@ package com.gabongao.jvm.classfile;
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantInterfaceMemberrefInfo extends ConstantMemberrefInfo {
public ConstantInterfaceMemberrefInfo(ConstantPool constantPool) {
public class ConstantInterfaceMethodrefInfo extends ConstantMemberrefInfo {
public ConstantInterfaceMethodrefInfo(ConstantPool constantPool) {
super(constantPool);
}
}

View File

@ -50,7 +50,7 @@ public class ConstantMemberrefInfo extends ConstantInfo {
nameAndTypeIndex = classReader.readUint16();
}
public String className() {
public String getClassName() {
return constantPool.getClassName(classIndex);
}

View File

@ -46,6 +46,16 @@ public class MemberInfo {
this.attributes = ClassFile.readAttributes(classReader, cp);
}
public AttrConstantValue getConstantValueAttribute() {
for (AttributeInfo attr : attributes
) {
if (attr instanceof AttrConstantValue) {
return (AttrConstantValue) attr;
}
}
return null;
}
public AttrCode getCodeAttribure() {
for (AttributeInfo attr : attributes
) {

View File

@ -39,6 +39,8 @@ public class ClassPath {
}
public byte[] readClass(String className) {
className = className.concat(".class");
byte[] bytes = bootClasspath.readClass(className);
if ( bytes!= null) {
return bytes;

View File

@ -9,7 +9,7 @@
package com.gabongao.jvm.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.Object;
import com.gabongao.jvm.rtda.heap.Object;
import com.gabongao.jvm.rtda.OperandStack;
/**
@ -48,7 +48,6 @@ public class BranchInstruction implements Instruction {
public void execute(Frame frame) {
}
;
public void branch(Frame frame, int offset) {
int pc = frame.getThread().getPc();

View File

@ -37,6 +37,7 @@ public class Factory {
static OperandsInstruction operandsInstruction = new OperandsInstruction();
static BranchInstruction branchInstruction = new BranchInstruction();
static Index8Instruction index8Instruction = new Index8Instruction();
static Index16Instruction index16Instruction = new Index16Instruction();
public static Instruction newInstruction(byte opcode) {
switch (Byte.toUnsignedInt(opcode)) {
@ -76,12 +77,12 @@ public class Factory {
return operandsInstruction.new Bipush();
case 0x11:
return operandsInstruction.new Sipush();
//case 0x12:
// return &LDC{}
//case 0x13:
// return &LDC_W{}
//case 0x14:
// return &LDC2_W{}
case 0x12:
return index8Instruction.new Ldc();
case 0x13:
return index8Instruction.new Ldc().new Ldc_W();
case 0x14:
return index8Instruction.new Ldc().new Ldc2_W();
case 0x15:
return index8Instruction.new Iload();
case 0x16:
@ -403,26 +404,26 @@ public class Factory {
// return areturn
// case 0xb1:
// return _return
//case 0xb2:
// return &GET_STATIC{}
//case 0xb3:
// return &PUT_STATIC{}
//case 0xb4:
// return &GET_FIELD{}
//case 0xb5:
// return &PUT_FIELD{}
//case 0xb6:
// return &INVOKE_VIRTUAL{}
//case 0xb7:
// return &INVOKE_SPECIAL{}
case 0xb2:
return index16Instruction.new GetStatic();
case 0xb3:
return index16Instruction.new PutStatic();
case 0xb4:
return index16Instruction.new GetField();
case 0xb5:
return index16Instruction.new PutField();
case 0xb6:
return index16Instruction.new InvokeVirtual();
case 0xb7:
return index16Instruction.new InvokeSpecial();
//case 0xb8:
// return &INVOKE_STATIC{}
//case 0xb9:
// return &INVOKE_INTERFACE{}
//case 0xba:
// return &INVOKE_DYNAMIC{}
//case 0xbb:
// return &NEW{}
case 0xbb:
return index16Instruction.new New();
//case 0xbc:
// return &NEW_ARRAY{}
//case 0xbd:
@ -431,10 +432,10 @@ public class Factory {
// return arraylength
//case 0xbf:
// return athrow
//case 0xc0:
// return &CHECK_CAST{}
//case 0xc1:
// return &INSTANCE_OF{}
case 0xc0:
return index16Instruction.new CheckCast();
case 0xc1:
return index16Instruction.new InstanceOf();
//case 0xc2:
// return monitorenter
//case 0xc3:
@ -461,6 +462,5 @@ public class Factory {
default:
throw new RuntimeException(String.format("Bad opcode: 0X%X", opcode));
}
}
}

View File

@ -8,6 +8,11 @@
package com.gabongao.jvm.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.OperandStack;
import com.gabongao.jvm.rtda.heap.*;
import com.gabongao.jvm.rtda.heap.Object;
/**
*            + +
*         + +
@ -32,11 +37,323 @@ package com.gabongao.jvm.instructions;
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public abstract class Index16Instruction implements Instruction {
private char Index;
public class Index16Instruction implements Instruction {
protected char index;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
Index = bytecodeReader.readUint16();
index = bytecodeReader.readUint16();
}
@Override
public void execute(Frame frame) {
}
public class New extends Index16Instruction {
@Override
public void execute(Frame frame) {
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
ClassRef classRef = (ClassRef) cp.getConstant(index).getObject();
ClassStruct classStruct = classRef.resolvedClass();
if (classStruct.IsInterface() || classStruct.IsAbstract()) {
throw new RuntimeException("InstantiationError");
}
Object ref = classStruct.newObject();
frame.getOperandStack().pushRef(ref);
}
//todo: index传值失败父类的index为private子类不能访问父类的值因此默认初始值0.
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
}
public class PutStatic extends Index16Instruction {
@Override
public void execute(Frame frame) {
Method currentMethod = frame.getMethod();
ClassStruct currentClass = currentMethod.getClassMember().getClassStruct();
ConstantPool cp = currentClass.getConstantPool();
FieldRef fieldRef = (FieldRef) cp.getConstant(index).getObject();
Field field = fieldRef.resolvedField();
ClassStruct classStruct = field.getClassStruct();
if (!field.IsStatic()) {
throw new RuntimeException("IncompatibleClassChangeError");
}
if (field.IsFinal()) {
if (currentClass != classStruct || !currentMethod.getClassMember().getName().equals("<clinit>")) {
throw new RuntimeException("IllegalAccessError");
}
}
String descriptor = field.getDescriptor();
int slotId = field.getSlotId();
Slots slots = classStruct.getStaticVars();
OperandStack operandStack = frame.getOperandStack();
char[] des = descriptor.toCharArray();
switch (des[0]) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
slots.setInt(slotId, operandStack.popInt());
break;
case 'F':
slots.setFloat(slotId, operandStack.popFloat());
break;
case 'J':
slots.setLong(slotId, operandStack.popLong());
break;
case 'D':
slots.setDouble(slotId, operandStack.popDouble());
break;
case 'L':
case '[':
slots.setRef(slotId, operandStack.popRef());
break;
}
}
}
public class GetStatic extends Index16Instruction {
@Override
public void execute(Frame frame) {
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
FieldRef fieldRef = (FieldRef) cp.getConstant(index).getObject();
Field field = fieldRef.resolvedField();
ClassStruct classStruct = field.getClassStruct();
if (!field.IsStatic()) {
throw new RuntimeException("IncompatibleClassChangeError");
}
String descriptor = field.getDescriptor();
int slotId = field.getSlotId();
Slots slots = classStruct.getStaticVars();
OperandStack operandStack = frame.getOperandStack();
char[] des = descriptor.toCharArray();
switch (des[0]) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
operandStack.pushInt(slots.getInt(slotId));
break;
case 'F':
operandStack.pushFloat(slots.getFloat(slotId));
break;
case 'J':
operandStack.pushLong(slots.getLong(slotId));
break;
case 'D':
operandStack.pushDouble(slots.getDouble(slotId));
break;
case 'L':
case '[':
operandStack.pushRef(slots.getRef(slotId));
break;
}
}
}
public class PutField extends Index16Instruction {
@Override
public void execute(Frame frame) {
Method currentMethod = frame.getMethod();
ClassStruct currentClass = currentMethod.getClassMember().getClassStruct();
ConstantPool cp = currentClass.getConstantPool();
FieldRef fieldRef = (FieldRef) cp.getConstant(index).getObject();
Field field = fieldRef.resolvedField();
if (field.IsStatic()) {
throw new RuntimeException("IncompatibleClassChangeError");
}
if (field.IsFinal()) {
if (currentClass != field.getClassStruct() || !currentMethod.getClassMember().getName().equals("<init>")) {
throw new RuntimeException("IllegalAccessError");
}
}
String descriptor = field.getDescriptor();
int slotId = field.getSlotId();
OperandStack operandStack = frame.getOperandStack();
char[] des = descriptor.toCharArray();
switch (des[0]) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
int vali = operandStack.popInt();
Object refi = operandStack.popRef();
if (refi == null) {
throw new RuntimeException("NullPointerException");
}
refi.getFields().setInt(slotId, vali);
break;
case 'F':
float valf = operandStack.popFloat();
Object reff = operandStack.popRef();
if (reff == null) {
throw new RuntimeException("NullPointerException");
}
reff.getFields().setFloat(slotId, valf);
break;
case 'J':
long vall = operandStack.popLong();
Object refl = operandStack.popRef();
if (refl == null) {
throw new RuntimeException("NullPointerException");
}
refl.getFields().setLong(slotId, vall);
break;
case 'D':
double vald = operandStack.popDouble();
Object refd = operandStack.popRef();
if (refd == null) {
throw new RuntimeException("NullPointerException");
}
refd.getFields().setDouble(slotId, vald);
break;
case 'L':
case '[':
Object valr = operandStack.popRef();
Object ref = operandStack.popRef();
if (ref == null) {
throw new RuntimeException("NullPointerException");
}
ref.getFields().setRef(slotId, valr);
break;
}
}
}
public class GetField extends Index16Instruction {
@Override
public void execute(Frame frame) {
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
FieldRef fieldRef = (FieldRef) cp.getConstant(index).getObject();
Field field = fieldRef.resolvedField();
if (field.IsStatic()) {
throw new RuntimeException("IncompatibleClassChangeError");
}
OperandStack operandStack = frame.getOperandStack();
Object ref = operandStack.popRef();
if (ref == null) {
throw new RuntimeException("NullPointerException");
}
String descriptor = field.getDescriptor();
int slotId = field.getSlotId();
Slots slots = ref.getFields();
char[] des = descriptor.toCharArray();
switch (des[0]) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
operandStack.pushInt(slots.getInt(slotId));
break;
case 'F':
operandStack.pushFloat(slots.getFloat(slotId));
break;
case 'J':
operandStack.pushLong(slots.getLong(slotId));
break;
case 'D':
operandStack.pushDouble(slots.getDouble(slotId));
break;
case 'L':
case '[':
operandStack.pushRef(slots.getRef(slotId));
break;
}
}
}
public class InstanceOf extends Index16Instruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Object ref = operandStack.popRef();
if (ref == null) {
operandStack.pushInt(0);
}
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
ClassRef classRef = (ClassRef) cp.getConstant(index).getObject();
ClassStruct classStruct = classRef.resolvedClass();
if (ref.isInstanceOf(classStruct)) {
operandStack.pushInt(1);
} else {
operandStack.pushInt(0);
}
}
}
public class CheckCast extends Index16Instruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Object ref = operandStack.popRef();
operandStack.pushRef(ref);
if (ref == null) {
return;
}
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
ClassRef classRef = (ClassRef) cp.getConstant(index).getObject();
ClassStruct classStruct = classRef.resolvedClass();
if (!ref.isInstanceOf(classStruct)) {
throw new RuntimeException("ClassCastException");
}
}
}
public class InvokeSpecial extends Index16Instruction {
@Override
public void execute(Frame frame) {
frame.getOperandStack().popRef();
}
}
public class InvokeVirtual extends Index16Instruction {
@Override
public void execute(Frame frame) {
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
MethodRef methodRef = (MethodRef) cp.getConstant(index).getObject();
if (methodRef.getName().equals("println")) {
OperandStack operandStack = frame.getOperandStack();
switch (methodRef.getDescriptor()) {
case "(Z)V":
System.out.println(operandStack.popInt() != 0);
break;
case "(C)V":
System.out.printf("%c\n", operandStack.popInt());
break;
case "(B)V":
System.out.println(operandStack.popInt());
break;
case "(S)V":
System.out.println(operandStack.popInt());
break;
case "(I)V":
System.out.println(operandStack.popInt());
break;
case "(J)V":
System.out.println(operandStack.popLong());
break;
case "(F)V":
System.out.println(operandStack.popFloat());
break;
case "(D)V":
System.out.println(operandStack.popDouble());
break;
default:
throw new RuntimeException("println:" + methodRef.getDescriptor());
}
operandStack.popRef();
}
}
}
}

View File

@ -10,7 +10,9 @@ package com.gabongao.jvm.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.LocalVars;
import com.gabongao.jvm.rtda.Object;
import com.gabongao.jvm.rtda.OperandStack;
import com.gabongao.jvm.rtda.heap.ConstantPool;
import com.gabongao.jvm.rtda.heap.Object;
/**
*            + +
@ -685,4 +687,55 @@ public class Index8Instruction implements Instruction {
localVars.setInt(super.getIndex(), localVars.getInt(super.getIndex()) + constVal);
}
}
public class Ldc extends Index8Instruction {
@Override
public void execute(Frame frame) {
_ldc(frame, super.getIndex());
}
public void _ldc(Frame frame, int index) {
OperandStack operandStack = frame.getOperandStack();
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
java.lang.Object c = cp.getConstant(index).getObject();
if (c instanceof Integer) {
operandStack.pushInt((int) c);
} else if (c instanceof Float) {
operandStack.pushFloat((float) c);
} else {
throw new RuntimeException("todo : ldc");
} //todo
}
}
public class Ldc_W extends Ldc {
@Override
public void execute(Frame frame) {
super.execute(frame);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
Index = bytecodeReader.readUint16();
}
}
public class Ldc2_W extends Ldc_W {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
ConstantPool cp = frame.getMethod().getClassMember().getClassStruct().getConstantPool();
java.lang.Object c = cp.getConstant(Index).getObject();
if (c instanceof Long) {
operandStack.pushLong((long) c);
} else if (c instanceof Double) {
operandStack.pushDouble((double) c);
} else {
throw new RuntimeException("ClassFormatError");
}
}
}
}

View File

@ -42,7 +42,6 @@ import sun.awt.OSInfo;
public class OperandsInstruction implements Instruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
//TODO
}
public void execute(Frame frame) {
@ -294,9 +293,15 @@ public class OperandsInstruction implements Instruction {
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot = operandStack.popSlot();
Slot slot1 = slot.copySlot();
operandStack.pushSlot(slot);
operandStack.pushSlot(slot);
operandStack.pushSlot(slot1);
}
//todo:dup 指令传入两个相同的引用要先拷贝一份
// Slot slot = operandStack.popSlot();
// operandStack.pushSlot(slot);
// operandStack.pushSlot(slot);
}
public class Dup_X1 extends OperandsInstruction {
@ -307,7 +312,7 @@ public class OperandsInstruction implements Instruction {
Slot slot2 = operandStack.popSlot();
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot1.copySlot());
}
}
@ -321,7 +326,7 @@ public class OperandsInstruction implements Instruction {
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot1.copySlot());
}
}
@ -334,7 +339,7 @@ public class OperandsInstruction implements Instruction {
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot1.copySlot());
}
}
@ -348,8 +353,8 @@ public class OperandsInstruction implements Instruction {
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2.copySlot());
operandStack.pushSlot(slot1.copySlot());
}
}
@ -365,8 +370,8 @@ public class OperandsInstruction implements Instruction {
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot4);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2.copySlot());
operandStack.pushSlot(slot1.copySlot());
}
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import com.gabongao.jvm.rtda.heap.Method;
/**
*            + +
*         + +
@ -37,6 +39,7 @@ public class Frame {
private LocalVars localVars;
private OperandStack operandStack;
private Thread thread;
private Method method;
private int nextPc;
public Frame(Thread thread, int maxLocals, int maxStack) {
@ -45,6 +48,17 @@ public class Frame {
operandStack = new OperandStack(maxStack);
}
public Frame(Thread thread, Method method) {
this.thread = thread;
this.method = method;
this.localVars = new LocalVars(method.getMaxLocals());
this.operandStack = new OperandStack(method.getMaxStack());
}
public Method getMethod() {
return method;
}
public LocalVars getLocalVars() {
return localVars;
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import com.gabongao.jvm.rtda.heap.Object;
import java.util.Arrays;
/**
@ -37,16 +39,19 @@ import java.util.Arrays;
public class LocalVars {
private Slot[] slots;
LocalVars(int maxLocals) {
if (maxLocals > 0) {
public LocalVars(int maxLocals) {
if (maxLocals >= 0) {
slots = new Slot[maxLocals];
for (int i = 0; i < maxLocals; i++) {
slots[i] = new Slot();
}
} else {
throw new RuntimeException("LocalVars Count Error");
}
}
public void setInt(int index, int val) {
slots[index] = new Slot();
// slots[index] = new Slot();
slots[index].setNum(val);
}
@ -55,7 +60,7 @@ public class LocalVars {
}
public void setFloat(int index, float val) {
slots[index] = new Slot();
// slots[index] = new Slot();
slots[index].setNum(Float.floatToRawIntBits(val));
}
@ -64,7 +69,7 @@ public class LocalVars {
}
public void setLong(int index, long val) {
slots[index] = new Slot();
// slots[index] = new Slot();
slots[index].setNum((int) val);
slots[index + 1] = new Slot();
slots[index + 1].setNum((int) (val >> 32));
@ -77,7 +82,7 @@ public class LocalVars {
}
public void setRef(int index, Object ref) {
slots[index] = new Slot();
// slots[index] = new Slot();
slots[index].setRef(ref);
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import com.gabongao.jvm.rtda.heap.Object;
import java.util.Arrays;
/**
@ -41,6 +43,9 @@ public class OperandStack {
public OperandStack(int maxStacks) {
if (maxStacks > 0) {
slots = new Slot[maxStacks];
for (int i = 0; i < maxStacks; i++) {
slots[i] = new Slot();
}
} else {
throw new RuntimeException("Operands Count Error");
}
@ -55,7 +60,7 @@ public class OperandStack {
}
public void pushInt(int val) {
slots[size] = new Slot();
// slots[size] = new Slot();
slots[size].setNum(val);
size++;
}
@ -66,7 +71,7 @@ public class OperandStack {
}
public void pushFloat(float val) {
slots[size] = new Slot();
// slots[size] = new Slot();
slots[size].setNum(Float.floatToRawIntBits(val));
size++;
}
@ -77,9 +82,9 @@ public class OperandStack {
}
public void pushLong(long val) {
slots[size] = new Slot();
// slots[size] = new Slot();
slots[size].setNum((int) val);
slots[size + 1] = new Slot();
// slots[size + 1] = new Slot();
slots[size + 1].setNum((int) (val >> 32));
size += 2;
}
@ -92,7 +97,7 @@ public class OperandStack {
}
public void pushRef(Object ref) {
slots[size] = new Slot();
// slots[size] = new Slot();
slots[size].setRef(ref);
size++;
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import com.gabongao.jvm.rtda.heap.Object;
/**
*            + +
*         + +
@ -36,6 +38,11 @@ public class Slot {
private int num;
private Object ref;
public Slot() {
this.num = 0;
this.ref = new Object();
}
@Override
public String toString() {
return "Slot{" +
@ -59,4 +66,12 @@ public class Slot {
public void setRef(Object ref) {
this.ref = ref;
}
public Slot copySlot() {
Slot s = new Slot();
s.setNum(this.getNum());
s.setRef(this.getRef());
return s;
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public enum AccessFlags {
ACCESS_PUBLIC(0X0001), //class field method
ACCESS_PRIVATE(0X0002), // field method
ACCESS_PROTECTED(0X0004), // field method
ACCESS_STATIC(0X0008), // field method
ACCESS_FINAL(0X0010), //class field method
ACCESS_SUPER(0X0020), //class
ACCESS_SYNCHRONIZED(0X0020), // method
ACCESS_VOLATILE(0X0040), // field
ACCESS_BRIDGE(0X0040), // method
ACCESS_TRANSIENT(0X0080), // field
ACCESS_VARARGS(0X0080), // method
ACCESS_NATIVE(0X0100), // method
ACCESS_INTERFACE(0X0200), //class
ACCESS_ABSTRACT(0X0400), //class method
ACCESS_STRICT(0X0800), // method
ACCESS_SYNTHETIC(0X1000), //class field method
ACCESS_ANNOTATION(0X2000), //class
ACCESS_ENUM(0X4000), //class field
;
private int value;
AccessFlags(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

View File

@ -0,0 +1,191 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ClassFile;
import com.gabongao.jvm.classpath.ClassPath;
import java.util.HashMap;
import java.util.LinkedHashMap;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class ClassLoader {
private ClassPath classPath;
private HashMap<String, ClassStruct> classStructHashMap;
public ClassLoader(ClassPath classPath) {
this.classPath = classPath;
classStructHashMap = new LinkedHashMap<>();
}
public ClassStruct loadClass(String name) {
ClassStruct classStruct = classStructHashMap.get(name);
if (classStruct == null) {
return loadNonArrayClass(name);
}
return classStruct;
}
private ClassStruct loadNonArrayClass(String name) {
byte[] classData = classPath.readClass(name);
ClassStruct classStruct = defineClass(classData);
link(classStruct);
System.out.printf("Loaded class %s \n", name);
return classStruct;
}
private ClassStruct defineClass(byte[] classData) {
ClassStruct classStruct = parseClass(classData);
classStruct.setClassLoader(this);
resolveSuperClass(classStruct);
resolveInterfaces(classStruct);
classStructHashMap.put(classStruct.getClassName(), classStruct);
return classStruct;
}
private ClassStruct parseClass(byte[] classData) {
ClassFile classFile = new ClassFile(classData);
classFile.read();
return new ClassStruct(classFile);
}
private void resolveSuperClass(ClassStruct classStruct) {
if (!classStruct.getClassName().equals("java/lang/Object")) {
classStruct.setSuperClass(classStruct.getClassLoader().loadClass(classStruct.getSuperClassName()));
}
}
private void resolveInterfaces(ClassStruct classStruct) {
int interfaceCount = classStruct.getInterfaceNames() == null ? 0 : classStruct.getInterfaceNames().length;
if (interfaceCount > 0) {
classStruct.setInterfaces(new ClassStruct[interfaceCount]);
for (int i = 0; i < interfaceCount; i++) {
classStruct.getInterfaces()[i] = classStruct.getClassLoader().loadClass(classStruct.getInterfaceNames()[i]);
}
}
}
private void link(ClassStruct classStruct) {
verify(classStruct);
prepare(classStruct);
}
private void verify(ClassStruct classStruct) {
//todo:verify class
}
private void prepare(ClassStruct classStruct) {
calcInstanceFieldSlotIds(classStruct);
calcStaticFieldSlotIds(classStruct);
allocAndInitStaticVars(classStruct);
}
private void calcInstanceFieldSlotIds(ClassStruct classStruct) {
int slotId = 0;
if (classStruct.getSuperClassName() != null) {
slotId = classStruct.getSuperClass() == null ? 0 : classStruct.getSuperClass().getInstanceSlotCount();
}
Field[] fields = classStruct.getFields();
int len = fields.length;
for (int i = 0; i < len; i++) {
if (!fields[i].IsStatic()) {
fields[i].setSlotId(slotId);
slotId++;
if (fields[i].isLongOrDouble()) {
slotId++;
}
}
}
classStruct.setInstanceSlotCount(slotId);
}
private void calcStaticFieldSlotIds(ClassStruct classStruct) {
int slotId = 0;
Field[] fields = classStruct.getFields();
int len = fields.length;
for (int i = 0; i < len; i++) {
if (fields[i].IsStatic()) {
fields[i].setSlotId(slotId);
slotId++;
if (fields[i].isLongOrDouble()) {
slotId++;
}
}
}
classStruct.setStaticSlotCount(slotId);
}
private void allocAndInitStaticVars(ClassStruct classStruct) {
classStruct.setStaticVars(new Slots(classStruct.getStaticSlotCount()));
Field[] fields = classStruct.getFields();
int len = fields.length;
for (int i = 0; i < len; i++) {
if (fields[i].IsStatic() && fields[i].IsFinal()) {
initStaticFinalVar(classStruct, fields[i]);
}
}
}
private void initStaticFinalVar(ClassStruct classStruct, Field field) {
Slots slots = classStruct.getStaticVars();
ConstantPool cp = classStruct.getConstantPool();
int cpIndex = field.getConstValueIndex();
int slotId = field.getSlotId();
if (cpIndex > 0) {
switch (field.getDescriptor()) {
case "Z":
case "B":
case "C":
case "S":
case "I":
int vali = (int) cp.getConstant(cpIndex).getObject();
slots.setInt(slotId, vali);
break;
case "J":
long vall = (Long) cp.getConstant(cpIndex).getObject();
slots.setLong(slotId, vall);
break;
case "F":
float valf = (Float) cp.getConstant(cpIndex).getObject();
slots.setFloat(slotId, valf);
break;
case "D":
double vald = (Double) cp.getConstant(cpIndex).getObject();
slots.setDouble(cpIndex, vald);
break;
case "Ljava/lang/String;":
throw new RuntimeException("todo");
//todo
}
}
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.AttrConstantValue;
import com.gabongao.jvm.classfile.MemberInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class ClassMember {
protected char accessFlags;
protected String name, descriptor;
private ClassStruct classStruct;
public ClassMember(MemberInfo memberInfo) {
this.accessFlags = memberInfo.getAccessFlags();
this.name = memberInfo.getName();
this.descriptor = memberInfo.getDescriptor();
}
public boolean isAccessibleTo(ClassStruct d) {
if (IsPublic()) {
return true;
}
ClassStruct c = classStruct;
if (IsProtected()) {
return d.equals(c) || d.isSubClassOf(c) || c.getPackageName().equals(d.getPackageName());
}
if (!IsPrivate()) {
return c.getPackageName().equals(d.getPackageName());
}
return d.equals(c);
}
public String getName() {
return name;
}
public String getDescriptor() {
return descriptor;
}
public ClassStruct getClassStruct() {
return classStruct;
}
public void setClassStruct(ClassStruct classStruct) {
this.classStruct = classStruct;
}
public char getAccessFlags() {
return accessFlags;
}
public boolean IsFinal() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_FINAL.getValue());
}
public boolean IsSynthetic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_SYNTHETIC.getValue());
}
public boolean IsEnum() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_ENUM.getValue());
}
public boolean IsPublic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PUBLIC.getValue());
}
public boolean IsPrivate() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PRIVATE.getValue());
}
public boolean IsProtected() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PROTECTED.getValue());
}
public boolean IsStatic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_STATIC.getValue());
}
public boolean IsVolatile() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_VOLATILE.getValue());
}
public boolean IsTransient() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_TRANSIENT.getValue());
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ConstantClassInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class ClassRef extends SymRef {
public ClassRef(ConstantPool constantPool, ConstantClassInfo classInfo) {
super(constantPool);
setClassName(classInfo.getName());
}
}

View File

@ -0,0 +1,380 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.*;
import java.lang.*;
import java.lang.Object;
import java.util.Arrays;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class ClassStruct {
private char accessFlags;
private String className, superClassName;
private String[] interfaceNames;
private ConstantPool constantPool;
private Field[] fields;
private Method[] methods;
private ClassLoader classLoader;
private ClassStruct superClass;
private ClassStruct[] interfaces;
private int instanceSlotCount, staticSlotCount;
private Slots staticVars;
public ClassStruct(ClassFile classFile) {
this.accessFlags = classFile.getAccessFlags();
this.className = classFile.thisClassName();
this.superClassName = classFile.superClassName();
this.interfaceNames = classFile.interfaceNames();
this.constantPool = newConstantPool(classFile.getConstantPool());
this.fields = newFields(classFile.getFields());
this.methods = newMethods(classFile.getMethods());
}
public com.gabongao.jvm.rtda.heap.Object newObject() {
return new com.gabongao.jvm.rtda.heap.Object(this);
}
private ConstantPool newConstantPool(com.gabongao.jvm.classfile.ConstantPool cfCp) {
int cpCount = cfCp.getConstantInfos().length;
Constant[] constants = new Constant[cpCount];
ConstantPool rtCp = new ConstantPool(this, constants);
for (int i = 1; i < cpCount; i++) {
ConstantInfo cpInfo = cfCp.getConstantInfos()[i];
switch (cpInfo.getClass().getName()) {
case "com.gabongao.jvm.classfile.ConstantIntegerInfo":
ConstantIntegerInfo constantIntegerInfo = (ConstantIntegerInfo) cpInfo;
constants[i] = new Constant(constantIntegerInfo.getVal());
break;
case "com.gabongao.jvm.classfile.ConstantLongInfo":
ConstantLongInfo constantLongInfo = (ConstantLongInfo) cpInfo;
constants[i] = new Constant(constantLongInfo.getVal());
i++;
break;
case "com.gabongao.jvm.classfile.ConstantDoubleInfo":
ConstantDoubleInfo constantDoubleInfo = (ConstantDoubleInfo) cpInfo;
constants[i] = new Constant(constantDoubleInfo.getVal());
break;
case "com.gabongao.jvm.classfile.ConstantStringInfo":
ConstantStringInfo constantStringInfo = (ConstantStringInfo) cpInfo;
constants[i] = new Constant(constantStringInfo.getString());
break;
case "com.gabongao.jvm.classfile.ConstantClassInfo":
ConstantClassInfo classInfo = (ConstantClassInfo) cpInfo;
ClassRef classRef = new ClassRef(rtCp, classInfo);
// classRef.setClassStruct(this);
constants[i] = new Constant(classRef);
break;
case "com.gabongao.jvm.classfile.ConstantFieldrefInfo":
ConstantFieldrefInfo fieldrefInfo = (ConstantFieldrefInfo) cpInfo;
FieldRef ref = new FieldRef(rtCp, fieldrefInfo);
// ref.setClassStruct(this);
constants[i] = new Constant(ref);
break;
case "com.gabongao.jvm.classfile.ConstantMethodrefInfo":
ConstantMethodrefInfo methodrefInfo = (ConstantMethodrefInfo) cpInfo;
MethodRef methodRef = new MethodRef(rtCp, methodrefInfo);
// methodRef.setClassStruct(this);
constants[i] = new Constant(methodRef);
break;
case "com.gabongao.jvm.classfile.ConstantInterfaceMethodrefInfo":
ConstantInterfaceMethodrefInfo interfaceMethodrefInfo = (ConstantInterfaceMethodrefInfo) cpInfo;
InterfaceMethodRef interfaceMethodRef = new InterfaceMethodRef(rtCp, interfaceMethodrefInfo);
// interfaceMethodRef.setClassStruct(this);
constants[i] = new Constant(interfaceMethodRef);
break;
}
}
return rtCp;
}
private Method[] newMethods(MemberInfo[] cfMethods) {
Method[] methods = new Method[cfMethods.length];
for (int i = 0; i < cfMethods.length; i++) {
methods[i] = new Method(cfMethods[i]);
methods[i].getClassMember().setClassStruct(this);
}
return methods;
}
private Field[] newFields(MemberInfo[] cfFields) {
Field[] fields = new Field[cfFields.length];
for (int i = 0; i < cfFields.length; i++) {
fields[i] = new Field(cfFields[i]);
fields[i].setClassStruct(this);
}
return fields;
}
public boolean isAccessibleTo(ClassStruct other) {
return this.IsPublic() || this.getPackageName().equals(other.getPackageName());
}
public boolean isSubClassOf(ClassStruct other) {
for (ClassStruct c = superClass; c != null; c = c.superClass) {
if (c == other) {
return true;
}
}
return false;
}
public String getPackageName() {
int i = className.lastIndexOf("/");
if (i >= 0) {
return className.substring(0, i);
}
return "";
}
public boolean IsPublic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PUBLIC.getValue());
}
public boolean IsFinal() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_FINAL.getValue());
}
public boolean IsSuper() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_SUPER.getValue());
}
public boolean IsInterface() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_INTERFACE.getValue());
}
public boolean IsAbstract() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_ABSTRACT.getValue());
}
public boolean IsSynthetic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_SYNTHETIC.getValue());
}
public boolean IsAnnotation() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_ANNOTATION.getValue());
}
public boolean IsEnum() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_ENUM.getValue());
}
public char getAccessFlags() {
return accessFlags;
}
public void setAccessFlags(char accessFlags) {
this.accessFlags = accessFlags;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getSuperClassName() {
return superClassName;
}
public void setSuperClassName(String superClassName) {
this.superClassName = superClassName;
}
public String[] getInterfaceNames() {
return interfaceNames;
}
public void setInterfaceNames(String[] interfaceNames) {
this.interfaceNames = interfaceNames;
}
public ConstantPool getConstantPool() {
return constantPool;
}
public void setConstantPool(ConstantPool constantPool) {
this.constantPool = constantPool;
}
public Field[] getFields() {
return fields;
}
public void setFields(Field[] fields) {
this.fields = fields;
}
public Method[] getMethods() {
return methods;
}
public void setMethods(Method[] methods) {
this.methods = methods;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public ClassStruct getSuperClass() {
return superClass;
}
public void setSuperClass(ClassStruct superClass) {
this.superClass = superClass;
}
public ClassStruct[] getInterfaces() {
return interfaces;
}
public void setInterfaces(ClassStruct[] interfaces) {
this.interfaces = interfaces;
}
public int getInstanceSlotCount() {
return instanceSlotCount;
}
public void setInstanceSlotCount(int instanceSlotCount) {
this.instanceSlotCount = instanceSlotCount;
}
public int getStaticSlotCount() {
return staticSlotCount;
}
public void setStaticSlotCount(int staticSlotCount) {
this.staticSlotCount = staticSlotCount;
}
public Slots getStaticVars() {
return staticVars;
}
public void setStaticVars(Slots staticVars) {
this.staticVars = staticVars;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ClassStruct)) return false;
ClassStruct that = (ClassStruct) o;
if (getAccessFlags() != that.getAccessFlags()) return false;
if (getInstanceSlotCount() != that.getInstanceSlotCount()) return false;
if (getStaticSlotCount() != that.getStaticSlotCount()) return false;
if (!getClassName().equals(that.getClassName())) return false;
if (!getSuperClassName().equals(that.getSuperClassName())) return false;
if (!getConstantPool().equals(that.getConstantPool())) return false;
if (!getClassLoader().equals(that.getClassLoader())) return false;
if (!getSuperClass().equals(that.getSuperClass())) return false;
return getStaticVars().equals(that.getStaticVars());
}
@Override
public int hashCode() {
int result = (int) getAccessFlags();
result = 31 * result + (getClassName() != null ? getClassName().hashCode() : 0);
result = 31 * result + (getSuperClassName() != null ? getSuperClassName().hashCode() : 0);
result = 31 * result + Arrays.hashCode(getInterfaceNames());
result = 31 * result + (getConstantPool() != null ? getConstantPool().hashCode() : 0);
result = 31 * result + Arrays.hashCode(getFields());
result = 31 * result + Arrays.hashCode(getMethods());
result = 31 * result + (getClassLoader() != null ? getClassLoader().hashCode() : 0);
result = 31 * result + (getSuperClass() != null ? getSuperClass().hashCode() : 0);
result = 31 * result + Arrays.hashCode(getInterfaces());
result = 31 * result + getInstanceSlotCount();
result = 31 * result + getStaticSlotCount();
result = 31 * result + (getStaticVars() != null ? getStaticVars().hashCode() : 0);
return result;
}
public boolean isAssignableFrom(ClassStruct other) {
ClassStruct s = other;
ClassStruct t = this;
if (s.equals(t)) {
return true;
}
if (!t.IsInterface()) {
return s.isSubClassOf(t);
} else {
return s.isImplements(t);
}
}
public boolean isImplements(ClassStruct iface) {
for (ClassStruct c = this.superClass; c != null; c = c.getSuperClass()) {
for (ClassStruct cs : c.interfaces
) {
if (cs.equals(iface) || cs.isSubInterfaceOf(iface)) {
return true;
}
}
}
return false;
}
public boolean isSubInterfaceOf(ClassStruct iface) {
for (ClassStruct superInterface : this.interfaces
) {
if (superInterface.equals(iface) || superInterface.isSubInterfaceOf(iface)) {
return true;
}
}
return false;
}
public Method getMainMethod() {
return this.getStaticMethod("main", "([Ljava/lang/String;)V");
}
public Method getStaticMethod(String name, String descriptor) {
for (Method method : methods
) {
if (method.IsStatic() && method.getClassMember().getName().equals(name) && method.getClassMember().getDescriptor().equals(descriptor)) {
return method;
}
}
return null;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import java.lang.*;
import java.lang.Object;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class Constant {
private java.lang.Object object;
public Constant(Object object) {
this.object = object;
}
public Object getObject() {
return object;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class ConstantPool {
private ClassStruct classStruct;
private Constant[] constants;
ConstantPool(ClassStruct classStruct, Constant[] constants) {
this.constants = constants;
this.classStruct = classStruct;
}
public Constant getConstant(int index) {
if (index >= constants.length) {
throw new RuntimeException("getConstant Array out of bound");
}
return constants[index] == null ? null : constants[index];
}
public ClassStruct getClassStruct() {
return classStruct;
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.AttrConstantValue;
import com.gabongao.jvm.classfile.MemberInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class Field extends ClassMember {
private int slotId;
private int constValueIndex;
public Field(MemberInfo memberInfo) {
super(memberInfo);
AttrConstantValue attr = memberInfo.getConstantValueAttribute();
if (attr != null) {
constValueIndex = attr.getConstantValueIndex();
}
}
public int getConstValueIndex() {
return constValueIndex;
}
public boolean IsFinal() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_FINAL.getValue());
}
public boolean IsSynthetic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_SYNTHETIC.getValue());
}
public boolean IsEnum() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_ENUM.getValue());
}
public boolean IsPublic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PUBLIC.getValue());
}
public boolean IsPrivate() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PRIVATE.getValue());
}
public boolean IsProtected() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_PROTECTED.getValue());
}
public boolean IsStatic() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_STATIC.getValue());
}
public boolean IsVolatile() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_VOLATILE.getValue());
}
public boolean IsTransient() {
return 0 != (((int) accessFlags) & AccessFlags.ACCESS_TRANSIENT.getValue());
}
public char getAccessFlags() {
return accessFlags;
}
public void setAccessFlags(char accessFlags) {
this.accessFlags = accessFlags;
}
public int getSlotId() {
return slotId;
}
public void setSlotId(int slotId) {
this.slotId = slotId;
}
public boolean isLongOrDouble() {
return descriptor.equals("J") || descriptor.equals("D");
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.*;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class FieldRef extends MemberRef {
private Field field;
public FieldRef(ConstantPool constantPool, ConstantMemberrefInfo memberrefInfo) {
super(constantPool, memberrefInfo);
}
public Field resolvedField() {
if (field == null) {
resolveFieldRef();
}
return field;
}
public void resolveFieldRef() {
ClassStruct d = constantPool.getClassStruct();
ClassStruct c = resolvedClass();
field = lookupField(c, name, descriptor);
if (field == null) {
throw new RuntimeException("NoSuchFieldError");
}
if (!field.isAccessibleTo(d)) {
throw new RuntimeException("IllegalAccessError");
}
}
public Field lookupField(ClassStruct c, String name, String descriptor) {
for (Field f : c.getFields()
) {
if (f.getName().equals(name) && f.descriptor.equals(descriptor)) {
return f;
}
}
for (ClassStruct cs : c.getInterfaces()
) {
Field field = lookupField(cs, name, descriptor);
if (field != null) {
return field;
}
}
if (c.getSuperClass() != null) {
return lookupField(c.getSuperClass(), name, descriptor);
}
return null;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ConstantMemberrefInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class InterfaceMethodRef extends MemberRef {
private Method method;
public InterfaceMethodRef(ConstantPool constantPool, ConstantMemberrefInfo memberrefInfo) {
super(constantPool, memberrefInfo);
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ConstantClassInfo;
import com.gabongao.jvm.classfile.ConstantMemberrefInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class MemberRef extends SymRef {
protected String name, descriptor;
public MemberRef(ConstantPool constantPool, ConstantMemberrefInfo memberrefInfo) {
super(constantPool);
super.setClassName(memberrefInfo.getClassName());
name = memberrefInfo.nameAndDescriptor()[0];
descriptor = memberrefInfo.nameAndDescriptor()[1];
}
public String getDescriptor() {
return descriptor;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.MemberInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class Method {
ClassMember classMember;
int maxStack, maxLocals;
byte[] code;
Method(MemberInfo memberInfo) {
classMember = new ClassMember(memberInfo);
maxLocals = memberInfo.getCodeAttribure() == null ? 0 : memberInfo.getCodeAttribure().getMaxLocals();
maxStack = memberInfo.getCodeAttribure() == null ? 0 : memberInfo.getCodeAttribure().getMaxStack();
code = memberInfo.getCodeAttribure() == null ? null : memberInfo.getCodeAttribure().getCode();
}
public ClassMember getClassMember() {
return classMember;
}
public void setClassMember(ClassMember classMember) {
this.classMember = classMember;
}
public int getMaxStack() {
return maxStack;
}
public void setMaxStack(int maxStack) {
this.maxStack = maxStack;
}
public int getMaxLocals() {
return maxLocals;
}
public void setMaxLocals(int maxLocals) {
this.maxLocals = maxLocals;
}
public byte[] getCode() {
return code;
}
public void setCode(byte[] code) {
this.code = code;
}
public boolean IsFinal() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_FINAL.getValue());
}
public boolean IsAbstract() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_ABSTRACT.getValue());
}
public boolean IsSynthetic() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_SYNTHETIC.getValue());
}
public boolean IsPublic() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_PUBLIC.getValue());
}
public boolean IsPrivate() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_PRIVATE.getValue());
}
public boolean IsProtected() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_PROTECTED.getValue());
}
public boolean IsStatic() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_STATIC.getValue());
}
public boolean IsSynchronized() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_SYNCHRONIZED.getValue());
}
public boolean IsBridge() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_BRIDGE.getValue());
}
public boolean IsVarargs() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_VARARGS.getValue());
}
public boolean IsNative() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_NATIVE.getValue());
}
public boolean IsStrict() {
return 0 != (((int) classMember.accessFlags) & AccessFlags.ACCESS_STRICT.getValue());
}
public char getAccessFlags() {
return classMember.accessFlags;
}
public void setAccessFlags(char accessFlags) {
this.classMember.accessFlags = accessFlags;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ConstantMemberrefInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class MethodRef extends MemberRef {
private Method method;
public MethodRef(ConstantPool constantPool, ConstantMemberrefInfo memberrefInfo) {
super(constantPool, memberrefInfo);
}
public Method getMethod() {
return method;
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*             
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class Object {
private ClassStruct classStruct;
private Slots fields;
//TODO
public Object() {
}
public Object(ClassStruct classStruct) {
this.classStruct = classStruct;
this.fields = new Slots(classStruct.getInstanceSlotCount());
}
public ClassStruct getClassStruct() {
return classStruct;
}
public Slots getFields() {
return fields;
}
public boolean isInstanceOf(ClassStruct classStruct) {
return classStruct.isAssignableFrom(this.classStruct);
}
}

View File

@ -6,7 +6,9 @@
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda;
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.rtda.LocalVars;
/**
*            + +
@ -30,8 +32,10 @@ package com.gabongao.jvm.rtda;
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
* Created by Imgaojp on 2017/2/20.
*/
public class Object {
//TODO
public class Slots extends LocalVars {
public Slots(int slotCount) {
super(slotCount);
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.rtda.heap;
import com.gabongao.jvm.classfile.ConstantClassInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/20.
*/
public class SymRef {
ConstantPool constantPool;
String className;
private ClassStruct classStruct;
public SymRef(ConstantPool constantPool) {
this.constantPool = constantPool;
}
public ConstantPool getConstantPool() {
return constantPool;
}
public void setConstantPool(ConstantPool constantPool) {
this.constantPool = constantPool;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public ClassStruct getClassStruct() {
return classStruct;
}
public void setClassStruct(ClassStruct classStruct) {
this.classStruct = classStruct;
}
public ClassStruct resolvedClass() {
if (this.classStruct == null) {
resolvedClassRef();
}
return classStruct;
}
public void resolvedClassRef() {
ClassStruct d = constantPool.getClassStruct();
ClassStruct c = d.getClassLoader().loadClass(className);
if (!c.isAccessibleTo(d)) {
throw new RuntimeException("java.lang.IllegalAccessError");
}
classStruct = c;
}
}