Use new BytecodeInfo, got a bit simpler

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@466 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent c96266226d
commit ed8097fb50
  1. 207
      jode/jode/jvm/Interpreter.java

@ -113,14 +113,14 @@ public class Interpreter implements Opcodes {
}
public static Object interpretMethod
(ClassAnalyzer ca, byte[] code, Value[] locals, Value[] stack)
(ClassAnalyzer ca, BytecodeInfo code, Value[] locals, Value[] stack)
throws InterpreterException, ClassFormatException {
try {
ConstantPool cpool = ca.getClazz().getConstantPool();
int pc = 0;
Instruction pc = code.getFirstInstr();
int stacktop = 0;
for(;;) {
// System.err.print(pc+": [");
Instruction instr = pc;
// System.err.print(instr.addr+": [");
// for (int i=0; i<stacktop; i++) {
// if (i>0)
// System.err.print(",");
@ -134,59 +134,29 @@ public class Interpreter implements Opcodes {
// for (int i=0; i<locals.length; i++)
// System.err.print(locals[i]+",");
// System.err.println("]");
int opcode = code[pc++] & 0xff;
pc = instr.nextByAddr;
int opcode = instr.opcode;
switch (opcode) {
case opc_nop:
break;
case opc_aconst_null:
stack[stacktop++].setObject(null);
break;
case opc_iconst_m1:
case opc_iconst_0: case opc_iconst_1: case opc_iconst_2:
case opc_iconst_3: case opc_iconst_4: case opc_iconst_5:
stack[stacktop++].setInt(opcode - opc_iconst_0);
break;
case opc_lconst_0: case opc_lconst_1:
stack[stacktop++].setLong(opcode - opc_lconst_0);
break;
case opc_fconst_0: case opc_fconst_1: case opc_fconst_2:
stack[stacktop++].setFloat(opcode - opc_fconst_0);
break;
case opc_dconst_0: case opc_dconst_1:
stack[stacktop++].setDouble(opcode - opc_dconst_0);
break;
case opc_bipush:
stack[stacktop++].setInt(code[pc++]);
break;
case opc_sipush:
stack[stacktop++].setInt((code[pc++] << 8)
| (code[pc++] & 0xff));
break;
case opc_ldc:
stack[stacktop++].setObject
(cpool.getConstant(code[pc++] & 0xff));
break;
case opc_ldc_w:
case opc_ldc2_w: {
int index = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff;
stack[stacktop++].setObject(cpool.getConstant(index));
stack[stacktop++].setObject(instr.objData);
break;
}
case opc_iload: case opc_lload:
case opc_fload: case opc_dload: case opc_aload:
stack[stacktop++].setValue(locals[code[pc++]]);
break;
case opc_iload_0: case opc_iload_1:
case opc_iload_2: case opc_iload_3:
case opc_lload_0: case opc_lload_1:
case opc_lload_2: case opc_lload_3:
case opc_fload_0: case opc_fload_1:
case opc_fload_2: case opc_fload_3:
case opc_dload_0: case opc_dload_1:
case opc_dload_2: case opc_dload_3:
case opc_aload_0: case opc_aload_1:
case opc_aload_2: case opc_aload_3:
stack[stacktop++].setValue(locals[(opcode - opc_iload_0) & 3]);
stack[stacktop++].setValue(locals[instr.localSlot]);
break;
case opc_iaload: case opc_laload:
case opc_faload: case opc_daload: case opc_aaload:
@ -217,19 +187,7 @@ public class Interpreter implements Opcodes {
}
case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore:
locals[code[pc++]].setValue(stack[--stacktop]);
break;
case opc_istore_0: case opc_istore_1:
case opc_istore_2: case opc_istore_3:
case opc_lstore_0: case opc_lstore_1:
case opc_lstore_2: case opc_lstore_3:
case opc_fstore_0: case opc_fstore_1:
case opc_fstore_2: case opc_fstore_3:
case opc_dstore_0: case opc_dstore_1:
case opc_dstore_2: case opc_dstore_3:
case opc_astore_0: case opc_astore_1:
case opc_astore_2: case opc_astore_3:
locals[(opcode-opc_istore_0) & 3].setValue(stack[--stacktop]);
locals[instr.localSlot].setValue(stack[--stacktop]);
break;
case opc_iastore: case opc_lastore:
case opc_fastore: case opc_dastore: case opc_aastore:
@ -464,11 +422,10 @@ public class Interpreter implements Opcodes {
stacktop--;
break;
case opc_iinc: {
int slot = code[pc++] & 0xff;
locals[slot].setInt(locals[slot].intValue() + code[pc++]);
case opc_iinc:
locals[instr.localSlot].setInt
(locals[instr.localSlot].intValue() + instr.intData);
break;
}
case opc_i2l:
stack[stacktop-1]
.setLong((long)stack[stacktop-1].intValue());
@ -589,68 +546,43 @@ public class Interpreter implements Opcodes {
opcode += opc_ifeq - opc_if_icmpeq;
}
}
int offset = ((code[pc++] << 8) | (code[pc++] & 0xff)) - 3;
if (value > 0 && (opcode == opc_ifgt || opcode == opc_ifge)
|| value < 0 && (opcode == opc_iflt || opcode == opc_ifle)
|| value == 0 && (opcode == opc_ifge || opcode == opc_ifle
|| opcode == opc_ifeq))
pc += offset;
pc = instr.succs[0];
break;
}
case opc_jsr:
stack[stacktop++].setObject(new ReturnAddress(pc));
case opc_jsr_w:
stack[stacktop++].setObject(instr);
/* fall through */
case opc_goto:
pc = (pc-1) + ((code[pc] << 8) | (code[pc+1] & 0xff));
case opc_goto_w:
pc = instr.succs[0];
break;
case opc_ret:
pc = ((ReturnAddress) locals[code[pc] & 0xff].objectValue())
.getPC();
pc = (Instruction)locals[instr.localSlot].objectValue();
break;
case opc_tableswitch: {
int value = stack[--stacktop].intValue();
int start = pc - 1;
pc += 3-(start % 4);
int dest = (code[pc++] << 24 | (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8 | (code[pc++] & 0xff));
int low = (code[pc++] << 24 | (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8 | (code[pc++] & 0xff));
int high = (code[pc++] << 24 | (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8 | (code[pc++] & 0xff));
if (value >= low && value <= high) {
pc += (value - low) << 2;
dest = (code[pc++] << 24 | (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8 | (code[pc++] & 0xff));
}
pc = start + dest;
int low = instr.intData;
if (value >= low && value <= low + instr.succs.length - 2)
pc = instr.succs[value - low];
else
pc = instr.succs[instr.succs.length-1];
break;
}
case opc_lookupswitch: {
int value = stack[--stacktop].intValue();
int start = pc - 1;
pc += 3-(start % 4);
int dest = (code[pc++] << 24
| (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8
| (code[pc++] & 0xff));
int npairs = (code[pc++] << 24
| (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8
| (code[pc++] & 0xff));
for (int i=0; i < npairs; i++) {
if (value == (code[pc++] << 24
| (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8
| (code[pc++] & 0xff))) {
dest = (code[pc++] << 24
| (code[pc++] & 0xff) << 16
| (code[pc++] & 0xff) << 8
| (code[pc++] & 0xff));
break;
}
pc+=2;
}
pc = start + dest;
int[] values = (int[]) instr.objData;
pc = instr.succs[values.length];
for (int i=0; i< values.length; i++) {
if (values[i] == value) {
pc = instr.succs[i];
break;
}
}
break;
}
case opc_ireturn: case opc_lreturn:
@ -668,16 +600,13 @@ public class Interpreter implements Opcodes {
case opc_invokespecial:
case opc_invokestatic :
case opc_invokeinterface: {
String[] ref = cpool.getRef((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff);
int argcount= (opcode == opc_invokeinterface)
? (code[pc++] << 8) | (code[pc++] & 0xff) : -1;
String[] ref = (String[]) instr.objData;
if (ref[0].equals(ca.getClazz().getName().replace('.','/'))) {
boolean isStatic = opcode == opc_invokestatic;
MethodType mt = new MethodType(isStatic, ref[2]);
CodeInfo info = ca.getMethod(ref[1], mt)
.getCode().getCodeInfo();
BytecodeInfo info = ca.getMethod(ref[1], mt)
.getCode().getBytecodeInfo();
Value[] newLocals = new Value[info.getMaxLocals()];
for (int i=0; i< newLocals.length; i++)
newLocals[i] = new Value();
@ -686,11 +615,10 @@ public class Interpreter implements Opcodes {
newStack[i] = new Value();
for (int i=mt.getParameterTypes().length - 1; i >= 0; i--)
newLocals[i].setValue(stack[--stacktop]);
Object result = interpretMethod(ca, info.getCode(),
Object result = interpretMethod(ca, info,
newLocals, newStack);
if (mt.getReturnType() != Type.tVoid) {
if (mt.getReturnType() != Type.tVoid)
stack[stacktop++].setObject(result);
}
} else {
Class clazz;
try {
@ -766,14 +694,13 @@ public class Interpreter implements Opcodes {
break;
}
case opc_new: {
String clazz = cpool.getClassName((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff);
String clazz = (String) instr.objData;
stack[stacktop++].setNewObject(new NewObject(clazz));
break;
}
case opc_newarray: {
int length = stack[--stacktop].intValue();
switch (code[pc++]) {
switch (instr.intData) {
case 4:
stack[stacktop++].setObject(new boolean[length]);
break;
@ -807,10 +734,7 @@ public class Interpreter implements Opcodes {
int length = stack[--stacktop].intValue();
Class clazz;
try {
clazz = Class.forName
(cpool.getClassName((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff)
.replace('/','.'));
clazz = Class.forName((String) instr.objData);
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
@ -829,10 +753,7 @@ public class Interpreter implements Opcodes {
case opc_checkcast: {
Class clazz;
try {
clazz = Class.forName
(cpool.getClassName((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff)
.replace('/','.'));
clazz = Class.forName((String) instr.objData);
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
@ -848,10 +769,7 @@ public class Interpreter implements Opcodes {
case opc_instanceof: {
Class clazz;
try {
clazz = Class.forName
(cpool.getClassName((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff)
.replace('/','.'));
clazz = Class.forName((String) instr.objData);
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
@ -868,60 +786,21 @@ public class Interpreter implements Opcodes {
case opc_monitorexit:
throw new InterpreterException
("MonitorEnter/Exit not implemented");
case opc_wide: {
opcode = code[pc++] & 0xff;
switch (opcode) {
case opc_iload: case opc_lload:
case opc_fload: case opc_dload: case opc_aload: {
int slot = (code[pc++] << 8) | (code[pc++] & 0xff);
stack[stacktop++].setValue(locals[slot & 0xffff]);
break;
}
case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore: {
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff;
locals[slot & 0xffff].setValue(stack[--stacktop]);
break;
}
case opc_iinc: {
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff;
int value = (code[pc++] << 8) | code[pc++] & 0xff;
locals[slot].setInt(locals[slot].intValue()
+ value);
}
case opc_ret: {
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff;
pc = ((ReturnAddress)locals[slot].objectValue()).getPC();
}
default:
throw new
ClassFormatException("Invalid wide opcode "+opcode);
}
}
case opc_multianewarray: {
Class clazz;
try {
clazz = Class.forName
(cpool.getClassName((code[pc++] << 8) & 0xff00
| code[pc++] & 0xff)
.replace('/','.'));
clazz = Class.forName((String) instr.objData);
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
}
int dimension = code[pc++] & 0xff;
int dimension = instr.intData;
int[] dims = new int[dimension];
for (int i=dimension-1; i >= 0; i--)
dims[i-1] = stack[--stacktop].intValue();
stack[stacktop++].setObject(Array.newInstance(clazz, dims));
break;
}
case opc_jsr_w:
stack[stacktop++].setObject(new ReturnAddress(pc));
/* fall through */
case opc_goto_w:
pc = pc-1 + (code[pc] << 24 | ((code[pc+1]&0xff) << 16)
| ((code[pc+2]&0xff) << 8) | code[pc+3]&0xff);
default:
throw new ClassFormatException("Invalid opcode "+opcode);
}

Loading…
Cancel
Save