instructions collectionified

Make more use of TypeSignature, type handling in CodeVerifier changed


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1098 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent c3ead8b084
commit c2ec44a43b
  1. 602
      jode/jode/jvm/CodeVerifier.java.in
  2. 52
      jode/jode/jvm/Interpreter.j
  3. 70
      jode/jode/jvm/Interpreter.java.in
  4. 83
      jode/jode/jvm/SyntheticAnalyzer.java.in

@ -68,7 +68,10 @@ initstack_enter:
ifge initstack_loop
pop2
invokevirtual jode/bytecode/BytecodeInfo/getFirstInstr()Ljode/bytecode/Instruction;
invokevirtual jode/bytecode/BytecodeInfo/getInstructions()Ljava.util.List;
iconst_0
invokevirtual java/util/List/get(I)Ljava/lang/Object;
checkcast jode/bytecode/Instruction;
astore 4
iconst_0
istore 5
@ -675,7 +678,7 @@ iinc_instr:
dup
invokevirtual jode/jvm/Value/intValue()I
aload 6
invokevirtual jode/bytecode/Instruction/getIntData()I
invokevirtual jode/bytecode/Instruction/getIncrement()I
iadd
invokevirtual jode/jvm/Value/setInt(I)V
goto big_loop
@ -1221,7 +1224,7 @@ if_or_special_instr:
goto_instr
jsr_instr
ret_instr
tableswitch_instr
illegal_instr
lookupswitch_instr
areturn_instr
lreturn_instr
@ -1318,9 +1321,7 @@ ificmp_final:
ifge big_loop
jump_succ:
aload 6
invokevirtual jode/bytecode/Instruction/getSuccs()[Ljode/bytecode/Instruction;
iconst_0
aaload
invokevirtual jode/bytecode/Instruction/getSingleSucc()Ljode/bytecode/Instruction;
astore 4
goto big_loop
@ -1347,43 +1348,6 @@ ret_instr:
astore 4
goto big_loop
tableswitch_instr:
pop
iinc 5 -1
aload_3
iload 5
aaload
invokevirtual jode/jvm/Value/intValue()I
aload 6
invokevirtual jode/bytecode/Instruction/getIntData()I
isub
dup
aload 6
invokevirtual jode/bytecode/Instruction/getSuccs()[Ljode/bytecode/Instruction;
dup_x2
; Stack:
; succs
; value - low
; value - low
; succs
arraylength
if_icmpge default_dest
dup
ifge load_dest
default_dest:
; Stack:
; value - low
; succs
pop
dup
arraylength
iconst_1
isub
load_dest:
aaload
astore 4
goto big_loop
lookupswitch_instr:
pop
iinc 5 -1
@ -1821,7 +1785,7 @@ monitorexit_instr:
multianewarray_instr:
pop
aload 6
invokevirtual jode/bytecode/Instruction/getIntData()I
invokevirtual jode/bytecode/Instruction/getDimensions()I
dup
istore 7
newarray int

@ -63,7 +63,7 @@ public class Interpreter implements Opcodes {
for (int i=0; i< stack.length; i++)
stack[i] = new Value();
Instruction pc = code.getFirstInstr();
Instruction pc = (Instruction) code.getInstructions().get(0);
int stacktop = 0;
big_loop:
for(;;) {
@ -410,7 +410,7 @@ public class Interpreter implements Opcodes {
case opc_iinc:
locals[instr.getLocalSlot()].setInt
(locals[instr.getLocalSlot()].intValue() + instr.getIntData());
(locals[instr.getLocalSlot()].intValue() + instr.getIncrement());
break;
case opc_i2l:
stack[stacktop-1]
@ -546,7 +546,7 @@ public class Interpreter implements Opcodes {
if (value > 0 && (opc_mask & CMP_GREATER_MASK) != 0
|| value < 0 && (opc_mask & CMP_LESS_MASK) != 0
|| value == 0 && (opc_mask & CMP_EQUAL_MASK) != 0)
pc = instr.getSuccs()[0];
pc = instr.getSingleSucc();
break;
}
case opc_jsr:
@ -555,20 +555,11 @@ public class Interpreter implements Opcodes {
/* fall through */
case opc_goto:
case opc_goto_w:
pc = instr.getSuccs()[0];
pc = instr.getSingleSucc();
break;
case opc_ret:
pc = (Instruction)locals[instr.getLocalSlot()].objectValue();
break;
case opc_tableswitch: {
int value = stack[--stacktop].intValue();
int low = instr.getIntData();
if (value >= low && value <= low + instr.getSuccs().length - 2)
pc = instr.getSuccs()[value - low];
else
pc = instr.getSuccs()[instr.getSuccs().length-1];
break;
}
case opc_lookupswitch: {
int value = stack[--stacktop].intValue();
int[] values = instr.getValues();
@ -663,53 +654,6 @@ public class Interpreter implements Opcodes {
stack[stacktop++].setNewObject(new NewObject(clazz));
break;
}
case opc_newarray: {
int length = stack[--stacktop].intValue();
try {
switch (instr.getIntData()) {
case 4:
stack[stacktop++].setObject(new boolean[length]);
break;
case 5:
stack[stacktop++].setObject(new char[length]);
break;
case 6:
stack[stacktop++].setObject(new float[length]);
break;
case 7:
stack[stacktop++].setObject(new double[length]);
break;
case 8:
stack[stacktop++].setObject(new byte[length]);
break;
case 9:
stack[stacktop++].setObject(new short[length]);
break;
case 10:
stack[stacktop++].setObject(new int[length]);
break;
case 11:
stack[stacktop++].setObject(new long[length]);
break;
default:
throw new AssertError("Invalid newarray operand");
}
} catch (NegativeArraySizeException ex) {
throw new InvocationTargetException(ex);
}
break;
}
case opc_anewarray: {
int length = stack[--stacktop].intValue();
try {
stack[stacktop++].setObject
(env.newArray(instr.getClazzType(),
new int[] { length }));
} catch (NegativeArraySizeException ex) {
throw new InvocationTargetException(ex);
}
break;
}
case opc_arraylength: {
Object array = stack[--stacktop].objectValue();
stack[stacktop++].setInt(Array.getLength(array));
@ -742,7 +686,7 @@ public class Interpreter implements Opcodes {
env.exitMonitor(stack[--stacktop].objectValue());
break;
case opc_multianewarray: {
int dimension = instr.getIntData();
int dimension = instr.getDimensions();
int[] dims = new int[dimension];
for (int i=dimension - 1; i >= 0; i--)
dims[i] = stack[--stacktop].intValue();
@ -761,8 +705,8 @@ public class Interpreter implements Opcodes {
Handler[] handlers = code.getExceptionHandlers();
Throwable obj = ex.getTargetException();
for (int i=0; i< handlers.length; i++) {
if (handlers[i].start.getAddr() <= pc.getAddr()
&& handlers[i].end.getAddr() >= pc.getAddr()
if (handlers[i].start.compareTo(pc) <= 0
&& handlers[i].end.compareTo(pc) >= 0
&& (handlers[i].type == null
|| env.instanceOf(obj, handlers[i].type))) {
stacktop = 0;

@ -19,12 +19,22 @@
package jode.jvm;
import jode.GlobalOptions;
import jode.bytecode.BytecodeInfo;
import jode.bytecode.ClassInfo;
import jode.bytecode.FieldInfo;
import jode.bytecode.Handler;
import jode.bytecode.Instruction;
import jode.bytecode.MethodInfo;
import jode.bytecode.Opcodes;
import jode.bytecode.Reference;
import jode.type.Type;
import jode.type.MethodType;
import java.lang.reflect.Modifier;
import jode.bytecode.*;
public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
import @COLLECTIONS@.Iterator;
public class SyntheticAnalyzer implements Opcodes {
public final static int UNKNOWN = 0;
public final static int GETCLASS = 1;
public final static int ACCESSGETFIELD = 2;
@ -83,37 +93,36 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
BytecodeInfo bytecode = method.getBytecode();
Handler[] excHandlers = bytecode.getExceptionHandlers();
if (excHandlers.length != 1)
if (excHandlers.length != 1
|| !"java.lang.ClassNotFoundException".equals(excHandlers[0].type))
return false;
int excSlot = -1;
Instruction instr = bytecode.getFirstInstr();
if (excHandlers[0].start != instr
|| !"java.lang.ClassNotFoundException".equals(excHandlers[0].type))
return false;
for (int i=0; i< getClassOpcodes.length; i++) {
if (instr.getOpcode() != getClassOpcodes[i])
return false;
if (i==0 && instr.getLocalSlot() != 0)
int i = 0;
for (Iterator iter = bytecode.getInstructions().iterator(); iter.hasNext(); i++) {
Instruction instr = (Instruction) iter.next();
if (i == getClassOpcodes.length
|| instr.getOpcode() != getClassOpcodes[i])
return false;
if (i == 3)
excSlot = instr.getLocalSlot();
if (i == 6 && instr.getLocalSlot() != excSlot)
if (i == 0 && (instr.getLocalSlot() != 0
|| excHandlers[0].start != instr))
return false;
if (i == 2 && excHandlers[0].end != instr)
return false;
if (i == 3 && excHandlers[0].catcher != instr)
return false;
if (i == 3) {
if (excHandlers[0].catcher != instr)
return false;
excSlot = instr.getLocalSlot();
}
if (i == 4 && !instr.getClazzType().equals
("Ljava/lang/NoClassDefFoundError;"))
return false;
if (i == 6 && instr.getLocalSlot() != excSlot)
return false;
if (getClassRefs[i] != null
&& !getClassRefs[i].equals(instr.getReference()))
return false;
instr = instr.getNextByAddr();
}
if (instr != null)
return false;
this.kind = GETCLASS;
return true;
}
@ -124,8 +133,9 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
public boolean checkStaticAccess() {
ClassInfo clazzInfo = method.getClazzInfo();
BytecodeInfo bytecode = method.getBytecode();
Instruction instr = bytecode.getFirstInstr();
Iterator iter = bytecode.getInstructions().iterator();
Instruction instr = (Instruction) iter.next();
if (instr.getOpcode() == opc_getstatic) {
Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1);
@ -137,11 +147,11 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refField.getModifiers() & modifierMask) !=
(Modifier.PRIVATE | Modifier.STATIC))
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false;
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
/* For valid bytecode the type matches automatically */
reference = ref;
@ -155,7 +165,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
params++;
slot += (instr.getOpcode() == opc_lload
|| instr.getOpcode() == opc_dload) ? 2 : 1;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
}
if (instr.getOpcode() == opc_putstatic) {
if (params != 1)
@ -171,10 +181,10 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refField.getModifiers() & modifierMask) !=
(Modifier.PRIVATE | Modifier.STATIC))
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (instr.getOpcode() != opc_return)
return false;
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
reference = ref;
kind = ACCESSPUTSTATIC;
@ -193,7 +203,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
(Modifier.PRIVATE | Modifier.STATIC)
|| refType.getParameterTypes().length != params)
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (refType.getReturnType() == Type.tVoid) {
if (instr.getOpcode() != opc_return)
return false;
@ -202,7 +212,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
|| instr.getOpcode() > opc_areturn)
return false;
}
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
/* For valid bytecode the types matches automatically */
@ -225,10 +235,11 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
return true;
}
Instruction instr = bytecode.getFirstInstr();
Iterator iter = bytecode.getInstructions().iterator();
Instruction instr = (Instruction) iter.next();
if (instr.getOpcode() != opc_aload || instr.getLocalSlot() != 0)
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (instr.getOpcode() == opc_getfield) {
Reference ref = instr.getReference();
@ -240,11 +251,11 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
= clazzInfo.findField(ref.getName(), ref.getType());
if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE)
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false;
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
/* For valid bytecode the type matches automatically */
reference = ref;
@ -258,7 +269,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
params++;
slot += (instr.getOpcode() == opc_lload
|| instr.getOpcode() == opc_dload) ? 2 : 1;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
}
if (instr.getOpcode() == opc_putfield) {
if (params != 1)
@ -273,10 +284,10 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
= clazzInfo.findField(ref.getName(), ref.getType());
if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE)
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (instr.getOpcode() != opc_return)
return false;
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
reference = ref;
kind = ACCESSPUTFIELD;
@ -294,7 +305,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refMethod.getModifiers() & modifierMask) != Modifier.PRIVATE
|| refType.getParameterTypes().length != params)
return false;
instr = instr.getNextByAddr();
instr = (Instruction) iter.next();
if (refType.getReturnType() == Type.tVoid) {
if (instr.getOpcode() != opc_return)
return false;
@ -303,7 +314,7 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
|| instr.getOpcode() > opc_areturn)
return false;
}
if (instr.getNextByAddr() != null)
if (iter.hasNext())
return false;
/* For valid bytecode the types matches automatically */
Loading…
Cancel
Save