Mirror of the JODE repository
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
jode/jode/src/net/sf/jode/jvm/SimpleRuntimeEnvironment.java

235 lines
7.3 KiB

/* SimpleRuntimeEnvironment Copyright (C) 1999 Jochen Hoenicke.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package net.sf.jode.jvm;
import net.sf.jode.bytecode.Reference;
import net.sf.jode.bytecode.TypeSignature;
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;
/**
* This is a runtime environment using reflection.
* Monitors are not supported by this class so exit/enterMonitor
* will through an InterpreterException.
*/
public class SimpleRuntimeEnvironment implements RuntimeEnvironment {
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 = TypeSignature.getClass(ref.getClazz());
try {
f = clazz.getField(ref.getName());
} catch (NoSuchFieldException ex) {
f = clazz.getDeclaredField(ref.getName());
}
} catch (ClassNotFoundException ex) {
throw new InterpreterException
(ref+": Class not found");
} catch (NoSuchFieldException ex) {
throw new InterpreterException
("Constructor "+ref+" not found");
} catch (SecurityException ex) {
throw new InterpreterException
(ref+": Security exception");
}
try {
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 = TypeSignature.getClass(ref.getClazz());
try {
f = clazz.getField(ref.getName());
} catch (NoSuchFieldException ex) {
f = clazz.getDeclaredField(ref.getName());
}
} catch (ClassNotFoundException ex) {
throw new InterpreterException
(ref+": Class not found");
} catch (NoSuchFieldException ex) {
throw new InterpreterException
("Constructor "+ref+" not found");
} catch (SecurityException ex) {
throw new InterpreterException
(ref+": Security exception");
}
try {
f.set(obj, toReflectType(ref.getType(), value));
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Field " + ref + " not accessible");
}
}
public Object invokeConstructor(Reference ref, Object[] params)
throws InterpreterException, InvocationTargetException {
Constructor c;
try {
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) {
c = clazz.getDeclaredConstructor(paramTypes);
}
} catch (ClassNotFoundException ex) {
throw new InterpreterException
(ref+": Class not found");
} catch (NoSuchMethodException ex) {
throw new InterpreterException
("Constructor "+ref+" not found");
} catch (SecurityException ex) {
throw new InterpreterException
(ref+": Security exception");
}
try {
return c.newInstance(params);
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Constructor " + ref + " not accessible");
} catch (InstantiationException ex) {
throw new InterpreterException
("InstantiationException in " + ref + ".");
}
}
public Object invokeMethod(Reference ref, boolean isVirtual,
Object cls, Object[] params)
throws InterpreterException, InvocationTargetException {
if (!isVirtual && cls != null) /*XXX*/
throw new InterpreterException
("Can't invoke nonvirtual Method " + ref + ".");
Method m;
try {
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) {
m = clazz.getDeclaredMethod(ref.getName(), paramTypes);
}
} catch (ClassNotFoundException ex) {
throw new InterpreterException
(ref+": Class not found");
} catch (NoSuchMethodException ex) {
throw new InterpreterException
("Method "+ref+" not found");
} catch (SecurityException ex) {
throw new InterpreterException
(ref+": Security exception");
}
String retType = TypeSignature.getReturnType(ref.getType());
try {
return fromReflectType(retType, m.invoke(cls, params));
} catch (IllegalAccessException ex) {
throw new InterpreterException
("Method " + ref + " not accessible");
}
}
public boolean instanceOf(Object obj, String className)
throws InterpreterException {
Class clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
}
return obj != null && !clazz.isInstance(obj);
}
public Object newArray(String type, int[] dimensions)
throws InterpreterException, NegativeArraySizeException {
Class clazz;
try {
/* get the base class (strip leading "[") */
clazz = TypeSignature.getClass(type.substring(dimensions.length));
} catch (ClassNotFoundException ex) {
throw new InterpreterException
("Class "+ex.getMessage()+" not found");
}
return Array.newInstance(clazz, dimensions);
}
public void enterMonitor(Object obj)
throws InterpreterException {
throw new InterpreterException("monitor not implemented");
}
public void exitMonitor(Object obj)
throws InterpreterException {
throw new InterpreterException("monitor not implemented");
}
}