simplified Interpreter even more

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1115 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 26 years ago
parent 2b972a10ae
commit e52d921afc
  1. 152
      jode/jode/jvm/Interpreter.java.in
  2. 79
      jode/jode/jvm/SimpleRuntimeEnvironment.java
  3. 2
      jode/jode/jvm/Value.java
  4. 32
      jode/jode/obfuscator/ConstantAnalyzer.java.in
  5. 5
      jode/jode/obfuscator/ConstantRuntimeEnvironment.java

@ -71,22 +71,7 @@ public class Interpreter implements Opcodes {
if (!code.getMethodInfo().isStatic())
locals[slot++].setObject(cls);
for (int i=0; i< myParamTypes.length; i++) {
char type = myParamTypes[i].charAt(0);
switch ("ZBSC".indexOf(type)) {
case 0:
locals[slot].setInt(((Boolean) params[i])
.booleanValue() ? 1 : 0);
break;
case 1: case 2:
locals[slot].setInt(((Number) params[i]).intValue());
break;
case 3:
locals[slot].setInt(((Character) params[i]).charValue());
break;
default:
locals[slot].setObject(params[i]);
break;
}
slot += TypeSignature.getTypeSize(myParamTypes[i]);
}
return locals;
@ -611,25 +596,7 @@ public class Interpreter implements Opcodes {
: instr.getSuccs()[pos];
break;
}
case opc_ireturn: {
Object result = stack[--stacktop].objectValue();
String retType = TypeSignature
.getReturnType(code.getMethodInfo().getType());
switch ("ZBSC".indexOf(retType.charAt(0))) {
case 0: // boolean
return new Boolean(((Integer)result).intValue() != 0);
case 1: // byte
return new Byte(((Integer)result).byteValue());
case 2: // short
return new Short(((Integer)result).shortValue());
case 3: // char
return new Character((char)
((Integer)result).intValue());
default: // integer
return result;
}
}
case opc_freturn: case opc_areturn:
case opc_ireturn: case opc_freturn: case opc_areturn:
return stack[--stacktop].objectValue();
case opc_lreturn: case opc_dreturn:
return stack[stacktop -= 2].objectValue();
@ -638,24 +605,7 @@ public class Interpreter implements Opcodes {
case opc_getstatic: {
Reference ref = instr.getReference();
Object result = env.getField(instr.getReference(), null);
char type = ref.getType().charAt(0);
switch ("ZBSC".indexOf(type)) {
case 0:
stack[stacktop].setInt(((Boolean) result)
.booleanValue() ? 1 : 0);
break;
case 1: case 2:
stack[stacktop].setInt(((Number) result)
.intValue());
break;
case 3:
stack[stacktop].setInt(((Character) result)
.charValue());
break;
default:
stack[stacktop].setObject(result);
break;
}
stacktop += TypeSignature.getTypeSize(ref.getType());
break;
}
@ -666,24 +616,7 @@ public class Interpreter implements Opcodes {
throw new InvocationTargetException
(new NullPointerException());
Object result = env.getField(instr.getReference(), cls);
char type = ref.getType().charAt(0);
switch ("ZBSC".indexOf(type)) {
case 0:
stack[stacktop].setInt(((Boolean) result)
.booleanValue() ? 1 : 0);
break;
case 1: case 2:
stack[stacktop].setInt(((Number) result)
.intValue());
break;
case 3:
stack[stacktop].setInt(((Character) result)
.charValue());
break;
default:
stack[stacktop].setObject(result);
break;
}
stacktop += TypeSignature.getTypeSize(ref.getType());
break;
}
@ -691,22 +624,6 @@ public class Interpreter implements Opcodes {
Reference ref = instr.getReference();
stacktop -= TypeSignature.getTypeSize(ref.getType());
Object value = stack[stacktop].objectValue();
int type = "ZBSC".indexOf(ref.getType().charAt(0));
switch(type) {
case 0: // boolean
value = new Boolean(((Integer)value).intValue() != 0);
break;
case 1: // byte
value = new Byte(((Integer)value).byteValue());
break;
case 2: // short
value = new Short(((Integer)value).shortValue());
break;
case 3: // char
value = new Character((char)
((Integer)value).intValue());
break;
}
env.putField(instr.getReference(), null, value);
break;
}
@ -714,22 +631,6 @@ public class Interpreter implements Opcodes {
Reference ref = instr.getReference();
stacktop -= TypeSignature.getTypeSize(ref.getType());
Object value = stack[stacktop].objectValue();
int type = "ZBSC".indexOf(ref.getType().charAt(0));
switch(type) {
case 0: // boolean
value = new Boolean(((Integer)value).intValue() != 0);
break;
case 1: // byte
value = new Byte(((Integer)value).byteValue());
break;
case 2: // short
value = new Short(((Integer)value).shortValue());
break;
case 3: // char
value = new Character((char)
((Integer)value).intValue());
break;
}
Object cls = stack[--stacktop].objectValue();
if (cls == null)
throw new InvocationTargetException
@ -747,33 +648,17 @@ public class Interpreter implements Opcodes {
Object[] args = new Object[paramTypes.length];
for (int i = paramTypes.length - 1; i >= 0; i--) {
stacktop -= TypeSignature.getTypeSize(paramTypes[i]);
Object value = stack[stacktop].objectValue();
int type = "ZBSC".indexOf(paramTypes[i].charAt(0));
switch(type) {
case 0: // boolean
value = new Boolean(((Integer)value)
.intValue() != 0);
break;
case 1: // byte
value = new Byte(((Integer)value).byteValue());
break;
case 2: // short
value = new Short(((Integer)value).shortValue());
break;
case 3: // char
value = new Character((char)
((Integer)value).intValue());
break;
}
args[i] = value;
args[i] = stack[stacktop].objectValue();
}
Object result = null;
if (ref.getName().equals("<init>")) {
if (opcode == opc_invokespecial
&& ref.getName().equals("<init>")
&& stack[--stacktop].getNewObject() != null) {
NewObject newObj = stack[--stacktop].getNewObject();
// if (!newObj.getType().equals(ref.getClazz()))
// throw new InterpreterException
// ("constructor called on wrong type");
if (!newObj.getType().equals(ref.getClazz()))
throw new InterpreterException
("constructor doesn't match new");
newObj.setObject(env.invokeConstructor(ref, args));
} else if (opcode == opc_invokestatic) {
result = env.invokeMethod(ref, false, null, args);
@ -787,27 +672,10 @@ public class Interpreter implements Opcodes {
}
String retType
= TypeSignature.getReturnType(ref.getType());
char type = retType.charAt(0);
switch ("ZBSCV".indexOf(type)) {
case 0:
stack[stacktop].setInt(((Boolean) result)
.booleanValue() ? 1 : 0);
break;
case 1: case 2:
stack[stacktop].setInt(((Number) result)
.intValue());
break;
case 3:
stack[stacktop].setInt(((Character) result)
.charValue());
break;
case 4: // Void
break;
default:
if (!retType.equals("V")) {
stack[stacktop].setObject(result);
break;
}
stacktop += TypeSignature.getTypeSize(retType);
}
break;
}
case opc_new: {

@ -20,9 +20,7 @@
package jode.jvm;
import jode.AssertError;
import jode.bytecode.Reference;
import jode.type.Type;
import jode.type.IntegerType;
import jode.type.MethodType;
import jode.bytecode.TypeSignature;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
@ -32,17 +30,40 @@ import java.lang.reflect.InvocationTargetException;
public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
public Class findClazz(String clName) throws ClassNotFoundException {
if (clName.charAt(0) == 'L')
clName = clName.substring(1, clName.length()-1);
return Class.forName(clName.replace('/','.'));
public static Object fromReflectType(String typeSig, Object value) {
switch(typeSig.charAt(0)) {
case 'Z':
return new Integer(((Boolean) value).booleanValue() ? 1 : 0);
case 'B':
case 'S':
return new Integer(((Number) value).intValue());
case 'C':
return new Integer(((Character) value).charValue());
default:
return value;
}
}
public static Object toReflectType(String typeSig, Object value) {
switch(typeSig.charAt(0)) {
case 'Z':
return new Boolean(((Integer)value).intValue() != 0);
case 'B':
return new Byte(((Integer)value).byteValue());
case 'S':
return new Short(((Integer)value).shortValue());
case 'C':
return new Character((char) ((Integer)value).intValue());
default:
return value;
}
}
public Object getField(Reference ref, Object obj)
throws InterpreterException {
Field f;
try {
Class clazz = findClazz(ref.getClazz());
Class clazz = TypeSignature.getClass(ref.getClazz());
try {
f = clazz.getField(ref.getName());
} catch (NoSuchFieldException ex) {
@ -59,17 +80,18 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
(ref+": Security exception");
}
try {
return f.get(obj);
return fromReflectType(ref.getType(), f.get(obj));
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Field " + ref + " not accessible");
}
}
public void putField(Reference ref, Object obj, Object value)
throws InterpreterException {
Field f;
try {
Class clazz = findClazz(ref.getClazz());
Class clazz = TypeSignature.getClass(ref.getClazz());
try {
f = clazz.getField(ref.getName());
} catch (NoSuchFieldException ex) {
@ -86,7 +108,7 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
(ref+": Security exception");
}
try {
f.set(obj, value);
f.set(obj, toReflectType(ref.getType(), value));
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Field " + ref + " not accessible");
@ -97,9 +119,14 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
throws InterpreterException, InvocationTargetException {
Constructor c;
try {
Class clazz = findClazz(ref.getClazz());
MethodType mt = (MethodType) Type.tType(ref.getType());
Class[] paramTypes = mt.getParameterClasses();
String[] paramTypeSigs
= TypeSignature.getParameterTypes(ref.getType());
Class clazz = TypeSignature.getClass(ref.getClazz());
Class[] paramTypes = new Class[paramTypeSigs.length];
for (int i=0; i< paramTypeSigs.length; i++) {
params[i] = toReflectType(paramTypeSigs[i], params[i]);
paramTypes[i] = TypeSignature.getClass(paramTypeSigs[i]);
}
try {
c = clazz.getConstructor(paramTypes);
} catch (NoSuchMethodException ex) {
@ -130,14 +157,20 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
public Object invokeMethod(Reference ref, boolean isVirtual,
Object cls, Object[] params)
throws InterpreterException, InvocationTargetException {
Method m;
if (!isVirtual && cls != null) /*XXX*/
throw new InterpreterException
("Can't invoke nonvirtual Method " + ref + ".");
MethodType mt = (MethodType) Type.tType(ref.getType());
Method m;
try {
Class clazz = findClazz(ref.getClazz());
Class[] paramTypes = mt.getParameterClasses();
String[] paramTypeSigs
= TypeSignature.getParameterTypes(ref.getType());
Class clazz = TypeSignature.getClass(ref.getClazz());
Class[] paramTypes = new Class[paramTypeSigs.length];
for (int i=0; i< paramTypeSigs.length; i++) {
params[i] = toReflectType(paramTypeSigs[i], params[i]);
paramTypes[i] = TypeSignature.getClass(paramTypeSigs[i]);
}
try {
m = clazz.getMethod(ref.getName(), paramTypes);
} catch (NoSuchMethodException ex) {
@ -153,8 +186,9 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
throw new InterpreterException
(ref+": Security exception");
}
String retType = TypeSignature.getReturnType(ref.getType());
try {
return m.invoke(cls, params);
return fromReflectType(retType, m.invoke(cls, params));
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Method " + ref + " not accessible");
@ -178,8 +212,7 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
Class clazz;
try {
/* get the base class (strip leading "[") */
clazz = Type.tType(type.substring(dimensions.length))
.getTypeClass();
clazz = TypeSignature.getClass(type.substring(dimensions.length));
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
@ -189,10 +222,10 @@ public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
public void enterMonitor(Object obj)
throws InterpreterException {
throw new InterpreterException("monitorenter not implemented");
throw new InterpreterException("monitor not implemented");
}
public void exitMonitor(Object obj)
throws InterpreterException {
throw new InterpreterException("monitorenter not implemented");
throw new InterpreterException("monitor not implemented");
}
}

@ -25,7 +25,7 @@ import jode.bytecode.*;
*
* @author Jochen Hoenicke
*/
public class Value {
class Value {
Object value;
NewObject newObj;

@ -1191,41 +1191,39 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_invokevirtual: {
canonizeReference(instr);
Reference ref = instr.getReference();
MethodType mt = (MethodType) Type.tType(ref.getType());
boolean constant = true;
int size = 0;
Object cls = null;
Object[] args = new Object[mt.getParameterTypes().length];
String[] paramTypes
= TypeSignature.getParameterTypes(ref.getType());
Object[] args = new Object[paramTypes.length];
ConstValue clsValue = null;
ConstValue[] argValues =
new ConstValue[mt.getParameterTypes().length];
for (int i=mt.getParameterTypes().length-1; i >=0; i--) {
size += mt.getParameterTypes()[i].stackSize();
argValues[i] = info.getStack(size);
if (argValues[i].value != ConstValue.VOLATILE)
args[i] = argValues[i].value;
ConstValue[] argValues = new ConstValue[paramTypes.length];
for (int i = paramTypes.length - 1; i >= 0; i--) {
size += TypeSignature.getTypeSize(paramTypes[i]);
Object value = (argValues[i] = info.getStack(size)).value;
if (value != ConstValue.VOLATILE)
arg[i] = value;
else
constant = false;
}
if (opcode != opc_invokestatic) {
size++;
clsValue = info.getStack(size);
cls = clsValue.value;
if (cls == ConstValue.VOLATILE
|| cls == null
|| !cls.getClass().getName().equals(ref.getClazz()))
if (cls == ConstValue.VOLATILE || cls == null)
constant = false;
}
Type retType = mt.getReturnType();
if (retType == Type.tVoid) {
String retType = TypeSignature.getReturnType(ref.getType());
if (retType.equals("V")) {
handleReference(ref, opcode == opc_invokevirtual
|| opcode == opc_invokeinterface);
mergeInfo(instr.getNextByAddr(), info.pop(size));
break;
}
if (constant
&& retType != Type.tString
&& retType.getTypeSignature().length() != 1) {
if (constant && !runtime.isWhite(retType)) {
/* This is not a valid constant type */
constant = false;
}

@ -55,6 +55,11 @@ public class ConstantRuntimeEnvironment extends SimpleRuntimeEnvironment {
public static boolean isWhite(Reference ref) {
return whiteList.containsKey(ref);
}
public static boolean isWhiteType(String retTypeSig) {
return retTypeSig.length() != 1;
&& !whiteList.contains(retTypeSig);
}
///#endif
static {

Loading…
Cancel
Save