Instructions

This commit is contained in:
Imgaojp 2017-02-19 21:53:17 +08:00
parent 716f2c9ad2
commit bad3a37270
16 changed files with 2792 additions and 12 deletions

View File

@ -0,0 +1,84 @@
/*
* 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;
import com.gabongao.jvm.classfile.AttrCode;
import com.gabongao.jvm.classfile.AttributeInfo;
import com.gabongao.jvm.classfile.MemberInfo;
import com.gabongao.jvm.instructions.*;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.Thread;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/19.
*/
public class Interpreter {
public void doInterpreter(MemberInfo memberInfo) {
AttrCode codeAttr = memberInfo.getCodeAttribure();
int maxLocals = codeAttr.getMaxLocals();
int maxStack = codeAttr.getMaxStack();
byte[] byteCode = codeAttr.getCode();
Thread thread = new Thread();
Frame frame = new Frame(thread, maxLocals, maxStack);
thread.pushFrame(frame);
try {
loop(thread, byteCode);
} catch (Exception e) {
e.printStackTrace();
System.out.println();
System.out.printf("LocalVars: %s\n", frame.getLocalVars());
System.out.printf("OperandStack: %s\n", frame.getOperandStack());
}
}
public void loop(Thread thread, byte[] byteCode) {
Frame frame = thread.popFrame();
BytecodeReader bytecodeReader = new BytecodeReader();
int n = 1;
for (; ; ) {
int pc = frame.getNextPc();
thread.setPc(pc);
System.out.printf("loop: %2d\t", n);
bytecodeReader.reset(byteCode, pc);
char opcode = (char) bytecodeReader.readInt8();
Instruction instruction = Factory.newInstruction((byte) opcode);
instruction.fetchOperands(bytecodeReader);
if (n == 13 || n == 14) {
System.out.printf("%d\t", bytecodeReader.getPc());
}
frame.setNextPc(bytecodeReader.getPc());
System.out.printf("pc:%2d\t inst:%s\n", pc, instruction.getClass().getName());
instruction.execute(frame);
n++;
}
}
}

View File

