use member functions to access Instruction fields

cleaned up imports


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1067 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent 4280f1d6ce
commit f301603e87
  1. 222
      jode/jode/jvm/CodeVerifier.java
  2. 89
      jode/jode/jvm/Interpreter.java
  3. 1
      jode/jode/jvm/InterpreterException.java
  4. 1
      jode/jode/jvm/NewObject.java
  5. 11
      jode/jode/jvm/SimpleRuntimeEnvironment.java
  6. 116
      jode/jode/jvm/SyntheticAnalyzer.java

@ -18,10 +18,20 @@
*/ */
package jode.jvm; package jode.jvm;
import jode.bytecode.*;
import jode.type.*;
import jode.AssertError; import jode.AssertError;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.bytecode.BytecodeInfo;
import jode.bytecode.ClassInfo;
import jode.bytecode.Handler;
import jode.bytecode.Instruction;
import jode.bytecode.MethodInfo;
import jode.bytecode.Opcodes;
import jode.bytecode.Reference;
import jode.type.ArrayType;
import jode.type.ClassInterfacesType;
import jode.type.MethodType;
import jode.type.Type;
import java.util.BitSet; import java.util.BitSet;
import java.util.Stack; import java.util.Stack;
@ -297,12 +307,12 @@ public class CodeVerifier implements Opcodes {
public boolean mergeInfo(Instruction instr, VerifyInfo info) public boolean mergeInfo(Instruction instr, VerifyInfo info)
throws VerifyException { throws VerifyException {
if (instr.tmpInfo == null) { if (instr.getTmpInfo() == null) {
instr.tmpInfo = info; instr.setTmpInfo(info);
return true; return true;
} }
boolean changed = false; boolean changed = false;
VerifyInfo oldInfo = (VerifyInfo) instr.tmpInfo; VerifyInfo oldInfo = (VerifyInfo) instr.getTmpInfo();
if (oldInfo.stackHeight != info.stackHeight) if (oldInfo.stackHeight != info.stackHeight)
throw new VerifyException("Stack height differ at: " throw new VerifyException("Stack height differ at: "
+ instr.getDescription()); + instr.getDescription());
@ -371,17 +381,18 @@ public class CodeVerifier implements Opcodes {
int jsrLength = int jsrLength =
prevInfo.jsrTargets != null ? prevInfo.jsrTargets.length : 0; prevInfo.jsrTargets != null ? prevInfo.jsrTargets.length : 0;
VerifyInfo result = (VerifyInfo) prevInfo.clone(); VerifyInfo result = (VerifyInfo) prevInfo.clone();
switch (instr.opcode) { switch (instr.getOpcode()) {
case opc_nop: case opc_nop:
case opc_goto: case opc_goto:
break; break;
case opc_ldc: { case opc_ldc: {
Type type; Type type;
if (instr.objData == null) Object constant = instr.getConstant();
if (constant == null)
type = Type.tUObject; type = Type.tUObject;
else if (instr.objData instanceof Integer) else if (constant instanceof Integer)
type = Type.tInt; type = Type.tInt;
else if (instr.objData instanceof Float) else if (constant instanceof Float)
type = Type.tFloat; type = Type.tFloat;
else else
type = Type.tString; type = Type.tString;
@ -390,7 +401,8 @@ public class CodeVerifier implements Opcodes {
} }
case opc_ldc2_w: { case opc_ldc2_w: {
Type type; Type type;
if (instr.objData instanceof Long) Object constant = instr.getConstant();
if (constant instanceof Long)
type = Type.tLong; type = Type.tLong;
else else
type = Type.tDouble; type = Type.tDouble;
@ -404,25 +416,25 @@ public class CodeVerifier implements Opcodes {
case opc_dload: case opc_dload:
case opc_aload: { case opc_aload: {
if (jsrLength > 0 if (jsrLength > 0
&& (!result.jsrLocals[jsrLength-1].get(instr.localSlot) && (!result.jsrLocals[jsrLength-1].get(instr.getLocalSlot())
|| ((instr.opcode & 0x1) == 0 || ((instr.getOpcode() & 0x1) == 0
&& !result.jsrLocals[jsrLength-1] && !result.jsrLocals[jsrLength-1]
.get(instr.localSlot+1)))) { .get(instr.getLocalSlot()+1)))) {
result.jsrLocals = (BitSet[]) result.jsrLocals.clone(); result.jsrLocals = (BitSet[]) result.jsrLocals.clone();
result.jsrLocals[jsrLength-1] result.jsrLocals[jsrLength-1]
= (BitSet) result.jsrLocals[jsrLength-1].clone(); = (BitSet) result.jsrLocals[jsrLength-1].clone();
result.jsrLocals[jsrLength-1].set(instr.localSlot); result.jsrLocals[jsrLength-1].set(instr.getLocalSlot());
if ((instr.opcode & 0x1) == 0) if ((instr.getOpcode() & 0x1) == 0)
result.jsrLocals[jsrLength-1].set(instr.localSlot + 1); result.jsrLocals[jsrLength-1].set(instr.getLocalSlot() + 1);
} }
if ((instr.opcode & 0x1) == 0 if ((instr.getOpcode() & 0x1) == 0
&& result.locals[instr.localSlot+1] != Type.tVoid) && result.locals[instr.getLocalSlot()+1] != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type type = result.locals[instr.localSlot]; Type type = result.locals[instr.getLocalSlot()];
if (!isOfType(type, types[instr.opcode - opc_iload])) if (!isOfType(type, types[instr.getOpcode() - opc_iload]))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
result.push(type); result.push(type);
if ((instr.opcode & 0x1) == 0) if ((instr.getOpcode() & 0x1) == 0)
result.push(Type.tVoid); result.push(Type.tVoid);
break; break;
} }
@ -433,50 +445,50 @@ public class CodeVerifier implements Opcodes {
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type arrType = result.pop(); Type arrType = result.pop();
if (!isOfType(arrType, if (!isOfType(arrType,
Type.tArray(types[instr.opcode - opc_iaload])) Type.tArray(types[instr.getOpcode() - opc_iaload]))
&& (instr.opcode != opc_baload && (instr.getOpcode() != opc_baload
|| !isOfType(arrType, Type.tArray(Type.tBoolean)))) || !isOfType(arrType, Type.tArray(Type.tBoolean))))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type elemType = (arrType.equals(Type.tUObject) Type elemType = (arrType.equals(Type.tUObject)
? types[instr.opcode - opc_iaload] ? types[instr.getOpcode() - opc_iaload]
:((ArrayType)arrType).getElementType()); :((ArrayType)arrType).getElementType());
result.push(elemType); result.push(elemType);
if (((1 << instr.opcode - opc_iaload) & 0xa) != 0) if (((1 << instr.getOpcode() - opc_iaload) & 0xa) != 0)
result.push(Type.tVoid); result.push(Type.tVoid);
break; break;
} }
case opc_istore: case opc_lstore: case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore: { case opc_fstore: case opc_dstore: case opc_astore: {
if (jsrLength > 0 if (jsrLength > 0
&& (!result.jsrLocals[jsrLength-1].get(instr.localSlot) && (!result.jsrLocals[jsrLength-1].get(instr.getLocalSlot())
|| ((instr.opcode & 0x1) != 0 || ((instr.getOpcode() & 0x1) != 0
&& !result.jsrLocals[jsrLength-1] && !result.jsrLocals[jsrLength-1]
.get(instr.localSlot+1)))) { .get(instr.getLocalSlot()+1)))) {
result.jsrLocals = (BitSet[]) result.jsrLocals.clone(); result.jsrLocals = (BitSet[]) result.jsrLocals.clone();
result.jsrLocals[jsrLength-1] result.jsrLocals[jsrLength-1]
= (BitSet) result.jsrLocals[jsrLength-1].clone(); = (BitSet) result.jsrLocals[jsrLength-1].clone();
result.jsrLocals[jsrLength-1].set(instr.localSlot); result.jsrLocals[jsrLength-1].set(instr.getLocalSlot());
if ((instr.opcode & 0x1) != 0) if ((instr.getOpcode() & 0x1) != 0)
result.jsrLocals[jsrLength-1].set(instr.localSlot + 1); result.jsrLocals[jsrLength-1].set(instr.getLocalSlot() + 1);
} }
if ((instr.opcode & 0x1) != 0 if ((instr.getOpcode() & 0x1) != 0
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type type = result.pop(); Type type = result.pop();
if (instr.opcode != opc_astore if (instr.getOpcode() != opc_astore
|| !(type instanceof ReturnAddressType)) || !(type instanceof ReturnAddressType))
if (!isOfType(type, types[instr.opcode - opc_istore])) if (!isOfType(type, types[instr.getOpcode() - opc_istore]))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
result.locals[instr.localSlot] = type; result.locals[instr.getLocalSlot()] = type;
if ((instr.opcode & 0x1) != 0) if ((instr.getOpcode() & 0x1) != 0)
result.locals[instr.localSlot+1] = Type.tVoid; result.locals[instr.getLocalSlot()+1] = Type.tVoid;
break; break;
} }
case opc_iastore: case opc_lastore: case opc_iastore: case opc_lastore:
case opc_fastore: case opc_dastore: case opc_aastore: case opc_fastore: case opc_dastore: case opc_aastore:
case opc_bastore: case opc_castore: case opc_sastore: { case opc_bastore: case opc_castore: case opc_sastore: {
if (((1 << instr.opcode - opc_iastore) & 0xa) != 0 if (((1 << instr.getOpcode() - opc_iastore) & 0xa) != 0
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type type = result.pop(); Type type = result.pop();
@ -484,24 +496,24 @@ public class CodeVerifier implements Opcodes {
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type arrType = result.pop(); Type arrType = result.pop();
if (!isOfType(arrType, if (!isOfType(arrType,
Type.tArray(types[instr.opcode - opc_iastore])) Type.tArray(types[instr.getOpcode() - opc_iastore]))
&& (instr.opcode != opc_bastore && (instr.getOpcode() != opc_bastore
|| !isOfType(arrType, Type.tArray(Type.tBoolean)))) || !isOfType(arrType, Type.tArray(Type.tBoolean))))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type elemType = instr.opcode >= opc_bastore ? Type.tInt Type elemType = instr.getOpcode() >= opc_bastore ? Type.tInt
: types[instr.opcode - opc_iastore]; : types[instr.getOpcode() - opc_iastore];
if (!isOfType(type, elemType)) if (!isOfType(type, elemType))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
break; break;
} }
case opc_pop: case opc_pop2: { case opc_pop: case opc_pop2: {
int count = instr.opcode - (opc_pop-1); int count = instr.getOpcode() - (opc_pop-1);
result.need(count); result.need(count);
result.stackHeight -= count; result.stackHeight -= count;
break; break;
} }
case opc_dup: case opc_dup_x1: case opc_dup_x2: { case opc_dup: case opc_dup_x1: case opc_dup_x2: {
int depth = instr.opcode - opc_dup; int depth = instr.getOpcode() - opc_dup;
result.reserve(1); result.reserve(1);
result.need(depth+1); result.need(depth+1);
if (result.stack[result.stackHeight-1] == Type.tVoid) if (result.stack[result.stackHeight-1] == Type.tVoid)
@ -517,7 +529,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_dup2: case opc_dup2_x1: case opc_dup2_x2: { case opc_dup2: case opc_dup2_x1: case opc_dup2_x2: {
int depth = instr.opcode - opc_dup2; int depth = instr.getOpcode() - opc_dup2;
result.reserve(2); result.reserve(2);
result.need(depth+2); result.need(depth+2);
if (result.stack[result.stackHeight-2] == Type.tVoid) if (result.stack[result.stackHeight-2] == Type.tVoid)
@ -552,13 +564,13 @@ public class CodeVerifier implements Opcodes {
case opc_imul: case opc_lmul: case opc_fmul: case opc_dmul: case opc_imul: case opc_lmul: case opc_fmul: case opc_dmul:
case opc_idiv: case opc_ldiv: case opc_fdiv: case opc_ddiv: case opc_idiv: case opc_ldiv: case opc_fdiv: case opc_ddiv:
case opc_irem: case opc_lrem: case opc_frem: case opc_drem: { case opc_irem: case opc_lrem: case opc_frem: case opc_drem: {
Type type = types[(instr.opcode - opc_iadd) & 3]; Type type = types[(instr.getOpcode() - opc_iadd) & 3];
if ((instr.opcode & 1) != 0 if ((instr.getOpcode() & 1) != 0
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
if (!isOfType(result.pop(), type)) if (!isOfType(result.pop(), type))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
if ((instr.opcode & 1) != 0) { if ((instr.getOpcode() & 1) != 0) {
result.need(2); result.need(2);
if (result.stack[result.stackHeight-1] != Type.tVoid if (result.stack[result.stackHeight-1] != Type.tVoid
|| !isOfType(result.stack[result.stackHeight-2], type)) || !isOfType(result.stack[result.stackHeight-2], type))
@ -571,8 +583,8 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg: { case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg: {
Type type = types[(instr.opcode - opc_ineg) & 3]; Type type = types[(instr.getOpcode() - opc_ineg) & 3];
if ((instr.opcode & 1) != 0) { if ((instr.getOpcode() & 1) != 0) {
result.need(2); result.need(2);
if (result.stack[result.stackHeight-1] != Type.tVoid if (result.stack[result.stackHeight-1] != Type.tVoid
|| !isOfType(result.stack[result.stackHeight-2], type)) || !isOfType(result.stack[result.stackHeight-2], type))
@ -590,7 +602,7 @@ public class CodeVerifier implements Opcodes {
if (!isOfType(result.pop(), Type.tInt)) if (!isOfType(result.pop(), Type.tInt))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
if ((instr.opcode & 1) != 0) { if ((instr.getOpcode() & 1) != 0) {
result.need(2); result.need(2);
if (result.stack[result.stackHeight-1] != Type.tVoid || if (result.stack[result.stackHeight-1] != Type.tVoid ||
!isOfType(result.stack[result.stackHeight-2],Type.tLong)) !isOfType(result.stack[result.stackHeight-2],Type.tLong))
@ -605,13 +617,13 @@ public class CodeVerifier implements Opcodes {
case opc_iand: case opc_land: case opc_iand: case opc_land:
case opc_ior : case opc_lor : case opc_ior : case opc_lor :
case opc_ixor: case opc_lxor: case opc_ixor: case opc_lxor:
if ((instr.opcode & 1) != 0 if ((instr.getOpcode() & 1) != 0
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
if (!isOfType(result.pop(), if (!isOfType(result.pop(),
types[instr.opcode & 1])) types[instr.getOpcode() & 1]))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
if ((instr.opcode & 1) != 0) { if ((instr.getOpcode() & 1) != 0) {
result.need(2); result.need(2);
if (result.stack[result.stackHeight-1] != Type.tVoid if (result.stack[result.stackHeight-1] != Type.tVoid
|| !isOfType(result.stack[result.stackHeight-2], || !isOfType(result.stack[result.stackHeight-2],
@ -626,15 +638,15 @@ public class CodeVerifier implements Opcodes {
break; break;
case opc_iinc: case opc_iinc:
if (!isOfType(result.locals[instr.localSlot], Type.tInt)) if (!isOfType(result.locals[instr.getLocalSlot()], Type.tInt))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
break; break;
case opc_i2l: case opc_i2f: case opc_i2d: case opc_i2l: case opc_i2f: case opc_i2d:
case opc_l2i: case opc_l2f: case opc_l2d: case opc_l2i: case opc_l2f: case opc_l2d:
case opc_f2i: case opc_f2l: case opc_f2d: case opc_f2i: case opc_f2l: case opc_f2d:
case opc_d2i: case opc_d2l: case opc_d2f: { case opc_d2i: case opc_d2l: case opc_d2f: {
int from = (instr.opcode-opc_i2l)/3; int from = (instr.getOpcode()-opc_i2l)/3;
int to = (instr.opcode-opc_i2l)%3; int to = (instr.getOpcode()-opc_i2l)%3;
if (to >= from) if (to >= from)
to++; to++;
if ((from & 1) != 0 if ((from & 1) != 0
@ -714,23 +726,23 @@ public class CodeVerifier implements Opcodes {
case opc_ireturn: case opc_lreturn: case opc_ireturn: case opc_lreturn:
case opc_freturn: case opc_dreturn: case opc_areturn: { case opc_freturn: case opc_dreturn: case opc_areturn: {
if (((1 << instr.opcode - opc_ireturn) & 0xa) != 0 if (((1 << instr.getOpcode() - opc_ireturn) & 0xa) != 0
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type type = result.pop(); Type type = result.pop();
if (!isOfType(type, types[instr.opcode - opc_ireturn]) if (!isOfType(type, types[instr.getOpcode() - opc_ireturn])
|| !isOfType(type, mt.getReturnType())) || !isOfType(type, mt.getReturnType()))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
break; break;
} }
case opc_jsr: { case opc_jsr: {
result.stack[result.stackHeight++] result.stack[result.stackHeight++]
= new ReturnAddressType(instr.succs[0]); = new ReturnAddressType(instr.getSuccs()[0]);
result.jsrTargets = new Instruction[jsrLength+1]; result.jsrTargets = new Instruction[jsrLength+1];
result.jsrLocals = new BitSet[jsrLength+1]; result.jsrLocals = new BitSet[jsrLength+1];
if (jsrLength > 0) { if (jsrLength > 0) {
for (int i=0; i< prevInfo.jsrTargets.length; i++) for (int i=0; i< prevInfo.jsrTargets.length; i++)
if (prevInfo.jsrTargets[i] == instr.succs[0]) if (prevInfo.jsrTargets[i] == instr.getSuccs()[0])
throw new VerifyException(instr.getDescription()+ throw new VerifyException(instr.getDescription()+
" is recursive"); " is recursive");
System.arraycopy(prevInfo.jsrTargets, 0, System.arraycopy(prevInfo.jsrTargets, 0,
@ -738,7 +750,7 @@ public class CodeVerifier implements Opcodes {
System.arraycopy(prevInfo.jsrLocals, 0, System.arraycopy(prevInfo.jsrLocals, 0,
result.jsrLocals, 0, jsrLength); result.jsrLocals, 0, jsrLength);
} }
result.jsrTargets[jsrLength] = instr.succs[0]; result.jsrTargets[jsrLength] = instr.getSuccs()[0];
result.jsrLocals[jsrLength] = new BitSet(); result.jsrLocals[jsrLength] = new BitSet();
break; break;
} }
@ -748,7 +760,7 @@ public class CodeVerifier implements Opcodes {
break; break;
case opc_getstatic: { case opc_getstatic: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
Type type = Type.tType(ref.getType()); Type type = Type.tType(ref.getType());
result.push(type); result.push(type);
if (type.stackSize() == 2) if (type.stackSize() == 2)
@ -756,7 +768,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_getfield: { case opc_getfield: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
Type classType = Type.tType(ref.getClazz()); Type classType = Type.tType(ref.getClazz());
if (!isOfType(result.pop(), classType)) if (!isOfType(result.pop(), classType))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
@ -767,7 +779,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_putstatic: { case opc_putstatic: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
Type type = Type.tType(ref.getType()); Type type = Type.tType(ref.getType());
if (type.stackSize() == 2 if (type.stackSize() == 2
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
@ -777,7 +789,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_putfield: { case opc_putfield: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
Type type = Type.tType(ref.getType()); Type type = Type.tType(ref.getType());
if (type.stackSize() == 2 if (type.stackSize() == 2
&& result.pop() != Type.tVoid) && result.pop() != Type.tVoid)
@ -793,7 +805,7 @@ public class CodeVerifier implements Opcodes {
case opc_invokespecial: case opc_invokespecial:
case opc_invokestatic : case opc_invokestatic :
case opc_invokeinterface: { case opc_invokeinterface: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
MethodType refmt = (MethodType) Type.tType(ref.getType()); MethodType refmt = (MethodType) Type.tType(ref.getType());
Type[] paramTypes = refmt.getParameterTypes(); Type[] paramTypes = refmt.getParameterTypes();
for (int i=paramTypes.length - 1; i >= 0; i--) { for (int i=paramTypes.length - 1; i >= 0; i--) {
@ -825,7 +837,7 @@ public class CodeVerifier implements Opcodes {
for (int i=0; i< result.locals.length; i++) for (int i=0; i< result.locals.length; i++)
if (result.locals[i] == clazz) if (result.locals[i] == clazz)
result.locals[i] = newType; result.locals[i] = newType;
} else if (instr.opcode != opc_invokestatic) { } else if (instr.getOpcode() != opc_invokestatic) {
Type classType = Type.tType(ref.getClazz()); Type classType = Type.tType(ref.getClazz());
if (!isOfType(result.pop(), classType)) if (!isOfType(result.pop(), classType))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
@ -839,7 +851,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_new: { case opc_new: {
String clName = (String) instr.objData; String clName = instr.getClazzType();
ClassInfo ci = ClassInfo.forName ClassInfo ci = ClassInfo.forName
(clName.substring(1, clName.length()-1).replace('/','.')); (clName.substring(1, clName.length()-1).replace('/','.'));
result.stack[result.stackHeight++] = result.stack[result.stackHeight++] =
@ -859,7 +871,7 @@ public class CodeVerifier implements Opcodes {
break; break;
} }
case opc_checkcast: { case opc_checkcast: {
Type classType = Type.tType((String) instr.objData); Type classType = Type.tType(instr.getClazzType());
if (!isOfType(result.pop(), Type.tUObject)) if (!isOfType(result.pop(), Type.tUObject))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
result.push(classType); result.push(classType);
@ -877,16 +889,16 @@ public class CodeVerifier implements Opcodes {
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
break; break;
case opc_multianewarray: { case opc_multianewarray: {
int dimension = instr.intData; int dimension = instr.getIntData();
for (int i=dimension - 1; i >= 0; i--) for (int i=dimension - 1; i >= 0; i--)
if (!isOfType(result.pop(), Type.tInt)) if (!isOfType(result.pop(), Type.tInt))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
Type classType = Type.tType((String) instr.objData); Type classType = Type.tType(instr.getClazzType());
result.push(classType); result.push(classType);
break; break;
} }
default: default:
throw new AssertError("Invalid opcode "+instr.opcode); throw new AssertError("Invalid opcode "+instr.getOpcode());
} }
return result; return result;
} }
@ -894,28 +906,28 @@ public class CodeVerifier implements Opcodes {
public void doVerify() throws VerifyException { public void doVerify() throws VerifyException {
Stack instrStack = new Stack(); Stack instrStack = new Stack();
bi.getFirstInstr().tmpInfo = initInfo(); bi.getFirstInstr().setTmpInfo(initInfo());
instrStack.push(bi.getFirstInstr()); instrStack.push(bi.getFirstInstr());
Handler[] handlers = bi.getExceptionHandlers(); Handler[] handlers = bi.getExceptionHandlers();
while (!instrStack.isEmpty()) { while (!instrStack.isEmpty()) {
Instruction instr = (Instruction) instrStack.pop(); Instruction instr = (Instruction) instrStack.pop();
if (!instr.alwaysJumps && instr.nextByAddr == null) if (!instr.doesAlwaysJump() && instr.getNextByAddr() == null)
throw new VerifyException("Flow can fall off end of method"); throw new VerifyException("Flow can fall off end of method");
VerifyInfo prevInfo = (VerifyInfo) instr.tmpInfo; VerifyInfo prevInfo = (VerifyInfo) instr.getTmpInfo();
if (instr.opcode == opc_ret) { if (instr.getOpcode() == opc_ret) {
if (prevInfo.jsrTargets == null if (prevInfo.jsrTargets == null
|| !(prevInfo.locals[instr.localSlot] || !(prevInfo.locals[instr.getLocalSlot()]
instanceof ReturnAddressType)) instanceof ReturnAddressType))
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
int jsrLength = prevInfo.jsrTargets.length - 1; int jsrLength = prevInfo.jsrTargets.length - 1;
Instruction jsrTarget = Instruction jsrTarget =
((ReturnAddressType) ((ReturnAddressType)
prevInfo.locals[instr.localSlot]).jsrTarget; prevInfo.locals[instr.getLocalSlot()]).jsrTarget;
while (jsrTarget != prevInfo.jsrTargets[jsrLength]) while (jsrTarget != prevInfo.jsrTargets[jsrLength])
if (--jsrLength < 0) if (--jsrLength < 0)
throw new VerifyException(instr.getDescription()); throw new VerifyException(instr.getDescription());
VerifyInfo jsrTargetInfo = (VerifyInfo) jsrTarget.tmpInfo; VerifyInfo jsrTargetInfo = (VerifyInfo) jsrTarget.getTmpInfo();
if (jsrTargetInfo.retInstr == null) if (jsrTargetInfo.retInstr == null)
jsrTargetInfo.retInstr = instr; jsrTargetInfo.retInstr = instr;
else if (jsrTargetInfo.retInstr != instr) else if (jsrTargetInfo.retInstr != instr)
@ -935,37 +947,37 @@ public class CodeVerifier implements Opcodes {
nextTargets = null; nextTargets = null;
nextLocals = null; nextLocals = null;
} }
for (int i=0; i < jsrTarget.preds.length; i++) { for (int i=0; i < jsrTarget.getPreds().length; i++) {
Instruction jsrInstr = jsrTarget.preds[i]; Instruction jsrInstr = jsrTarget.getPreds()[i];
if (jsrInstr.tmpInfo != null) if (jsrInstr.getTmpInfo() != null)
instrStack.push(jsrInstr); instrStack.push(jsrInstr);
} }
} else { } else {
VerifyInfo info = modelEffect(instr, prevInfo); VerifyInfo info = modelEffect(instr, prevInfo);
if (!instr.alwaysJumps) if (!instr.doesAlwaysJump())
if (mergeInfo(instr.nextByAddr, info)) if (mergeInfo(instr.getNextByAddr(), info))
instrStack.push(instr.nextByAddr); instrStack.push(instr.getNextByAddr());
if (instr.opcode == opc_jsr) { if (instr.getOpcode() == opc_jsr) {
VerifyInfo targetInfo = VerifyInfo targetInfo =
(VerifyInfo) instr.succs[0].tmpInfo; (VerifyInfo) instr.getSuccs()[0].getTmpInfo();
if (targetInfo != null && targetInfo.retInstr != null) { if (targetInfo != null && targetInfo.retInstr != null) {
VerifyInfo afterJsrInfo VerifyInfo afterJsrInfo
= (VerifyInfo) prevInfo.clone(); = (VerifyInfo) prevInfo.clone();
VerifyInfo retInfo VerifyInfo retInfo
= (VerifyInfo) targetInfo.retInstr.tmpInfo; = (VerifyInfo) targetInfo.retInstr.getTmpInfo();
BitSet usedLocals BitSet usedLocals
= retInfo.jsrLocals[retInfo.jsrLocals.length-1]; = retInfo.jsrLocals[retInfo.jsrLocals.length-1];
for (int j = 0; j < bi.getMaxLocals(); j++) { for (int j = 0; j < bi.getMaxLocals(); j++) {
if (usedLocals.get(j)) if (usedLocals.get(j))
afterJsrInfo.locals[j] = retInfo.locals[j]; afterJsrInfo.locals[j] = retInfo.locals[j];
} }
if (mergeInfo(instr.nextByAddr, afterJsrInfo)) if (mergeInfo(instr.getNextByAddr(), afterJsrInfo))
instrStack.push(instr.nextByAddr); instrStack.push(instr.getNextByAddr());
} }
} }
if (instr.succs != null) { if (instr.getSuccs() != null) {
for (int i=0; i< instr.succs.length; i++) { for (int i=0; i< instr.getSuccs().length; i++) {
if (instr.succs[i].addr < instr.addr) { if (instr.getSuccs()[i].getAddr() < instr.getAddr()) {
/* This is a backwards branch */ /* This is a backwards branch */
for (int j = 0; j < prevInfo.locals.length; j++) { for (int j = 0; j < prevInfo.locals.length; j++) {
if (prevInfo.locals[j] if (prevInfo.locals[j]
@ -980,14 +992,14 @@ public class CodeVerifier implements Opcodes {
("Uninitialized stack in back-branch"); ("Uninitialized stack in back-branch");
} }
} }
if (mergeInfo(instr.succs[i], if (mergeInfo(instr.getSuccs()[i],
(VerifyInfo) info.clone())) (VerifyInfo) info.clone()))
instrStack.push(instr.succs[i]); instrStack.push(instr.getSuccs()[i]);
} }
} }
for (int i=0; i<handlers.length; i++) { for (int i=0; i<handlers.length; i++) {
if (handlers[i].start.addr <= instr.addr if (handlers[i].start.getAddr() <= instr.getAddr()
&& handlers[i].end.addr >= instr.addr) { && handlers[i].end.getAddr() >= instr.getAddr()) {
for (int j = 0; j < prevInfo.locals.length; j++) { for (int j = 0; j < prevInfo.locals.length; j++) {
if (prevInfo.locals[j] if (prevInfo.locals[j]
instanceof UninitializedClassType) instanceof UninitializedClassType)
@ -1011,9 +1023,9 @@ public class CodeVerifier implements Opcodes {
if ((GlobalOptions.debuggingFlags if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_VERIFIER) != 0) { & GlobalOptions.DEBUG_VERIFIER) != 0) {
for (Instruction instr = bi.getFirstInstr(); instr != null; for (Instruction instr = bi.getFirstInstr(); instr != null;
instr = instr.nextByAddr) { instr = instr.getNextByAddr()) {
VerifyInfo info = (VerifyInfo) instr.tmpInfo; VerifyInfo info = (VerifyInfo) instr.getTmpInfo();
if (info != null) if (info != null)
GlobalOptions.err.println(info.toString()); GlobalOptions.err.println(info.toString());
GlobalOptions.err.println(instr.getDescription()); GlobalOptions.err.println(instr.getDescription());
@ -1021,8 +1033,8 @@ public class CodeVerifier implements Opcodes {
} }
} }
for (Instruction instr = bi.getFirstInstr(); instr != null; for (Instruction instr = bi.getFirstInstr(); instr != null;
instr = instr.nextByAddr) instr = instr.getNextByAddr())
instr.tmpInfo = null; instr.setTmpInfo(null);
} }
@ -1031,14 +1043,14 @@ public class CodeVerifier implements Opcodes {
doVerify(); doVerify();
} catch (VerifyException ex) { } catch (VerifyException ex) {
for (Instruction instr = bi.getFirstInstr(); instr != null; for (Instruction instr = bi.getFirstInstr(); instr != null;
instr = instr.nextByAddr) { instr = instr.getNextByAddr()) {
VerifyInfo info = (VerifyInfo) instr.tmpInfo; VerifyInfo info = (VerifyInfo) instr.getTmpInfo();
if (info != null) if (info != null)
GlobalOptions.err.println(info.toString()); GlobalOptions.err.println(info.toString());
GlobalOptions.err.println(instr.getDescription()); GlobalOptions.err.println(instr.getDescription());
instr.tmpInfo = null; instr.setTmpInfo(null);
} }
throw ex; throw ex;
} }

@ -20,9 +20,14 @@
package jode.jvm; package jode.jvm;
import jode.AssertError; import jode.AssertError;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.type.*; import jode.bytecode.BytecodeInfo;
import jode.bytecode.*; import jode.bytecode.Handler;
import jode.decompiler.ClassAnalyzer; import jode.bytecode.Instruction;
import jode.bytecode.Opcodes;
import jode.bytecode.Reference;
import jode.type.MethodType;
import jode.type.Type;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -53,7 +58,7 @@ public class Interpreter implements Opcodes {
throws InterpreterException, InvocationTargetException { throws InterpreterException, InvocationTargetException {
if ((GlobalOptions.debuggingFlags if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_INTERPRT) != 0) & GlobalOptions.DEBUG_INTERPRT) != 0)
GlobalOptions.err.println("Interpreting "+code.getMethodInfo()); GlobalOptions.err.println("Interpreting "+code);
Value[] stack = new Value[code.getMaxStack()]; Value[] stack = new Value[code.getMaxStack()];
for (int i=0; i< stack.length; i++) for (int i=0; i< stack.length; i++)
stack[i] = new Value(); stack[i] = new Value();
@ -82,23 +87,23 @@ public class Interpreter implements Opcodes {
GlobalOptions.err.print(locals[i]+","); GlobalOptions.err.print(locals[i]+",");
GlobalOptions.err.println("]"); GlobalOptions.err.println("]");
} }
pc = instr.nextByAddr; pc = instr.getNextByAddr();
int opcode = instr.opcode; int opcode = instr.getOpcode();
switch (opcode) { switch (opcode) {
case opc_nop: case opc_nop:
break; break;
case opc_ldc: case opc_ldc:
stack[stacktop++].setObject(instr.objData); stack[stacktop++].setObject(instr.getConstant());
break; break;
case opc_ldc2_w: case opc_ldc2_w:
stack[stacktop].setObject(instr.objData); stack[stacktop].setObject(instr.getConstant());
stacktop += 2; stacktop += 2;
break; break;
case opc_iload: case opc_fload: case opc_aload: case opc_iload: case opc_fload: case opc_aload:
stack[stacktop++].setValue(locals[instr.localSlot]); stack[stacktop++].setValue(locals[instr.getLocalSlot()]);
break; break;
case opc_lload: case opc_dload: case opc_lload: case opc_dload:
stack[stacktop].setValue(locals[instr.localSlot]); stack[stacktop].setValue(locals[instr.getLocalSlot()]);
stacktop += 2; stacktop += 2;
break; break;
case opc_iaload: case opc_laload: case opc_iaload: case opc_laload:
@ -136,10 +141,10 @@ public class Interpreter implements Opcodes {
break; break;
} }
case opc_istore: case opc_fstore: case opc_astore: case opc_istore: case opc_fstore: case opc_astore:
locals[instr.localSlot].setValue(stack[--stacktop]); locals[instr.getLocalSlot()].setValue(stack[--stacktop]);
break; break;
case opc_lstore: case opc_dstore: case opc_lstore: case opc_dstore:
locals[instr.localSlot].setValue(stack[stacktop -= 2]); locals[instr.getLocalSlot()].setValue(stack[stacktop -= 2]);
break; break;
case opc_lastore: case opc_dastore: case opc_lastore: case opc_dastore:
@ -404,8 +409,8 @@ public class Interpreter implements Opcodes {
break; break;
case opc_iinc: case opc_iinc:
locals[instr.localSlot].setInt locals[instr.getLocalSlot()].setInt
(locals[instr.localSlot].intValue() + instr.intData); (locals[instr.getLocalSlot()].intValue() + instr.getIntData());
break; break;
case opc_i2l: case opc_i2l:
stack[stacktop-1] stack[stacktop-1]
@ -541,7 +546,7 @@ public class Interpreter implements Opcodes {
if (value > 0 && (opc_mask & CMP_GREATER_MASK) != 0 if (value > 0 && (opc_mask & CMP_GREATER_MASK) != 0
|| value < 0 && (opc_mask & CMP_LESS_MASK) != 0 || value < 0 && (opc_mask & CMP_LESS_MASK) != 0
|| value == 0 && (opc_mask & CMP_EQUAL_MASK) != 0) || value == 0 && (opc_mask & CMP_EQUAL_MASK) != 0)
pc = instr.succs[0]; pc = instr.getSuccs()[0];
break; break;
} }
case opc_jsr: case opc_jsr:
@ -550,27 +555,27 @@ public class Interpreter implements Opcodes {
/* fall through */ /* fall through */
case opc_goto: case opc_goto:
case opc_goto_w: case opc_goto_w:
pc = instr.succs[0]; pc = instr.getSuccs()[0];
break; break;
case opc_ret: case opc_ret:
pc = (Instruction)locals[instr.localSlot].objectValue(); pc = (Instruction)locals[instr.getLocalSlot()].objectValue();
break; break;
case opc_tableswitch: { case opc_tableswitch: {
int value = stack[--stacktop].intValue(); int value = stack[--stacktop].intValue();
int low = instr.intData; int low = instr.getIntData();
if (value >= low && value <= low + instr.succs.length - 2) if (value >= low && value <= low + instr.getSuccs().length - 2)
pc = instr.succs[value - low]; pc = instr.getSuccs()[value - low];
else else
pc = instr.succs[instr.succs.length-1]; pc = instr.getSuccs()[instr.getSuccs().length-1];
break; break;
} }
case opc_lookupswitch: { case opc_lookupswitch: {
int value = stack[--stacktop].intValue(); int value = stack[--stacktop].intValue();
int[] values = (int[]) instr.objData; int[] values = instr.getValues();
pc = instr.succs[values.length]; pc = instr.getSuccs()[values.length];
for (int i=0; i< values.length; i++) { for (int i=0; i< values.length; i++) {
if (values[i] == value) { if (values[i] == value) {
pc = instr.succs[i]; pc = instr.getSuccs()[i];
break; break;
} }
} }
@ -583,46 +588,46 @@ public class Interpreter implements Opcodes {
case opc_return: case opc_return:
return Void.TYPE; return Void.TYPE;
case opc_getstatic: { case opc_getstatic: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
stack[stacktop].setObject stack[stacktop].setObject
(env.getField((Reference) instr.objData, null)); (env.getField(instr.getReference(), null));
stacktop += Type.tType(ref.getType()).stackSize(); stacktop += Type.tType(ref.getType()).stackSize();
break; break;
} }
case opc_getfield: { case opc_getfield: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
Object cls = stack[--stacktop]; Object cls = stack[--stacktop];
if (cls == null) if (cls == null)
throw new InvocationTargetException throw new InvocationTargetException
(new NullPointerException()); (new NullPointerException());
stack[stacktop].setObject stack[stacktop].setObject
(env.getField((Reference) instr.objData, cls)); (env.getField(instr.getReference(), cls));
stacktop += Type.tType(ref.getType()).stackSize(); stacktop += Type.tType(ref.getType()).stackSize();
break; break;
} }
case opc_putstatic: { case opc_putstatic: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
stacktop -= Type.tType(ref.getType()).stackSize(); stacktop -= Type.tType(ref.getType()).stackSize();
Object value = stack[stacktop]; Object value = stack[stacktop];
env.putField((Reference) instr.objData, null, value); env.putField(instr.getReference(), null, value);
break; break;
} }
case opc_putfield: { case opc_putfield: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
stacktop -= Type.tType(ref.getType()).stackSize(); stacktop -= Type.tType(ref.getType()).stackSize();
Object value = stack[stacktop]; Object value = stack[stacktop];
Object cls = stack[--stacktop]; Object cls = stack[--stacktop];
if (cls == null) if (cls == null)
throw new InvocationTargetException throw new InvocationTargetException
(new NullPointerException()); (new NullPointerException());
env.putField((Reference) instr.objData, cls, value); env.putField(instr.getReference(), cls, value);
break; break;
} }
case opc_invokevirtual: case opc_invokevirtual:
case opc_invokespecial: case opc_invokespecial:
case opc_invokestatic : case opc_invokestatic :
case opc_invokeinterface: { case opc_invokeinterface: {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
MethodType mt = (MethodType) Type.tType(ref.getType()); MethodType mt = (MethodType) Type.tType(ref.getType());
Object[] args = new Object[mt.getParameterTypes().length]; Object[] args = new Object[mt.getParameterTypes().length];
for (int i=args.length - 1; i >= 0; i--) { for (int i=args.length - 1; i >= 0; i--) {
@ -654,14 +659,14 @@ public class Interpreter implements Opcodes {
break; break;
} }
case opc_new: { case opc_new: {
String clazz = (String) instr.objData; String clazz = instr.getClazzType();
stack[stacktop++].setNewObject(new NewObject(clazz)); stack[stacktop++].setNewObject(new NewObject(clazz));
break; break;
} }
case opc_newarray: { case opc_newarray: {
int length = stack[--stacktop].intValue(); int length = stack[--stacktop].intValue();
try { try {
switch (instr.intData) { switch (instr.getIntData()) {
case 4: case 4:
stack[stacktop++].setObject(new boolean[length]); stack[stacktop++].setObject(new boolean[length]);
break; break;
@ -698,7 +703,7 @@ public class Interpreter implements Opcodes {
int length = stack[--stacktop].intValue(); int length = stack[--stacktop].intValue();
try { try {
stack[stacktop++].setObject stack[stacktop++].setObject
(env.newArray((String) instr.objData, (env.newArray(instr.getClazzType(),
new int[] { length })); new int[] { length }));
} catch (NegativeArraySizeException ex) { } catch (NegativeArraySizeException ex) {
throw new InvocationTargetException(ex); throw new InvocationTargetException(ex);
@ -719,7 +724,7 @@ public class Interpreter implements Opcodes {
case opc_checkcast: { case opc_checkcast: {
Object obj = stack[stacktop-1].objectValue(); Object obj = stack[stacktop-1].objectValue();
if (obj != null if (obj != null
&& !env.instanceOf(obj, (String) instr.objData)) && !env.instanceOf(obj, instr.getClazzType()))
throw new InvocationTargetException throw new InvocationTargetException
(new ClassCastException(obj.getClass().getName())); (new ClassCastException(obj.getClass().getName()));
break; break;
@ -727,7 +732,7 @@ public class Interpreter implements Opcodes {
case opc_instanceof: { case opc_instanceof: {
Object obj = stack[--stacktop].objectValue(); Object obj = stack[--stacktop].objectValue();
stack[stacktop++].setInt stack[stacktop++].setInt
(env.instanceOf(obj, (String) instr.objData) ? 1 : 0); (env.instanceOf(obj, instr.getClazzType()) ? 1 : 0);
break; break;
} }
case opc_monitorenter: case opc_monitorenter:
@ -737,13 +742,13 @@ public class Interpreter implements Opcodes {
env.exitMonitor(stack[--stacktop].objectValue()); env.exitMonitor(stack[--stacktop].objectValue());
break; break;
case opc_multianewarray: { case opc_multianewarray: {
int dimension = instr.intData; int dimension = instr.getIntData();
int[] dims = new int[dimension]; int[] dims = new int[dimension];
for (int i=dimension - 1; i >= 0; i--) for (int i=dimension - 1; i >= 0; i--)
dims[i] = stack[--stacktop].intValue(); dims[i] = stack[--stacktop].intValue();
try { try {
stack[stacktop++].setObject stack[stacktop++].setObject
(env.newArray((String) instr.objData, dims)); (env.newArray(instr.getClazzType(), dims));
} catch (NegativeArraySizeException ex) { } catch (NegativeArraySizeException ex) {
throw new InvocationTargetException(ex); throw new InvocationTargetException(ex);
} }
@ -756,8 +761,8 @@ public class Interpreter implements Opcodes {
Handler[] handlers = code.getExceptionHandlers(); Handler[] handlers = code.getExceptionHandlers();
Throwable obj = ex.getTargetException(); Throwable obj = ex.getTargetException();
for (int i=0; i< handlers.length; i++) { for (int i=0; i< handlers.length; i++) {
if (handlers[i].start.addr <= pc.addr if (handlers[i].start.getAddr() <= pc.getAddr()
&& handlers[i].end.addr >= pc.addr && handlers[i].end.getAddr() >= pc.getAddr()
&& (handlers[i].type == null && (handlers[i].type == null
|| env.instanceOf(obj, handlers[i].type))) { || env.instanceOf(obj, handlers[i].type))) {
stacktop = 0; stacktop = 0;

@ -18,7 +18,6 @@
*/ */
package jode.jvm; package jode.jvm;
import jode.bytecode.*;
/** /**
* This exception is thrown by the interpreter on various conditions. * This exception is thrown by the interpreter on various conditions.

@ -18,7 +18,6 @@
*/ */
package jode.jvm; package jode.jvm;
import jode.bytecode.*;
/** /**
* This class represents a new object, that may not be initialized yet. * This class represents a new object, that may not be initialized yet.

@ -20,8 +20,15 @@
package jode.jvm; package jode.jvm;
import jode.AssertError; import jode.AssertError;
import jode.bytecode.Reference; import jode.bytecode.Reference;
import jode.type.*; import jode.type.Type;
import java.lang.reflect.*; import jode.type.IntegerType;
import jode.type.MethodType;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class SimpleRuntimeEnvironment implements RuntimeEnvironment { public class SimpleRuntimeEnvironment implements RuntimeEnvironment {

@ -63,10 +63,10 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
opc_astore, opc_new, opc_dup, opc_aload, opc_astore, opc_new, opc_dup, opc_aload,
opc_invokevirtual, opc_invokespecial, opc_athrow opc_invokevirtual, opc_invokespecial, opc_athrow
}; };
private static final Object[] getClassRefs = { private static final Reference[] getClassRefs = {
null, Reference.getReference("Ljava/lang/Class;", "forName", null, Reference.getReference("Ljava/lang/Class;", "forName",
"(Ljava/lang/String;)Ljava/lang/Class;"), "(Ljava/lang/String;)Ljava/lang/Class;"),
null, null, "Ljava/lang/NoClassDefFoundError;", null, null, null, null, null, null, null,
Reference.getReference("Ljava/lang/Throwable;", "getMessage", Reference.getReference("Ljava/lang/Throwable;", "getMessage",
"()Ljava/lang/String;"), "()Ljava/lang/String;"),
Reference.getReference("Ljava/lang/NoClassDefFoundError;", "<init>", Reference.getReference("Ljava/lang/NoClassDefFoundError;", "<init>",
@ -88,25 +88,29 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
int excSlot = -1; int excSlot = -1;
Instruction instr = bytecode.getFirstInstr(); Instruction instr = bytecode.getFirstInstr();
if (excHandlers[0].start != instr) if (excHandlers[0].start != instr
|| !"java.lang.ClassNotFoundException".equals(excHandlers[0].type))
return false; return false;
for (int i=0; i< getClassOpcodes.length; i++) { for (int i=0; i< getClassOpcodes.length; i++) {
if (instr.opcode != getClassOpcodes[i]) if (instr.getOpcode() != getClassOpcodes[i])
return false; return false;
if (i==0 && instr.localSlot != 0) if (i==0 && instr.getLocalSlot() != 0)
return false; return false;
if (i == 3) if (i == 3)
excSlot = instr.localSlot; excSlot = instr.getLocalSlot();
if (i == 6 && instr.localSlot != excSlot) if (i == 6 && instr.getLocalSlot() != excSlot)
return false; return false;
if (i == 2 && excHandlers[0].end != instr) if (i == 2 && excHandlers[0].end != instr)
return false; return false;
if (i == 3 && excHandlers[0].catcher != instr) if (i == 3 && excHandlers[0].catcher != instr)
return false; return false;
if (i == 4 && !instr.getClazzType().equals
("Ljava/lang/NoClassDefFoundError;"))
return false;
if (getClassRefs[i] != null if (getClassRefs[i] != null
&& !getClassRefs[i].equals(instr.objData)) && !getClassRefs[i].equals(instr.getReference()))
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
} }
if (instr != null) if (instr != null)
return false; return false;
@ -122,8 +126,8 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
BytecodeInfo bytecode = method.getBytecode(); BytecodeInfo bytecode = method.getBytecode();
Instruction instr = bytecode.getFirstInstr(); Instruction instr = bytecode.getFirstInstr();
if (instr.opcode == opc_getstatic) { if (instr.getOpcode() == opc_getstatic) {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -133,10 +137,11 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refField.getModifiers() & modifierMask) != if ((refField.getModifiers() & modifierMask) !=
(Modifier.PRIVATE | Modifier.STATIC)) (Modifier.PRIVATE | Modifier.STATIC))
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (instr.opcode < opc_ireturn || instr.opcode > opc_areturn) if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false; return false;
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
/* For valid bytecode the type matches automatically */ /* For valid bytecode the type matches automatically */
reference = ref; reference = ref;
@ -144,18 +149,19 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
return true; return true;
} }
int params = 0, slot = 0; int params = 0, slot = 0;
while (instr.opcode >= opc_iload && instr.opcode <= opc_aload while (instr.getOpcode() >= opc_iload
&& instr.localSlot == slot) { && instr.getOpcode() <= opc_aload
&& instr.getLocalSlot() == slot) {
params++; params++;
slot += (instr.opcode == opc_lload slot += (instr.getOpcode() == opc_lload
|| instr.opcode == opc_dload) ? 2 : 1; || instr.getOpcode() == opc_dload) ? 2 : 1;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
} }
if (instr.opcode == opc_putstatic) { if (instr.getOpcode() == opc_putstatic) {
if (params != 1) if (params != 1)
return false; return false;
/* For valid bytecode the type of param matches automatically */ /* For valid bytecode the type of param matches automatically */
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -165,17 +171,17 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refField.getModifiers() & modifierMask) != if ((refField.getModifiers() & modifierMask) !=
(Modifier.PRIVATE | Modifier.STATIC)) (Modifier.PRIVATE | Modifier.STATIC))
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (instr.opcode != opc_return) if (instr.getOpcode() != opc_return)
return false; return false;
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
reference = ref; reference = ref;
kind = ACCESSPUTSTATIC; kind = ACCESSPUTSTATIC;
return true; return true;
} }
if (instr.opcode == opc_invokestatic) { if (instr.getOpcode() == opc_invokestatic) {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -187,15 +193,16 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
(Modifier.PRIVATE | Modifier.STATIC) (Modifier.PRIVATE | Modifier.STATIC)
|| refType.getParameterTypes().length != params) || refType.getParameterTypes().length != params)
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (refType.getReturnType() == Type.tVoid) { if (refType.getReturnType() == Type.tVoid) {
if (instr.opcode != opc_return) if (instr.getOpcode() != opc_return)
return false; return false;
} else { } else {
if (instr.opcode < opc_ireturn || instr.opcode > opc_areturn) if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false; return false;
} }
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
/* For valid bytecode the types matches automatically */ /* For valid bytecode the types matches automatically */
@ -219,12 +226,12 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
} }
Instruction instr = bytecode.getFirstInstr(); Instruction instr = bytecode.getFirstInstr();
if (instr.opcode != opc_aload || instr.localSlot != 0) if (instr.getOpcode() != opc_aload || instr.getLocalSlot() != 0)
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (instr.opcode == opc_getfield) { if (instr.getOpcode() == opc_getfield) {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -233,10 +240,11 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
= clazzInfo.findField(ref.getName(), ref.getType()); = clazzInfo.findField(ref.getName(), ref.getType());
if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE) if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE)
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (instr.opcode < opc_ireturn || instr.opcode > opc_areturn) if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false; return false;
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
/* For valid bytecode the type matches automatically */ /* For valid bytecode the type matches automatically */
reference = ref; reference = ref;
@ -244,18 +252,19 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
return true; return true;
} }
int params = 0, slot = 1; int params = 0, slot = 1;
while (instr.opcode >= opc_iload && instr.opcode <= opc_aload while (instr.getOpcode() >= opc_iload
&& instr.localSlot == slot) { && instr.getOpcode() <= opc_aload
&& instr.getLocalSlot() == slot) {
params++; params++;
slot += (instr.opcode == opc_lload slot += (instr.getOpcode() == opc_lload
|| instr.opcode == opc_dload) ? 2 : 1; || instr.getOpcode() == opc_dload) ? 2 : 1;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
} }
if (instr.opcode == opc_putfield) { if (instr.getOpcode() == opc_putfield) {
if (params != 1) if (params != 1)
return false; return false;
/* For valid bytecode the type of param matches automatically */ /* For valid bytecode the type of param matches automatically */
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -264,17 +273,17 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
= clazzInfo.findField(ref.getName(), ref.getType()); = clazzInfo.findField(ref.getName(), ref.getType());
if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE) if ((refField.getModifiers() & modifierMask) != Modifier.PRIVATE)
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (instr.opcode != opc_return) if (instr.getOpcode() != opc_return)
return false; return false;
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
reference = ref; reference = ref;
kind = ACCESSPUTFIELD; kind = ACCESSPUTFIELD;
return true; return true;
} }
if (instr.opcode == opc_invokespecial) { if (instr.getOpcode() == opc_invokespecial) {
Reference ref = (Reference) instr.objData; Reference ref = instr.getReference();
String refClazz = ref.getClazz().substring(1); String refClazz = ref.getClazz().substring(1);
if (!(refClazz.substring(0, refClazz.length()-1) if (!(refClazz.substring(0, refClazz.length()-1)
.equals(clazzInfo.getName().replace('.','/')))) .equals(clazzInfo.getName().replace('.','/'))))
@ -285,15 +294,16 @@ public class SyntheticAnalyzer implements jode.bytecode.Opcodes {
if ((refMethod.getModifiers() & modifierMask) != Modifier.PRIVATE if ((refMethod.getModifiers() & modifierMask) != Modifier.PRIVATE
|| refType.getParameterTypes().length != params) || refType.getParameterTypes().length != params)
return false; return false;
instr = instr.nextByAddr; instr = instr.getNextByAddr();
if (refType.getReturnType() == Type.tVoid) { if (refType.getReturnType() == Type.tVoid) {
if (instr.opcode != opc_return) if (instr.getOpcode() != opc_return)
return false; return false;
} else { } else {
if (instr.opcode < opc_ireturn || instr.opcode > opc_areturn) if (instr.getOpcode() < opc_ireturn
|| instr.getOpcode() > opc_areturn)
return false; return false;
} }
if (instr.nextByAddr != null) if (instr.getNextByAddr() != null)
return false; return false;
/* For valid bytecode the types matches automatically */ /* For valid bytecode the types matches automatically */

Loading…
Cancel
Save