From e52d921afc2252c18d570b77eca56349242074ac Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Jul 1999 15:06:42 +0000 Subject: [PATCH] simplified Interpreter even more git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1115 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/jvm/Interpreter.java.in | 158 ++---------------- jode/jode/jvm/SimpleRuntimeEnvironment.java | 79 ++++++--- jode/jode/jvm/Value.java | 2 +- jode/jode/obfuscator/ConstantAnalyzer.java.in | 32 ++-- .../ConstantRuntimeEnvironment.java | 5 + 5 files changed, 90 insertions(+), 186 deletions(-) diff --git a/jode/jode/jvm/Interpreter.java.in b/jode/jode/jvm/Interpreter.java.in index 011b5f3..18d0a0d 100644 --- a/jode/jode/jvm/Interpreter.java.in +++ b/jode/jode/jvm/Interpreter.java.in @@ -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; - } + locals[slot].setObject(params[i]); 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; - } + stack[stacktop].setObject(result); 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; - } + stack[stacktop].setObject(result); 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("")) { + if (opcode == opc_invokespecial + && ref.getName().equals("") + && 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); } - stacktop += TypeSignature.getTypeSize(retType); break; } case opc_new: { diff --git a/jode/jode/jvm/SimpleRuntimeEnvironment.java b/jode/jode/jvm/SimpleRuntimeEnvironment.java index 900ad26..a6383f9 100644 --- a/jode/jode/jvm/SimpleRuntimeEnvironment.java +++ b/jode/jode/jvm/SimpleRuntimeEnvironment.java @@ -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"); } } diff --git a/jode/jode/jvm/Value.java b/jode/jode/jvm/Value.java index ee030bd..518e917 100644 --- a/jode/jode/jvm/Value.java +++ b/jode/jode/jvm/Value.java @@ -25,7 +25,7 @@ import jode.bytecode.*; * * @author Jochen Hoenicke */ -public class Value { +class Value { Object value; NewObject newObj; diff --git a/jode/jode/obfuscator/ConstantAnalyzer.java.in b/jode/jode/obfuscator/ConstantAnalyzer.java.in index f465aa6..e803a97 100644 --- a/jode/jode/obfuscator/ConstantAnalyzer.java.in +++ b/jode/jode/obfuscator/ConstantAnalyzer.java.in @@ -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; } diff --git a/jode/jode/obfuscator/ConstantRuntimeEnvironment.java b/jode/jode/obfuscator/ConstantRuntimeEnvironment.java index d882507..9339ce2 100644 --- a/jode/jode/obfuscator/ConstantRuntimeEnvironment.java +++ b/jode/jode/obfuscator/ConstantRuntimeEnvironment.java @@ -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 {