@ -1,14 +1,12 @@
package com.gabongao.jvm;
import com.gabongao.jvm.classfile.ClassFile;
import com.gabongao.jvm.classfile.MemberInfo;
import com.gabongao.jvm.classpath.ClassPath;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.LocalVars;
import com.gabongao.jvm.rtda.OperandStack;
import java.io.File;
import java.util.Arrays;
/**
*            + +
*         + +
@ -97,12 +95,41 @@ public class Jvm {
}
*/
/* ch04
Frame frame = new Frame(100, 100);
testLocalVars(frame.getLocalVars());
testOperandStack(frame.getOperandStack());
*/
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);
}
}
public static MemberInfo getMainMethod(ClassFile classFile) {
for (MemberInfo methodInfo : classFile.getMethods()
) {
if ("main".equals(methodInfo.getName()) && methodInfo.getDescriptor().equals("([Ljava/lang/String;)V")) {
return methodInfo;
}
}
return null;
}
public static ClassFile loadClass(String className, ClassPath classPath) {
byte[] classData = classPath.readClass(className);
return new ClassFile(classData);
}
private static void testLocalVars(LocalVars localVars) {
localVars.setInt(0, 100);

View File

@ -33,11 +33,11 @@ package com.gabongao.jvm.classfile;
* Created by Imgaojp on 2017/2/18.
*/
public class AttrCode implements AttributeInfo {
char maxStack, maxLocals;
byte[] code;
ConstantPool constantPool;
AttributeInfo[] attributes;
ExceptionTableEntry[] exceptionTableEntries;
private char maxStack, maxLocals;
private ConstantPool constantPool;
private AttributeInfo[] attributes;
private ExceptionTableEntry[] exceptionTableEntries;
public AttrCode(ConstantPool constantPool) {
@ -54,6 +54,30 @@ public class AttrCode implements AttributeInfo {
attributes = ClassFile.readAttributes(classReader, constantPool);
}
public char getMaxStack() {
return maxStack;
}
public char getMaxLocals() {
return maxLocals;
}
public byte[] getCode() {
return code;
}
public ConstantPool getConstantPool() {
return constantPool;
}
public AttributeInfo[] getAttributes() {
return attributes;
}
public ExceptionTableEntry[] getExceptionTableEntries() {
return exceptionTableEntries;
}
public ExceptionTableEntry[] readExceptionTable(ClassReader classReader) {
char exceptionTableLength = classReader.readUint16();
ExceptionTableEntry[] exceptionTableEntries = new ExceptionTableEntry[exceptionTableLength];

View File

@ -33,9 +33,9 @@ package com.gabongao.jvm.classfile;
* Created by Imgaojp on 2017/2/18.
*/
public class MemberInfo {
ConstantPool cp;
char accessFlags, nameIndex, descriptorIndex;
AttributeInfo[] attributes;
private ConstantPool cp;
private char accessFlags, nameIndex, descriptorIndex;
private AttributeInfo[] attributes;
public MemberInfo(ClassReader classReader, ConstantPool cp) {
@ -46,6 +46,16 @@ public class MemberInfo {
this.attributes = ClassFile.readAttributes(classReader, cp);
}
public AttrCode getCodeAttribure() {
for (AttributeInfo attr : attributes
) {
if (attr instanceof AttrCode) {
return (AttrCode) attr;
}
}
return null;
}
public String getName() {
return cp.getUTF8(nameIndex);
}

View File

@ -0,0 +1,305 @@
/*
* 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.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.Object;
import com.gabongao.jvm.rtda.OperandStack;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class BranchInstruction implements Instruction {
private int offset;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
offset = bytecodeReader.readInt16();
}
@Override
public void execute(Frame frame) {
}
;
public void branch(Frame frame, int offset) {
int pc = frame.getThread().getPc();
int nextPc = pc + offset;
frame.setNextPc(nextPc);
}
public class Ifeq extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val == 0) {
branch(frame, super.offset);
}
}
}
public class Ifne extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val != 0) {
branch(frame, super.offset);
}
}
}
public class Iflt extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val < 0) {
branch(frame, super.offset);
}
}
}
public class Ifle extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val <= 0) {
branch(frame, super.offset);
}
}
}
public class Ifgt extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val > 0) {
branch(frame, super.offset);
}
}
}
public class Ifge extends BranchInstruction {
@Override
public void execute(Frame frame) {
int val = frame.getOperandStack().popInt();
if (val >= 0) {
branch(frame, super.offset);
}
}
}
public class If_icmpne extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 != val2) {
branch(frame, super.offset);
}
}
}
public class If_icmpeq extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 == val2) {
branch(frame, super.offset);
}
}
}
public class If_icmplt extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 < val2) {
branch(frame, super.offset);
}
}
}
public class If_icmple extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 <= val2) {
branch(frame, super.offset);
}
}
}
public class If_icmpgt extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 > val2) {
branch(frame, super.offset);
}
}
}
public class If_icmpge extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val2 = operandStack.popInt();
int val1 = operandStack.popInt();
if (val1 >= val2) {
branch(frame, super.offset);
}
}
}
public class If_acmpeq extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Object val2 = operandStack.popRef();
Object val1 = operandStack.popRef();
if (val1 == val2) {
branch(frame, super.offset);
}
}
}
public class If_acmpne extends BranchInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Object val2 = operandStack.popRef();
Object val1 = operandStack.popRef();
if (val1 != val2) {
branch(frame, super.offset);
}
}
}
public class Goto extends BranchInstruction {
@Override
public void execute(Frame frame) {
branch(frame, super.offset);
}
}
public class Goto_W extends BranchInstruction {
@Override
public void execute(Frame frame) {
branch(frame, super.offset);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.offset = bytecodeReader.readInt32();
}
}
public class TableSwitch extends BranchInstruction {
int low, high, defaultOffset;
int[] jumpOffsets;
@Override
public void execute(Frame frame) {
int index = frame.getOperandStack().popInt();
int offset;
if ((index >= low) && (index <= high)) {
offset = (jumpOffsets[index - low]);
} else {
offset = defaultOffset;
}
branch(frame, offset);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
bytecodeReader.skipPadding();
defaultOffset = bytecodeReader.readInt32();
low = bytecodeReader.readInt32();
high = bytecodeReader.readInt32();
int jumpOffsetsCount = high - low + 1;
jumpOffsets = bytecodeReader.readInt32s(jumpOffsetsCount);
}
}
public class LookUpSwitch extends BranchInstruction {
int defaultOffset, npairs;
int[] matchOffsets;
@Override
public void execute(Frame frame) {
int key = frame.getOperandStack().popInt();
for (int i = 0; i < npairs * 2; i += 2) {
if (matchOffsets[i] == key) {
branch(frame, matchOffsets[i + 1]);
return;
}
}
branch(frame, defaultOffset);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
bytecodeReader.skipPadding();
defaultOffset = bytecodeReader.readInt32();
npairs = bytecodeReader.readInt32();
matchOffsets = bytecodeReader.readInt32s(npairs * 2);
}
}
public class Ifnull extends BranchInstruction {
@Override
public void execute(Frame frame) {
Object ref = frame.getOperandStack().popRef();
if (ref == null) {
branch(frame, super.offset);
}
}
}
public class Ifnonnull extends BranchInstruction {
@Override
public void execute(Frame frame) {
Object ref = frame.getOperandStack().popRef();
if (ref != null) {
branch(frame, super.offset);
}
}
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.instructions;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class BytecodeReader {
private byte[] code;
private int pc;
public void reset(byte[] code, int pc) {
this.code = code;
this.pc = pc;
}
public int getPc() {
return pc;
}
public char readUint8() {
byte b = code[pc];
pc++;
return (char) b;
}
public char readUint16() {
// Byte.toUnsignedInt((byte) readUint8());
char high = (char) (readUint8() << 8);
char low = readUint8();
char res = (char) ((high & 0xff00) | (low & 0x00ff));
return res;
}
public int readInt8() {
return (int) readUint8();
}
public int readInt16() {
char uint16 = readUint16();
if (uint16 >> 15 == 1) {
return (((~(uint16 - 1)) & 0x000000007f) * -1);
} else {
return uint16;
}
}
public int readInt32() {
return (((((int) readUint8()) << 24) & 0xff000000) | ((((int) readUint8()) << 16) & 0x00ff0000) | ((((int) readUint8()) << 8) & 0x0000ff00) | ((((int) readUint8())) & 0x000000ff));
}
public void skipPadding() {
while ((pc % 4) != 0) {
readInt8();
}
}
public int[] readInt32s(int count) {
int[] ints = new int[count];
for (int i = 0; i < count; i++) {
ints[i] = readInt32();
}
return ints;
}
}

View File

@ -0,0 +1,466 @@
/*
* 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.instructions;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/19.
*/
public class Factory {
static OperandsInstruction operandsInstruction = new OperandsInstruction();
static BranchInstruction branchInstruction = new BranchInstruction();
static Index8Instruction index8Instruction = new Index8Instruction();
public static Instruction newInstruction(byte opcode) {
switch (Byte.toUnsignedInt(opcode)) {
case 0x00:
return operandsInstruction.new Nop();
case 0x01:
return operandsInstruction.new Aconst_null();
case 0x02:
return operandsInstruction.new Iconst_M1();
case 0x03:
return operandsInstruction.new Iconst_0();
case 0x04:
return operandsInstruction.new Iconst_1();
case 0x05:
return operandsInstruction.new Iconst_2();
case 0x06:
return operandsInstruction.new Iconst_3();
case 0x07:
return operandsInstruction.new Iconst_4();
case 0x08:
return operandsInstruction.new Iconst_5();
case 0x09:
return operandsInstruction.new Lconst_0();
case 0x0a:
return operandsInstruction.new Lconst_1();
case 0x0b:
return operandsInstruction.new Fconst_0();
case 0x0c:
return operandsInstruction.new Fconst_1();
case 0x0d:
return operandsInstruction.new Fconst_2();
case 0x0e:
return operandsInstruction.new Dconst_0();
case 0x0f:
return operandsInstruction.new Dconst_1();
case 0x10:
return operandsInstruction.new Bipush();
case 0x11:
return operandsInstruction.new Sipush();
//case 0x12:
// return &LDC{}
//case 0x13:
// return &LDC_W{}
//case 0x14:
// return &LDC2_W{}
case 0x15:
return index8Instruction.new Iload();
case 0x16:
return index8Instruction.new Lload();
case 0x17:
return index8Instruction.new Fload();
case 0x18:
return index8Instruction.new Dload();
case 0x19:
return index8Instruction.new Aload();
case 0x1a:
return (index8Instruction.new Iload()).new Iload_0();
case 0x1b:
return (index8Instruction.new Iload()).new Iload_1();
case 0x1c:
return (index8Instruction.new Iload()).new Iload_2();
case 0x1d:
return (index8Instruction.new Iload()).new Iload_3();
case 0x1e:
return (index8Instruction.new Lload()).new Lload_0();
case 0x1f:
return (index8Instruction.new Lload()).new Lload_1();
case 0x20:
return (index8Instruction.new Lload()).new Lload_2();
case 0x21:
return (index8Instruction.new Lload()).new Lload_3();
case 0x22:
return (index8Instruction.new Fload()).new Fload_0();
case 0x23:
return (index8Instruction.new Fload()).new Fload_1();
case 0x24:
return (index8Instruction.new Fload()).new Fload_2();
case 0x25:
return (index8Instruction.new Fload()).new Fload_3();
case 0x26:
return (index8Instruction.new Dload()).new Dload_0();
case 0x27:
return (index8Instruction.new Dload()).new Dload_1();
case 0x28:
return (index8Instruction.new Dload()).new Dload_2();
case 0x29:
return (index8Instruction.new Dload()).new Dload_3();
case 0x2a:
return (index8Instruction.new Aload()).new Aload_0();
case 0x2b:
return (index8Instruction.new Aload()).new Aload_1();
case 0x2c:
return (index8Instruction.new Aload()).new Aload_2();
case 0x2d:
return (index8Instruction.new Aload()).new Aload_3();
//case 0x2e:
// return iaload
//case 0x2f:
// return laload
//case 0x30:
// return faload
//case 0x31:
// return daload
//case 0x32:
// return aaload
//case 0x33:
// return baload
//case 0x34:
// return caload
//case 0x35:
// return saload
case 0x36:
return index8Instruction.new Istore();
case 0x37:
return index8Instruction.new Lstore();
case 0x38:
return index8Instruction.new Fstore();
case 0x39:
return index8Instruction.new Dstore();
case 0x3a:
return index8Instruction.new Astore();
case 0x3b:
return (index8Instruction.new Istore()).new Istore_0();
case 0x3c:
return (index8Instruction.new Istore()).new Istore_1();
case 0x3d:
return (index8Instruction.new Istore()).new Istore_2();
case 0x3e:
return (index8Instruction.new Istore()).new Istore_3();
case 0x3f:
return (index8Instruction.new Lstore()).new Lstore_0();
case 0x40:
return (index8Instruction.new Lstore()).new Lstore_1();
case 0x41:
return (index8Instruction.new Lstore()).new Lstore_2();
case 0x42:
return (index8Instruction.new Lstore()).new Lstore_3();
case 0x43:
return (index8Instruction.new Fstore()).new Fstore_0();
case 0x44:
return (index8Instruction.new Fstore()).new Fstore_1();
case 0x45:
return (index8Instruction.new Fstore()).new Fstore_2();
case 0x46:
return (index8Instruction.new Fstore()).new Fstore_3();
case 0x47:
return (index8Instruction.new Dstore()).new Dstore_0();
case 0x48:
return (index8Instruction.new Dstore()).new Dstore_1();
case 0x49:
return (index8Instruction.new Dstore()).new Dstore_2();
case 0x4a:
return (index8Instruction.new Dstore()).new Dstore_3();
case 0x4b:
return (index8Instruction.new Astore()).new Astore_0();
case 0x4c:
return (index8Instruction.new Astore()).new Astore_1();
case 0x4d:
return (index8Instruction.new Astore()).new Astore_2();
case 0x4e:
return (index8Instruction.new Astore()).new Astore_3();
//case 0x4f:
// return iastore
//case 0x50:
// return lastore
//case 0x51:
// return fastore
//case 0x52:
// return dastore
//case 0x53:
// return aastore
//case 0x54:
// return bastore
//case 0x55:
// return castore
//case 0x56:
// return sastore
case 0x57:
return operandsInstruction.new Pop();
case 0x58:
return operandsInstruction.new Pop2();
case 0x59:
return operandsInstruction.new Dup();
case 0x5a:
return operandsInstruction.new Dup_X1();
case 0x5b:
return operandsInstruction.new Dup_X2();
case 0x5c:
return operandsInstruction.new Dup2();
case 0x5d:
return operandsInstruction.new Dup2_X1();
case 0x5e:
return operandsInstruction.new Dup2_X2();
case 0x5f:
return operandsInstruction.new Swap();
case 0x60:
return operandsInstruction.new Iadd();
case 0x61:
return operandsInstruction.new Ladd();
case 0x62:
return operandsInstruction.new Fadd();
case 0x63:
return operandsInstruction.new Dadd();
case 0x64:
return operandsInstruction.new Isub();
case 0x65:
return operandsInstruction.new Lsub();
case 0x66:
return operandsInstruction.new Fsub();
case 0x67:
return operandsInstruction.new Dsub();
case 0x68:
return operandsInstruction.new Imul();
case 0x69:
return operandsInstruction.new Lmul();
case 0x6a:
return operandsInstruction.new Fmul();
case 0x6b:
return operandsInstruction.new Dmul();
case 0x6c:
return operandsInstruction.new Idiv();
case 0x6d:
return operandsInstruction.new Ldiv();
case 0x6e:
return operandsInstruction.new Fdiv();
case 0x6f:
return operandsInstruction.new Ddiv();
case 0x70:
return operandsInstruction.new Irem();
case 0x71:
return operandsInstruction.new Lrem();
case 0x72:
return operandsInstruction.new Frem();
case 0x73:
return operandsInstruction.new Drem();
case 0x74:
return operandsInstruction.new Ineg();
case 0x75:
return operandsInstruction.new Lneg();
case 0x76:
return operandsInstruction.new Fneg();
case 0x77:
return operandsInstruction.new Dneg();
case 0x78:
return operandsInstruction.new Ishl();
case 0x79:
return operandsInstruction.new Lshl();
case 0x7a:
return operandsInstruction.new Ishr();
case 0x7b:
return operandsInstruction.new Lshr();
case 0x7c:
return operandsInstruction.new Iushr();
case 0x7d:
return operandsInstruction.new Lushr();
case 0x7e:
return operandsInstruction.new Iand();
case 0x7f:
return operandsInstruction.new Land();
case 0x80:
return operandsInstruction.new Ior();
case 0x81:
return operandsInstruction.new Lor();
case 0x82:
return operandsInstruction.new Ixor();
case 0x83:
return operandsInstruction.new Lxor();
case 0x84:
return index8Instruction.new Iinc();
case 0x85:
return operandsInstruction.new I2l();
case 0x86:
return operandsInstruction.new I2f();
case 0x87:
return operandsInstruction.new I2d();
case 0x88:
return operandsInstruction.new L2i();
case 0x89:
return operandsInstruction.new L2f();
case 0x8a:
return operandsInstruction.new L2d();
case 0x8b:
return operandsInstruction.new F2i();
case 0x8c:
return operandsInstruction.new F2l();
case 0x8d:
return operandsInstruction.new F2d();
case 0x8e:
return operandsInstruction.new D2i();
case 0x8f:
return operandsInstruction.new D2l();
case 0x90:
return operandsInstruction.new D2f();
// case 0x91:
// return operandsInstruction.new I2b();
// case 0x92:
// return i2c
// case 0x93:
// return i2s
case 0x94:
return operandsInstruction.new Lcmp();
case 0x95:
return (operandsInstruction.new Fcmp()).new Fcmpl();
case 0x96:
return (operandsInstruction.new Fcmp()).new Fcmpg();
case 0x97:
return (operandsInstruction.new Dcmp()).new Dcmpl();
case 0x98:
return (operandsInstruction.new Dcmp()).new Dcmpg();
case 0x99:
return branchInstruction.new Ifeq();
case 0x9a:
return branchInstruction.new Ifne();
case 0x9b:
return branchInstruction.new Iflt();
case 0x9c:
return branchInstruction.new Ifge();
case 0x9d:
return branchInstruction.new Ifgt();
case 0x9e:
return branchInstruction.new Ifle();
case 0x9f:
return branchInstruction.new If_icmpeq();
case 0xa0:
return branchInstruction.new If_icmpne();
case 0xa1:
return branchInstruction.new If_icmplt();
case 0xa2:
return branchInstruction.new If_icmpge();
case 0xa3:
return branchInstruction.new If_icmpgt();
case 0xa4:
return branchInstruction.new If_icmple();
case 0xa5:
return branchInstruction.new If_acmpeq();
case 0xa6:
return branchInstruction.new If_acmpne();
case 0xa7:
return branchInstruction.new Goto();
// case 0xa8:
// return &control.JSR {
// }
// case 0xa9:
// return &control.RET {
// }
case 0xaa:
return branchInstruction.new TableSwitch();
case 0xab:
return branchInstruction.new LookUpSwitch();
//
// case 0xac:
// return ireturn
// case 0xad:
// return lreturn
// case 0xae:
// return freturn
// case 0xaf:
// return dreturn
// case 0xb0:
// return areturn
// case 0xb1:
// return _return
//case 0xb2:
// return &GET_STATIC{}
//case 0xb3:
// return &PUT_STATIC{}
//case 0xb4:
// return &GET_FIELD{}
//case 0xb5:
// return &PUT_FIELD{}
//case 0xb6:
// return &INVOKE_VIRTUAL{}
//case 0xb7:
// return &INVOKE_SPECIAL{}
//case 0xb8:
// return &INVOKE_STATIC{}
//case 0xb9:
// return &INVOKE_INTERFACE{}
//case 0xba:
// return &INVOKE_DYNAMIC{}
//case 0xbb:
// return &NEW{}
//case 0xbc:
// return &NEW_ARRAY{}
//case 0xbd:
// return &ANEW_ARRAY{}
//case 0xbe:
// return arraylength
//case 0xbf:
// return athrow
//case 0xc0:
// return &CHECK_CAST{}
//case 0xc1:
// return &INSTANCE_OF{}
//case 0xc2:
// return monitorenter
//case 0xc3:
// return monitorexit
// case 0xc4:
// return &extended.WIDE {
// }
//case 0xc5:
// return &MULTI_ANEW_ARRAY{}
case 0xc6:
return branchInstruction.new Ifnull();
case 0xc7:
return branchInstruction.new Ifnonnull();
case 0xc8:
return branchInstruction.new Goto_W();
// case 0xc9:
// return &control.JSR_W {
// }
////case 0xca: todo breakpoint
//case 0xfe:
// return invoke_native // impdep1
//case 0xff:
// return &BOOTSTRAP{} // impdep2
default:
throw new RuntimeException(String.format("Bad opcode: 0X%X", opcode));
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.instructions;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public abstract class Index16Instruction implements Instruction {
private char Index;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
Index = bytecodeReader.readUint16();
}
}

View File

@ -0,0 +1,688 @@
/*
* 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.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.LocalVars;
import com.gabongao.jvm.rtda.Object;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class Index8Instruction implements Instruction {
private char Index;
public char getIndex() {
return Index;
}
public void setIndex(char index) {
Index = index;
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
Index = bytecodeReader.readUint8();
}
public void execute(Frame frame) {
}
;
public class Iload extends Index8Instruction {
@Override
public void execute(Frame frame) {
_iload(frame, getIndex());
}
public void _iload(Frame frame, int index) {
int val = frame.getLocalVars().getInt(index);
frame.getOperandStack().pushInt(val);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
public class Iload_0 extends Iload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_iload(frame, 0);
}
}
public class Iload_1 extends Iload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_iload(frame, 1);
}
}
public class Iload_2 extends Iload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_iload(frame, 2);
}
}
public class Iload_3 extends Iload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_iload(frame, 3);
}
}
}
public class Aload extends Index8Instruction {
@Override
public void execute(Frame frame) {
_aload(frame, getIndex());
}
public void _aload(Frame frame, int index) {
Object val = frame.getLocalVars().getRef(index);
frame.getOperandStack().pushRef(val);
}
public class Aload_0 extends Aload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_aload(frame, 0);
}
}
public class Aload_1 extends Aload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_aload(frame, 1);
}
}
public class Aload_2 extends Aload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_aload(frame, 2);
}
}
public class Aload_3 extends Aload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_aload(frame, 3);
}
}
}
public class Dload extends Index8Instruction {
@Override
public void execute(Frame frame) {
_dload(frame, getIndex());
}
public void _dload(Frame frame, int index) {
double val = frame.getLocalVars().getDouble(index);
frame.getOperandStack().pushDouble(val);
}
public class Dload_0 extends Dload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dload(frame, 0);
}
}
public class Dload_1 extends Dload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dload(frame, 1);
}
}
public class Dload_2 extends Dload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dload(frame, 2);
}
}
public class Dload_3 extends Dload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dload(frame, 3);
}
}
}
public class Fload extends Index8Instruction {
@Override
public void execute(Frame frame) {
_fload(frame, getIndex());
}
public void _fload(Frame frame, int index) {
float val = frame.getLocalVars().getFloat(index);
frame.getOperandStack().pushFloat(val);
}
public class Fload_0 extends Fload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fload(frame, 0);
}
}
public class Fload_1 extends Fload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fload(frame, 1);
}
}
public class Fload_2 extends Fload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fload(frame, 2);
}
}
public class Fload_3 extends Fload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fload(frame, 3);
}
}
}
public class Lload extends Index8Instruction {
@Override
public void execute(Frame frame) {
_lload(frame, getIndex());
}
public void _lload(Frame frame, int index) {
long val = frame.getLocalVars().getLong(index);
frame.getOperandStack().pushLong(val);
}
public class Lload_0 extends Lload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lload(frame, 0);
}
}
public class Lload_1 extends Lload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lload(frame, 1);
}
}
public class Lload_2 extends Lload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lload(frame, 2);
}
}
public class Lload_3 extends Lload {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lload(frame, 3);
}
}
}
public class Lstore extends Index8Instruction {
@Override
public void execute(Frame frame) {
_lstore(frame, getIndex());
}
public void _lstore(Frame frame, int index) {
Long val = frame.getOperandStack().popLong();
frame.getLocalVars().setLong(index, val);
}
public class Lstore_0 extends Lstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lstore(frame, 0);
}
}
public class Lstore_1 extends Lstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lstore(frame, 1);
}
}
public class Lstore_2 extends Lstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lstore(frame, 2);
}
}
public class Lstore_3 extends Lstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_lstore(frame, 3);
}
}
}
public class Astore extends Index8Instruction {
@Override
public void execute(Frame frame) {
_astore(frame, getIndex());
}
public void _astore(Frame frame, int index) {
Object val = frame.getOperandStack().popRef();
frame.getLocalVars().setRef(index, val);
}
public class Astore_0 extends Astore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_astore(frame, 0);
}
}
public class Astore_1 extends Astore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_astore(frame, 1);
}
}
public class Astore_2 extends Astore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_astore(frame, 2);
}
}
public class Astore_3 extends Astore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_astore(frame, 3);
}
}
}
public class Istore extends Index8Instruction {
@Override
public void execute(Frame frame) {
_istore(frame, getIndex());
}
public void _istore(Frame frame, int index) {
int val = frame.getOperandStack().popInt();
frame.getLocalVars().setInt(index, val);
}
public class Istore_0 extends Istore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_istore(frame, 0);
}
}
public class Istore_1 extends Istore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_istore(frame, 1);
}
}
public class Istore_2 extends Istore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_istore(frame, 2);
}
}
public class Istore_3 extends Istore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_istore(frame, 3);
}
}
}
public class Dstore extends Index8Instruction {
@Override
public void execute(Frame frame) {
_dstore(frame, getIndex());
}
public void _dstore(Frame frame, int index) {
double val = frame.getOperandStack().popDouble();
frame.getLocalVars().setDouble(index, val);
}
public class Dstore_0 extends Dstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dstore(frame, 0);
}
}
public class Dstore_1 extends Dstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dstore(frame, 1);
}
}
public class Dstore_2 extends Dstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dstore(frame, 2);
}
}
public class Dstore_3 extends Dstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_dstore(frame, 3);
}
}
}
public class Fstore extends Index8Instruction {
@Override
public void execute(Frame frame) {
_fstore(frame, getIndex());
}
public void _fstore(Frame frame, int index) {
float val = frame.getOperandStack().popFloat();
frame.getLocalVars().setFloat(index, val);
}
public class Fstore_0 extends Fstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fstore(frame, 0);
}
}
public class Fstore_1 extends Fstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fstore(frame, 1);
}
}
public class Fstore_2 extends Fstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fstore(frame, 2);
}
}
public class Fstore_3 extends Fstore {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
}
@Override
public void execute(Frame frame) {
_fstore(frame, 3);
}
}
}
public class Iinc extends Index8Instruction {
private int constVal;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.setIndex(bytecodeReader.readUint8());
constVal = bytecodeReader.readInt8();
}
@Override
public void execute(Frame frame) {
LocalVars localVars = frame.getLocalVars();
localVars.setInt(super.getIndex(), localVars.getInt(super.getIndex()) + constVal);
}
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.instructions;
import com.gabongao.jvm.rtda.Frame;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public interface Instruction {
void fetchOperands(BytecodeReader bytecodeReader);
void execute(Frame frame);
}

View File

@ -0,0 +1,950 @@
/*
* 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.instructions;
import com.gabongao.jvm.rtda.Frame;
import com.gabongao.jvm.rtda.OperandStack;
import com.gabongao.jvm.rtda.Slot;
import com.gabongao.jvm.rtda.Stack;
import org.ietf.jgss.Oid;
import sun.awt.OSInfo;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class OperandsInstruction implements Instruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
//TODO
}
public void execute(Frame frame) {
}
;
public class Nop extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
}
}
public class Aconst_null extends OperandsInstruction {
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushRef(null);
}
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
}
public class Dconst_0 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushDouble(0.0);
}
}
public class Dconst_1 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushDouble(1.0);
}
}
public class Fconst_0 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushFloat(0.0f);
}
}
public class Fconst_1 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushFloat(1.0f);
}
}
public class Fconst_2 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushDouble(2.0f);
}
}
public class Iconst_M1 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(-1);
}
}
public class Iconst_0 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(0);
}
}
public class Iconst_1 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(1);
}
}
public class Iconst_2 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(2);
}
}
public class Iconst_3 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(3);
}
}
public class Iconst_4 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(4);
}
}
public class Iconst_5 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt(5);
}
}
public class Lconst_0 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushLong(0L);
}
}
public class Lconst_1 extends OperandsInstruction {
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
super.fetchOperands(bytecodeReader);
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushLong(1L);
}
}
public class Bipush extends OperandsInstruction {
byte val;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
val = (byte) bytecodeReader.readUint8();
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt((int) val);
}
}
public class Sipush extends OperandsInstruction {
char val;
@Override
public void fetchOperands(BytecodeReader bytecodeReader) {
val = bytecodeReader.readUint16();
}
@Override
public void execute(Frame frame) {
frame.getOperandStack().pushInt((int) val);
}
}
public class Pop extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
operandStack.popSlot();
}
}
public class Pop2 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
operandStack.popSlot();
operandStack.popSlot();
}
}
public class Dup extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot = operandStack.popSlot();
operandStack.pushSlot(slot);
operandStack.pushSlot(slot);
}
}
public class Dup_X1 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
}
}
public class Dup_X2 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
Slot slot3 = operandStack.popSlot();
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
}
}
public class Dup2 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
}
}
public class Dup2_X1 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
Slot slot3 = operandStack.popSlot();
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
}
}
public class Dup2_X2 extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
Slot slot3 = operandStack.popSlot();
Slot slot4 = operandStack.popSlot();
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot4);
operandStack.pushSlot(slot3);
operandStack.pushSlot(slot2);
operandStack.pushSlot(slot1);
}
}
public class Swap extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
Slot slot1 = operandStack.popSlot();
Slot slot2 = operandStack.popSlot();
operandStack.pushSlot(slot1);
operandStack.pushSlot(slot2);
}
}
public class Irem extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
int v2 = stack.popInt();
int v1 = stack.popInt();
if (v2 == 0) {
throw new RuntimeException("ArithmeticException");
}
stack.pushInt(v1 % v2);
}
}
public class Lrem extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
long v2 = stack.popLong();
long v1 = stack.popLong();
if (v2 == 0) {
throw new RuntimeException("ArithmeticException");
}
stack.pushLong(v1 % v2);
}
}
public class Frem extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
float v2 = stack.popFloat();
float v1 = stack.popFloat();
stack.pushFloat(v1 % v2);
}
}
public class Drem extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
double v2 = stack.popDouble();
double v1 = stack.popDouble();
stack.pushDouble(v1 % v2);
}
}
public class Idiv extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
int v2 = stack.popInt();
int v1 = stack.popInt();
if (v2 == 0) {
throw new RuntimeException("ArithmeticException");
}
stack.pushInt(v1 / v2);
}
}
public class Ldiv extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
long v2 = stack.popLong();
long v1 = stack.popLong();
if (v2 == 0) {
throw new RuntimeException("ArithmeticException");
}
stack.pushLong(v1 / v2);
}
}
public class Fdiv extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
float v2 = stack.popFloat();
float v1 = stack.popFloat();
stack.pushFloat(v1 / v2);
}
}
public class Ddiv extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack stack = frame.getOperandStack();
double v2 = stack.popDouble();
double v1 = stack.popDouble();
stack.pushDouble(v1 / v2);
}
}
public class Iadd extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 + v2);
}
}
public class Dadd extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double v2 = operandStack.popDouble();
double v1 = operandStack.popDouble();
operandStack.pushDouble(v1 + v2);
}
}
public class Fadd extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float v2 = operandStack.popFloat();
float v1 = operandStack.popFloat();
operandStack.pushFloat(v1 + v2);
}
}
public class Ladd extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 + v2);
}
}
public class Isub extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 - v2);
}
}
public class Dsub extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double v2 = operandStack.popDouble();
double v1 = operandStack.popDouble();
operandStack.pushDouble(v1 - v2);
}
}
public class Fsub extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float v2 = operandStack.popFloat();
float v1 = operandStack.popFloat();
operandStack.pushFloat(v1 - v2);
}
}
public class Lsub extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 - v2);
}
}
public class Imul extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 * v2);
}
}
public class Dmul extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double v2 = operandStack.popDouble();
double v1 = operandStack.popDouble();
operandStack.pushDouble(v1 * v2);
}
}
public class Fmul extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float v2 = operandStack.popFloat();
float v1 = operandStack.popFloat();
operandStack.pushFloat(v1 * v2);
}
}
public class Lmul extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 * v2);
}
}
public class Ineg extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int val = operandStack.popInt();
operandStack.pushInt(-val);
}
}
public class Dneg extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double val = operandStack.popDouble();
operandStack.pushDouble(-val);
}
}
public class Fneg extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float val = operandStack.popFloat();
operandStack.pushFloat(-val);
}
}
public class Lneg extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long val = operandStack.popLong();
operandStack.pushLong(-val);
}
}
public class Ishl extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 << v2);
}
}
public class Ishr extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 >> v2);
}
}
public class Iushr extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 >>> v2);
}
}
public class Lshl extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 << v2);
}
}
public class Lshr extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 >> v2);
}
}
public class Lushr extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 >>> v2);
}
}
public class Iand extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 & v2);
}
}
public class Land extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 & v2);
}
}
public class Ior extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 | v2);
}
}
public class Lor extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 | v2);
}
}
public class Ixor extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int v2 = operandStack.popInt();
int v1 = operandStack.popInt();
operandStack.pushInt(v1 ^ v2);
}
}
public class Lxor extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
operandStack.pushLong(v1 ^ v2);
}
}
public class D2f extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double d = operandStack.popDouble();
operandStack.pushFloat((float) d);
}
}
public class D2i extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double d = operandStack.popDouble();
operandStack.pushInt((int) d);
}
}
public class D2l extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
double d = operandStack.popDouble();
operandStack.pushLong((long) d);
}
}
public class I2f extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int i = operandStack.popInt();
operandStack.pushFloat((float) i);
}
}
public class I2d extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int i = operandStack.popInt();
operandStack.pushDouble((double) i);
}
}
public class I2l extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
int i = operandStack.popInt();
operandStack.pushLong((long) i);
}
}
public class F2i extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float f = operandStack.popFloat();
operandStack.pushInt((int) f);
}
}
public class F2d extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float f = operandStack.popFloat();
operandStack.pushDouble((double) f);
}
}
public class F2l extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
float f = operandStack.popFloat();
operandStack.pushLong((long) f);
}
}
public class L2i extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long l = operandStack.popLong();
operandStack.pushInt((int) l);
}
}
public class L2d extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long l = operandStack.popLong();
operandStack.pushDouble((double) l);
}
}
public class L2f extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long l = operandStack.popLong();
operandStack.pushFloat((float) l);
}
}
public class Lcmp extends OperandsInstruction {
@Override
public void execute(Frame frame) {
OperandStack operandStack = frame.getOperandStack();
long v2 = operandStack.popLong();
long v1 = operandStack.popLong();
if (v1 > v2) {
operandStack.pushInt(1);
} else if (v1 == v2) {
operandStack.pushInt(0);
} else {
operandStack.pushInt(-1);
}
}
}
public class Fcmp extends OperandsInstruction {
@Override
public void execute(Frame frame) {
}
public void _fcmp(Frame frame, boolean gFlag) {
OperandStack operandStack = frame.getOperandStack();
float v2 = operandStack.popFloat();
float v1 = operandStack.popFloat();
if (v1 > v2) {
operandStack.pushInt(1);
} else if (v1 == v2) {
operandStack.pushInt(0);
} else if (v1 < v2) {
operandStack.pushInt(-1);
} else if (gFlag) {
operandStack.pushInt(1);
} else {
operandStack.pushInt(-1);
}
}
public class Fcmpg extends Fcmp {
@Override
public void execute(Frame frame) {
_fcmp(frame, true);
}
}
public class Fcmpl extends Fcmp {
@Override
public void execute(Frame frame) {
_fcmp(frame, false);
}
}
}
public class Dcmp extends OperandsInstruction {
@Override
public void execute(Frame frame) {
}
public void _dcmp(Frame frame, boolean gFlag) {
OperandStack operandStack = frame.getOperandStack();
double v2 = operandStack.popDouble();
double v1 = operandStack.popDouble();
if (v1 > v2) {
operandStack.pushInt(1);
} else if (v1 == v2) {
operandStack.pushInt(0);
} else if (v1 < v2) {
operandStack.pushInt(-1);
} else if (gFlag) {
operandStack.pushInt(1);
} else {
operandStack.pushInt(-1);
}
}
public class Dcmpg extends Dcmp {
@Override
public void execute(Frame frame) {
_dcmp(frame, true);
}
}
public class Dcmpl extends Dcmp {
@Override
public void execute(Frame frame) {
_dcmp(frame, false);
}
}
}
}

View File

@ -36,8 +36,11 @@ public class Frame {
private Frame lower;
private LocalVars localVars;
private OperandStack operandStack;
private Thread thread;
private int nextPc;
public Frame(int maxLocals, int maxStack) {
public Frame(Thread thread, int maxLocals, int maxStack) {
this.thread = thread;
localVars = new LocalVars(maxLocals);
operandStack = new OperandStack(maxStack);
}
@ -46,6 +49,18 @@ public class Frame {
return localVars;
}
public Thread getThread() {
return thread;
}
public int getNextPc() {
return nextPc;
}
public void setNextPc(int nextPc) {
this.nextPc = nextPc;
}
public OperandStack getOperandStack() {
return operandStack;
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import java.util.Arrays;
/**
*            + +
*         + +
@ -90,4 +92,9 @@ public class LocalVars {
public double getDouble(int index) {
return Double.longBitsToDouble(getLong(index));
}
@Override
public String toString() {
return "slots:" + Arrays.asList(slots).toString();
}
}

View File

@ -8,6 +8,8 @@
package com.gabongao.jvm.rtda;
import java.util.Arrays;
/**
*            + +
*         + +
@ -44,6 +46,14 @@ public class OperandStack {
}
}
@Override
public String toString() {
return "OperandStack{" +
"size=" + size +
", slots=" + Arrays.toString(slots) +
'}';
}
public void pushInt(int val) {
slots[size] = new Slot();
slots[size].setNum(val);
@ -102,4 +112,14 @@ public class OperandStack {
public double popDouble() {
return Double.longBitsToDouble(popLong());
}
public void pushSlot(Slot slot) {
slots[size] = slot;
size++;
}
public Slot popSlot() {
size--;
return slots[size];
}
}

View File

@ -36,6 +36,14 @@ public class Slot {
private int num;
private Object ref;
@Override
public String toString() {
return "Slot{" +
"num=" + num +
", ref=" + ref +
'}';
}
public int getNum() {
return num;
}

View File

@ -59,4 +59,5 @@ public class Thread {
public Frame currentFrame() {
return stack.top();
}
}