ClassLoader
This commit is contained in:
parent
6233862b56
commit
675d9fd807
@ -14,6 +14,7 @@ import com.gabongao.jvm.classfile.MemberInfo;
|
|||||||
import com.gabongao.jvm.instructions.*;
|
import com.gabongao.jvm.instructions.*;
|
||||||
import com.gabongao.jvm.rtda.Frame;
|
import com.gabongao.jvm.rtda.Frame;
|
||||||
import com.gabongao.jvm.rtda.Thread;
|
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) {
|
public void loop(Thread thread, byte[] byteCode) {
|
||||||
Frame frame = thread.popFrame();
|
Frame frame = thread.popFrame();
|
||||||
BytecodeReader bytecodeReader = new BytecodeReader();
|
BytecodeReader bytecodeReader = new BytecodeReader();
|
||||||
@ -65,13 +80,13 @@ public class Interpreter {
|
|||||||
for (; ; ) {
|
for (; ; ) {
|
||||||
int pc = frame.getNextPc();
|
int pc = frame.getNextPc();
|
||||||
thread.setPc(pc);
|
thread.setPc(pc);
|
||||||
System.out.printf("loop: %2d\t", n);
|
System.out.printf("loop: %6d\t", n);
|
||||||
bytecodeReader.reset(byteCode, pc);
|
bytecodeReader.reset(byteCode, pc);
|
||||||
char opcode = (char) bytecodeReader.readInt8();
|
char opcode = (char) bytecodeReader.readInt8();
|
||||||
Instruction instruction = Factory.newInstruction((byte) opcode);
|
Instruction instruction = Factory.newInstruction((byte) opcode);
|
||||||
instruction.fetchOperands(bytecodeReader);
|
instruction.fetchOperands(bytecodeReader);
|
||||||
frame.setNextPc(bytecodeReader.getPc());
|
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);
|
instruction.execute(frame);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,9 @@ import com.gabongao.jvm.classpath.ClassPath;
|
|||||||
import com.gabongao.jvm.rtda.Frame;
|
import com.gabongao.jvm.rtda.Frame;
|
||||||
import com.gabongao.jvm.rtda.LocalVars;
|
import com.gabongao.jvm.rtda.LocalVars;
|
||||||
import com.gabongao.jvm.rtda.OperandStack;
|
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
|
/* ch02
|
||||||
ClassPath cp = new ClassPath();
|
ClassPath cp = new ClassPath();
|
||||||
cp.parse(cmd.jreOption, cmd.cpOption);
|
cp.parse(cmd.jreOption, cmd.cpOption);
|
||||||
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.className, Arrays.asList(cmd.args));
|
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.getClassName, Arrays.asList(cmd.args));
|
||||||
String className = cmd.className.replace(".", "/").concat(".class");
|
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
|
||||||
byte[] classData = cp.readClass(className);
|
byte[] classData = cp.readClass(getClassName);
|
||||||
if (classData == null) {
|
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);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
for (byte b:classData
|
for (byte b:classData
|
||||||
@ -69,10 +72,10 @@ public class Jvm {
|
|||||||
/* ch03
|
/* ch03
|
||||||
ClassPath cp = new ClassPath();
|
ClassPath cp = new ClassPath();
|
||||||
cp.parse(cmd.jreOption, cmd.cpOption);
|
cp.parse(cmd.jreOption, cmd.cpOption);
|
||||||
String className = cmd.className.replace(".", "/").concat(".class");
|
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
|
||||||
ClassFile classFile = new ClassFile(cp.readClass(className));
|
ClassFile classFile = new ClassFile(cp.readClass(getClassName));
|
||||||
classFile.read();
|
classFile.read();
|
||||||
System.out.println(cmd.className);
|
System.out.println(cmd.getClassName);
|
||||||
printClassInfo(classFile);
|
printClassInfo(classFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,24 +98,48 @@ public class Jvm {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ch04
|
// ch04
|
||||||
|
/*
|
||||||
Frame frame = new Frame(100, 100);
|
Frame frame = new Frame(100, 100);
|
||||||
testLocalVars(frame.getLocalVars());
|
testLocalVars(frame.getLocalVars());
|
||||||
testOperandStack(frame.getOperandStack());
|
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();
|
Interpreter interpreter = new Interpreter();
|
||||||
ClassPath cp = new ClassPath();
|
ClassPath cp = new ClassPath();
|
||||||
|
|
||||||
|
ClassLoader classLoader = new ClassLoader(cp);
|
||||||
cp.parse(cmd.jreOption, cmd.cpOption);
|
cp.parse(cmd.jreOption, cmd.cpOption);
|
||||||
String className = cmd.className.replace(".", "/").concat(".class");
|
// String className = cmd.className.replace(".", "/").concat(".class");
|
||||||
ClassFile classFile = loadClass(className, cp);
|
String className = cmd.className;
|
||||||
classFile.read();
|
ClassStruct mainClass = classLoader.loadClass(className);
|
||||||
MemberInfo mainMethod = getMainMethod(classFile);
|
Method mainMethod = mainClass.getMainMethod();
|
||||||
|
// ClassFile classFile = loadClass(className, cp);
|
||||||
|
// classFile.read();
|
||||||
|
// MemberInfo mainMethod = getMainMethod(classFile);
|
||||||
if (mainMethod != null) {
|
if (mainMethod != null) {
|
||||||
interpreter.doInterpreter(mainMethod);
|
interpreter.doInterpreter(mainMethod);
|
||||||
} else {
|
} else {
|
||||||
System.out.printf("Main method not found in class %s\n", className);
|
System.out.printf("Main method not found in class %s\n", className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MemberInfo getMainMethod(ClassFile classFile) {
|
public static MemberInfo getMainMethod(ClassFile classFile) {
|
||||||
|
|||||||
@ -33,30 +33,30 @@ package com.gabongao.jvm.classfile;
|
|||||||
* Created by Imgaojp on 2017/2/18.
|
* Created by Imgaojp on 2017/2/18.
|
||||||
*/
|
*/
|
||||||
public class ClassFile {
|
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_MethodHandle = 15;
|
||||||
static final int CONSTANT_MethodType = 16;
|
static final int CONSTANT_MethodType = 16;
|
||||||
static final int CONSTANT_InvokeDynamic = 18;
|
static final int CONSTANT_InvokeDynamic = 18;
|
||||||
char majorVersion;
|
private static final int CONSTANT_Class = 7;
|
||||||
ConstantPool constantPool;
|
private static final int CONSTANT_Fieldref = 9;
|
||||||
char accessFlags;
|
private static final int CONSTANT_Methodref = 10;
|
||||||
char thisClass;
|
private static final int CONSTANT_InterfaceMethodref = 11;
|
||||||
char superClass;
|
private static final int CONSTANT_String = 8;
|
||||||
char[] interfaces;
|
private static final int CONSTANT_Integer = 3;
|
||||||
MemberInfo[] fields;
|
private static final int CONSTANT_Float = 4;
|
||||||
MemberInfo[] methods;
|
private static final int CONSTANT_Long = 5;
|
||||||
AttributeInfo[] attributes;
|
private static final int CONSTANT_Double = 6;
|
||||||
ClassReader classReader;
|
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;
|
private char minorVersion;
|
||||||
|
|
||||||
public ClassFile(byte[] classData) {
|
public ClassFile(byte[] classData) {
|
||||||
@ -107,6 +107,7 @@ public class ClassFile {
|
|||||||
public void read() {
|
public void read() {
|
||||||
readAndCheckMagic();
|
readAndCheckMagic();
|
||||||
readAndCheckVersion();
|
readAndCheckVersion();
|
||||||
|
constantPool = new ConstantPool();
|
||||||
constantPool = readConstantPool();
|
constantPool = readConstantPool();
|
||||||
accessFlags = classReader.readUint16();
|
accessFlags = classReader.readUint16();
|
||||||
thisClass = classReader.readUint16();
|
thisClass = classReader.readUint16();
|
||||||
@ -136,16 +137,17 @@ public class ClassFile {
|
|||||||
|
|
||||||
public ConstantPool readConstantPool() {
|
public ConstantPool readConstantPool() {
|
||||||
int cpCount = classReader.readUint16();
|
int cpCount = classReader.readUint16();
|
||||||
|
// constantPool.constantInfos = new ConstantInfo[cpCount];
|
||||||
ConstantInfo[] constantInfos = new ConstantInfo[cpCount];
|
ConstantInfo[] constantInfos = new ConstantInfo[cpCount];
|
||||||
|
// ConstantPool cp = new ConstantPool();
|
||||||
for (int i = 1; i < cpCount; i++) {
|
for (int i = 1; i < cpCount; i++) {
|
||||||
constantInfos[i] = readConstantInfo();
|
constantInfos[i] = readConstantInfo();
|
||||||
if (constantInfos[i] instanceof ConstantLongInfo || constantInfos[i] instanceof ConstantDoubleInfo) {
|
if (constantInfos[i] instanceof ConstantLongInfo || constantInfos[i] instanceof ConstantDoubleInfo) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstantPool cp = new ConstantPool();
|
constantPool.setConstantInfos(constantInfos);
|
||||||
cp.setConstantInfos(constantInfos);
|
return constantPool;
|
||||||
return cp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantInfo readConstantInfo() {
|
public ConstantInfo readConstantInfo() {
|
||||||
@ -176,7 +178,7 @@ public class ClassFile {
|
|||||||
case CONSTANT_Methodref:
|
case CONSTANT_Methodref:
|
||||||
return new ConstantMethodrefInfo(constantPool);
|
return new ConstantMethodrefInfo(constantPool);
|
||||||
case CONSTANT_InterfaceMethodref:
|
case CONSTANT_InterfaceMethodref:
|
||||||
return new ConstantInterfaceMemberrefInfo(constantPool);
|
return new ConstantInterfaceMethodrefInfo(constantPool);
|
||||||
case CONSTANT_NameAndType:
|
case CONSTANT_NameAndType:
|
||||||
return new ConstantNameAndTypeInfo();
|
return new ConstantNameAndTypeInfo();
|
||||||
// case CONSTANT_MethodType:
|
// case CONSTANT_MethodType:
|
||||||
@ -223,13 +225,17 @@ public class ClassFile {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo:return null
|
||||||
public String[] interfaceNames() {
|
public String[] interfaceNames() {
|
||||||
|
if ((interfaces != null)) {
|
||||||
String[] interfaceNames = new String[interfaces.length];
|
String[] interfaceNames = new String[interfaces.length];
|
||||||
for (int i = 0; i < interfaces.length; i++) {
|
for (int i = 0; i < interfaces.length; i++) {
|
||||||
interfaceNames[i] = constantPool.getClassName(interfaces[i]);
|
interfaceNames[i] = constantPool.getClassName(interfaces[i]);
|
||||||
}
|
}
|
||||||
return interfaceNames;
|
return interfaceNames;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public char getMinorVersion() {
|
public char getMinorVersion() {
|
||||||
|
|||||||
@ -32,8 +32,8 @@ package com.gabongao.jvm.classfile;
|
|||||||
* ┗┻┛ ┗┻┛+ + + +
|
* ┗┻┛ ┗┻┛+ + + +
|
||||||
* Created by Imgaojp on 2017/2/18.
|
* Created by Imgaojp on 2017/2/18.
|
||||||
*/
|
*/
|
||||||
public class ConstantInterfaceMemberrefInfo extends ConstantMemberrefInfo {
|
public class ConstantInterfaceMethodrefInfo extends ConstantMemberrefInfo {
|
||||||
public ConstantInterfaceMemberrefInfo(ConstantPool constantPool) {
|
public ConstantInterfaceMethodrefInfo(ConstantPool constantPool) {
|
||||||
super(constantPool);
|
super(constantPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ public class ConstantMemberrefInfo extends ConstantInfo {
|
|||||||
nameAndTypeIndex = classReader.readUint16();
|
nameAndTypeIndex = classReader.readUint16();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String className() {
|
public String getClassName() {
|
||||||
return constantPool.getClassName(classIndex);
|
return constantPool.getClassName(classIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,16 @@ public class MemberInfo {
|
|||||||
this.attributes = ClassFile.readAttributes(classReader, cp);
|
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() {
|
public AttrCode getCodeAttribure() {
|
||||||
for (AttributeInfo attr : attributes
|
for (AttributeInfo attr : attributes
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -39,6 +39,8 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] readClass(String className) {
|
public byte[] readClass(String className) {
|
||||||
|
|
||||||
|
className = className.concat(".class");
|
||||||
byte[] bytes = bootClasspath.readClass(className);
|
byte[] bytes = bootClasspath.readClass(className);
|
||||||
if ( bytes!= null) {
|
if ( bytes!= null) {
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
package com.gabongao.jvm.instructions;
|
package com.gabongao.jvm.instructions;
|
||||||
|
|
||||||
import com.gabongao.jvm.rtda.Frame;
|
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;
|
import com.gabongao.jvm.rtda.OperandStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +48,6 @@ public class BranchInstruction implements Instruction {
|
|||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
public void branch(Frame frame, int offset) {
|
public void branch(Frame frame, int offset) {
|
||||||
int pc = frame.getThread().getPc();
|
int pc = frame.getThread().getPc();
|
||||||
|
|||||||
@ -37,6 +37,7 @@ public class Factory {
|
|||||||
static OperandsInstruction operandsInstruction = new OperandsInstruction();
|
static OperandsInstruction operandsInstruction = new OperandsInstruction();
|
||||||
static BranchInstruction branchInstruction = new BranchInstruction();
|
static BranchInstruction branchInstruction = new BranchInstruction();
|
||||||
static Index8Instruction index8Instruction = new Index8Instruction();
|
static Index8Instruction index8Instruction = new Index8Instruction();
|
||||||
|
static Index16Instruction index16Instruction = new Index16Instruction();
|
||||||
|
|
||||||
public static Instruction newInstruction(byte opcode) {
|
public static Instruction newInstruction(byte opcode) {
|
||||||
switch (Byte.toUnsignedInt(opcode)) {
|
switch (Byte.toUnsignedInt(opcode)) {
|
||||||
@ -76,12 +77,12 @@ public class Factory {
|
|||||||
return operandsInstruction.new Bipush();
|
return operandsInstruction.new Bipush();
|
||||||
case 0x11:
|
case 0x11:
|
||||||
return operandsInstruction.new Sipush();
|
return operandsInstruction.new Sipush();
|
||||||
//case 0x12:
|
case 0x12:
|
||||||
// return &LDC{}
|
return index8Instruction.new Ldc();
|
||||||
//case 0x13:
|
case 0x13:
|
||||||
// return &LDC_W{}
|
return index8Instruction.new Ldc().new Ldc_W();
|
||||||
//case 0x14:
|
case 0x14:
|
||||||
// return &LDC2_W{}
|
return index8Instruction.new Ldc().new Ldc2_W();
|
||||||
case 0x15:
|
case 0x15:
|
||||||
return index8Instruction.new Iload();
|
return index8Instruction.new Iload();
|
||||||
case 0x16:
|
case 0x16:
|
||||||
@ -403,26 +404,26 @@ public class Factory {
|
|||||||
// return areturn
|
// return areturn
|
||||||
// case 0xb1:
|
// case 0xb1:
|
||||||
// return _return
|
// return _return
|
||||||
//case 0xb2:
|
case 0xb2:
|
||||||
// return &GET_STATIC{}
|
return index16Instruction.new GetStatic();
|
||||||
//case 0xb3:
|
case 0xb3:
|
||||||
// return &PUT_STATIC{}
|
return index16Instruction.new PutStatic();
|
||||||
//case 0xb4:
|
case 0xb4:
|
||||||
// return &GET_FIELD{}
|
return index16Instruction.new GetField();
|
||||||
//case 0xb5:
|
case 0xb5:
|
||||||
// return &PUT_FIELD{}
|
return index16Instruction.new PutField();
|
||||||
//case 0xb6:
|
case 0xb6:
|
||||||
// return &INVOKE_VIRTUAL{}
|
return index16Instruction.new InvokeVirtual();
|
||||||
//case 0xb7:
|
case 0xb7:
|
||||||
// return &INVOKE_SPECIAL{}
|
return index16Instruction.new InvokeSpecial();
|
||||||
//case 0xb8:
|
//case 0xb8:
|
||||||
// return &INVOKE_STATIC{}
|
// return &INVOKE_STATIC{}
|
||||||
//case 0xb9:
|
//case 0xb9:
|
||||||
// return &INVOKE_INTERFACE{}
|
// return &INVOKE_INTERFACE{}
|
||||||
//case 0xba:
|
//case 0xba:
|
||||||
// return &INVOKE_DYNAMIC{}
|
// return &INVOKE_DYNAMIC{}
|
||||||
//case 0xbb:
|
case 0xbb:
|
||||||
// return &NEW{}
|
return index16Instruction.new New();
|
||||||
//case 0xbc:
|
//case 0xbc:
|
||||||
// return &NEW_ARRAY{}
|
// return &NEW_ARRAY{}
|
||||||
//case 0xbd:
|
//case 0xbd:
|
||||||
@ -431,10 +432,10 @@ public class Factory {
|
|||||||
// return arraylength
|
// return arraylength
|
||||||
//case 0xbf:
|
//case 0xbf:
|
||||||
// return athrow
|
// return athrow
|
||||||
//case 0xc0:
|
case 0xc0:
|
||||||
// return &CHECK_CAST{}
|
return index16Instruction.new CheckCast();
|
||||||
//case 0xc1:
|
case 0xc1:
|
||||||
// return &INSTANCE_OF{}
|
return index16Instruction.new InstanceOf();
|
||||||
//case 0xc2:
|
//case 0xc2:
|
||||||
// return monitorenter
|
// return monitorenter
|
||||||
//case 0xc3:
|
//case 0xc3:
|
||||||
@ -461,6 +462,5 @@ public class Factory {
|
|||||||
default:
|
default:
|
||||||
throw new RuntimeException(String.format("Bad opcode: 0X%X", opcode));
|
throw new RuntimeException(String.format("Bad opcode: 0X%X", opcode));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,11 @@
|
|||||||
|
|
||||||
package com.gabongao.jvm.instructions;
|
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.
|
* Created by Imgaojp on 2017/2/18.
|
||||||
*/
|
*/
|
||||||
public abstract class Index16Instruction implements Instruction {
|
public class Index16Instruction implements Instruction {
|
||||||
private char Index;
|
protected char index;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetchOperands(BytecodeReader bytecodeReader) {
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,9 @@ package com.gabongao.jvm.instructions;
|
|||||||
|
|
||||||
import com.gabongao.jvm.rtda.Frame;
|
import com.gabongao.jvm.rtda.Frame;
|
||||||
import com.gabongao.jvm.rtda.LocalVars;
|
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);
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -42,7 +42,6 @@ import sun.awt.OSInfo;
|
|||||||
public class OperandsInstruction implements Instruction {
|
public class OperandsInstruction implements Instruction {
|
||||||
@Override
|
@Override
|
||||||
public void fetchOperands(BytecodeReader bytecodeReader) {
|
public void fetchOperands(BytecodeReader bytecodeReader) {
|
||||||
//TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
@ -294,9 +293,15 @@ public class OperandsInstruction implements Instruction {
|
|||||||
public void execute(Frame frame) {
|
public void execute(Frame frame) {
|
||||||
OperandStack operandStack = frame.getOperandStack();
|
OperandStack operandStack = frame.getOperandStack();
|
||||||
Slot slot = operandStack.popSlot();
|
Slot slot = operandStack.popSlot();
|
||||||
|
Slot slot1 = slot.copySlot();
|
||||||
operandStack.pushSlot(slot);
|
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 {
|
public class Dup_X1 extends OperandsInstruction {
|
||||||
@ -307,7 +312,7 @@ public class OperandsInstruction implements Instruction {
|
|||||||
Slot slot2 = operandStack.popSlot();
|
Slot slot2 = operandStack.popSlot();
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1);
|
||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2);
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1.copySlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +326,7 @@ public class OperandsInstruction implements Instruction {
|
|||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1);
|
||||||
operandStack.pushSlot(slot3);
|
operandStack.pushSlot(slot3);
|
||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2);
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1.copySlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +339,7 @@ public class OperandsInstruction implements Instruction {
|
|||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2);
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1);
|
||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2);
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1.copySlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,8 +353,8 @@ public class OperandsInstruction implements Instruction {
|
|||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2);
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1);
|
||||||
operandStack.pushSlot(slot3);
|
operandStack.pushSlot(slot3);
|
||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2.copySlot());
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1.copySlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,8 +370,8 @@ public class OperandsInstruction implements Instruction {
|
|||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1);
|
||||||
operandStack.pushSlot(slot4);
|
operandStack.pushSlot(slot4);
|
||||||
operandStack.pushSlot(slot3);
|
operandStack.pushSlot(slot3);
|
||||||
operandStack.pushSlot(slot2);
|
operandStack.pushSlot(slot2.copySlot());
|
||||||
operandStack.pushSlot(slot1);
|
operandStack.pushSlot(slot1.copySlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.gabongao.jvm.rtda;
|
package com.gabongao.jvm.rtda;
|
||||||
|
|
||||||
|
import com.gabongao.jvm.rtda.heap.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ┏┓ ┏┓+ +
|
* ┏┓ ┏┓+ +
|
||||||
* ┏┛┻━━━┛┻┓ + +
|
* ┏┛┻━━━┛┻┓ + +
|
||||||
@ -37,6 +39,7 @@ public class Frame {
|
|||||||
private LocalVars localVars;
|
private LocalVars localVars;
|
||||||
private OperandStack operandStack;
|
private OperandStack operandStack;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
private Method method;
|
||||||
private int nextPc;
|
private int nextPc;
|
||||||
|
|
||||||
public Frame(Thread thread, int maxLocals, int maxStack) {
|
public Frame(Thread thread, int maxLocals, int maxStack) {
|
||||||
@ -45,6 +48,17 @@ public class Frame {
|
|||||||
operandStack = new OperandStack(maxStack);
|
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() {
|
public LocalVars getLocalVars() {
|
||||||
return localVars;
|
return localVars;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.gabongao.jvm.rtda;
|
package com.gabongao.jvm.rtda;
|
||||||
|
|
||||||
|
import com.gabongao.jvm.rtda.heap.Object;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,16 +39,19 @@ import java.util.Arrays;
|
|||||||
public class LocalVars {
|
public class LocalVars {
|
||||||
private Slot[] slots;
|
private Slot[] slots;
|
||||||
|
|
||||||
LocalVars(int maxLocals) {
|
public LocalVars(int maxLocals) {
|
||||||
if (maxLocals > 0) {
|
if (maxLocals >= 0) {
|
||||||
slots = new Slot[maxLocals];
|
slots = new Slot[maxLocals];
|
||||||
|
for (int i = 0; i < maxLocals; i++) {
|
||||||
|
slots[i] = new Slot();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("LocalVars Count Error");
|
throw new RuntimeException("LocalVars Count Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInt(int index, int val) {
|
public void setInt(int index, int val) {
|
||||||
slots[index] = new Slot();
|
// slots[index] = new Slot();
|
||||||
slots[index].setNum(val);
|
slots[index].setNum(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +60,7 @@ public class LocalVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFloat(int index, float val) {
|
public void setFloat(int index, float val) {
|
||||||
slots[index] = new Slot();
|
// slots[index] = new Slot();
|
||||||
slots[index].setNum(Float.floatToRawIntBits(val));
|
slots[index].setNum(Float.floatToRawIntBits(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +69,7 @@ public class LocalVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setLong(int index, long val) {
|
public void setLong(int index, long val) {
|
||||||
slots[index] = new Slot();
|
// slots[index] = new Slot();
|
||||||
slots[index].setNum((int) val);
|
slots[index].setNum((int) val);
|
||||||
slots[index + 1] = new Slot();
|
slots[index + 1] = new Slot();
|
||||||
slots[index + 1].setNum((int) (val >> 32));
|
slots[index + 1].setNum((int) (val >> 32));
|
||||||
@ -77,7 +82,7 @@ public class LocalVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setRef(int index, Object ref) {
|
public void setRef(int index, Object ref) {
|
||||||
slots[index] = new Slot();
|
// slots[index] = new Slot();
|
||||||
slots[index].setRef(ref);
|
slots[index].setRef(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.gabongao.jvm.rtda;
|
package com.gabongao.jvm.rtda;
|
||||||
|
|
||||||
|
import com.gabongao.jvm.rtda.heap.Object;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +43,9 @@ public class OperandStack {
|
|||||||
public OperandStack(int maxStacks) {
|
public OperandStack(int maxStacks) {
|
||||||
if (maxStacks > 0) {
|
if (maxStacks > 0) {
|
||||||
slots = new Slot[maxStacks];
|
slots = new Slot[maxStacks];
|
||||||
|
for (int i = 0; i < maxStacks; i++) {
|
||||||
|
slots[i] = new Slot();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Operands Count Error");
|
throw new RuntimeException("Operands Count Error");
|
||||||
}
|
}
|
||||||
@ -55,7 +60,7 @@ public class OperandStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushInt(int val) {
|
public void pushInt(int val) {
|
||||||
slots[size] = new Slot();
|
// slots[size] = new Slot();
|
||||||
slots[size].setNum(val);
|
slots[size].setNum(val);
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
@ -66,7 +71,7 @@ public class OperandStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushFloat(float val) {
|
public void pushFloat(float val) {
|
||||||
slots[size] = new Slot();
|
// slots[size] = new Slot();
|
||||||
slots[size].setNum(Float.floatToRawIntBits(val));
|
slots[size].setNum(Float.floatToRawIntBits(val));
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
@ -77,9 +82,9 @@ public class OperandStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushLong(long val) {
|
public void pushLong(long val) {
|
||||||
slots[size] = new Slot();
|
// slots[size] = new Slot();
|
||||||
slots[size].setNum((int) val);
|
slots[size].setNum((int) val);
|
||||||
slots[size + 1] = new Slot();
|
// slots[size + 1] = new Slot();
|
||||||
slots[size + 1].setNum((int) (val >> 32));
|
slots[size + 1].setNum((int) (val >> 32));
|
||||||
size += 2;
|
size += 2;
|
||||||
}
|
}
|
||||||
@ -92,7 +97,7 @@ public class OperandStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushRef(Object ref) {
|
public void pushRef(Object ref) {
|
||||||
slots[size] = new Slot();
|
// slots[size] = new Slot();
|
||||||
slots[size].setRef(ref);
|
slots[size].setRef(ref);
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.gabongao.jvm.rtda;
|
package com.gabongao.jvm.rtda;
|
||||||
|
|
||||||
|
import com.gabongao.jvm.rtda.heap.Object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ┏┓ ┏┓+ +
|
* ┏┓ ┏┓+ +
|
||||||
* ┏┛┻━━━┛┻┓ + +
|
* ┏┛┻━━━┛┻┓ + +
|
||||||
@ -36,6 +38,11 @@ public class Slot {
|
|||||||
private int num;
|
private int num;
|
||||||
private Object ref;
|
private Object ref;
|
||||||
|
|
||||||
|
public Slot() {
|
||||||
|
this.num = 0;
|
||||||
|
this.ref = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Slot{" +
|
return "Slot{" +
|
||||||
@ -59,4 +66,12 @@ public class Slot {
|
|||||||
public void setRef(Object ref) {
|
public void setRef(Object ref) {
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Slot copySlot() {
|
||||||
|
Slot s = new Slot();
|
||||||
|
s.setNum(this.getNum());
|
||||||
|
s.setRef(this.getRef());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/com/gabongao/jvm/rtda/heap/AccessFlags.java
Normal file
64
src/com/gabongao/jvm/rtda/heap/AccessFlags.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
191
src/com/gabongao/jvm/rtda/heap/ClassLoader.java
Normal file
191
src/com/gabongao/jvm/rtda/heap/ClassLoader.java
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
119
src/com/gabongao/jvm/rtda/heap/ClassMember.java
Normal file
119
src/com/gabongao/jvm/rtda/heap/ClassMember.java
Normal 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
42
src/com/gabongao/jvm/rtda/heap/ClassRef.java
Normal file
42
src/com/gabongao/jvm/rtda/heap/ClassRef.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
380
src/com/gabongao/jvm/rtda/heap/ClassStruct.java
Normal file
380
src/com/gabongao/jvm/rtda/heap/ClassStruct.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/com/gabongao/jvm/rtda/heap/Constant.java
Normal file
48
src/com/gabongao/jvm/rtda/heap/Constant.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/com/gabongao/jvm/rtda/heap/ConstantPool.java
Normal file
55
src/com/gabongao/jvm/rtda/heap/ConstantPool.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/com/gabongao/jvm/rtda/heap/Field.java
Normal file
110
src/com/gabongao/jvm/rtda/heap/Field.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/com/gabongao/jvm/rtda/heap/FieldRef.java
Normal file
82
src/com/gabongao/jvm/rtda/heap/FieldRef.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/com/gabongao/jvm/rtda/heap/InterfaceMethodRef.java
Normal file
43
src/com/gabongao/jvm/rtda/heap/InterfaceMethodRef.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/com/gabongao/jvm/rtda/heap/MemberRef.java
Normal file
55
src/com/gabongao/jvm/rtda/heap/MemberRef.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
138
src/com/gabongao/jvm/rtda/heap/Method.java
Normal file
138
src/com/gabongao/jvm/rtda/heap/Method.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
47
src/com/gabongao/jvm/rtda/heap/MethodRef.java
Normal file
47
src/com/gabongao/jvm/rtda/heap/MethodRef.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/com/gabongao/jvm/rtda/heap/Object.java
Normal file
59
src/com/gabongao/jvm/rtda/heap/Object.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,9 @@
|
|||||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
* 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 {
|
public class Slots extends LocalVars {
|
||||||
//TODO
|
public Slots(int slotCount) {
|
||||||
|
super(slotCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
85
src/com/gabongao/jvm/rtda/heap/SymRef.java
Normal file
85
src/com/gabongao/jvm/rtda/heap/SymRef.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user