Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Created on 10 nov 2009
- */
- package interpreter.api.util;
- import interpreter.api.ExecutionFrame;
- import interpreter.api.ExecutionThread;
- import interpreter.api.InterpreterProcess;
- import java.lang.reflect.Array;
- import java.util.ArrayList;
- import java.util.List;
- public class InterpreterTypeUtil
- {
- public static Class< ? > lookupClass(String classname)
- {
- classname = classname.replace('/', '.');
- try
- {
- return Class.forName(classname);
- }
- catch (Exception exc)
- {
- throw new IllegalStateException(exc);
- }
- }
- public static Object popValueFromStack(ExecutionFrame frame, Class< ? > type)
- {
- if (type.isPrimitive())
- {
- if (type == boolean.class)
- return Boolean.valueOf(frame.popInt() != 0);
- if (type == byte.class)
- return Byte.valueOf((byte) frame.popInt());
- if (type == short.class)
- return Short.valueOf((short) frame.popInt());
- if (type == char.class)
- return Character.valueOf((char) frame.popInt());
- if (type == int.class)
- return Integer.valueOf(frame.popInt());
- if (type == long.class)
- return Long.valueOf(frame.popLong());
- if (type == float.class)
- return Float.valueOf(frame.popFloat());
- if (type == double.class)
- return Double.valueOf(frame.popDouble());
- }
- else if (type.isArray())
- {
- throw new IllegalStateException();
- }
- int ref = frame.popReference();
- if (InterpreterProcess.isJavaReference(ref))
- return frame.thread.process.heap.lookupObject(ref);
- return Integer.valueOf(ref);
- }
- public static Object loadValueFromLocals(ExecutionFrame frame, int index, Class< ? > type)
- {
- if (type.isPrimitive())
- {
- if (type == boolean.class)
- return Boolean.valueOf(frame.loadInt(index) != 0);
- if (type == byte.class)
- return Byte.valueOf((byte) frame.loadInt(index));
- if (type == short.class)
- return Short.valueOf((short) frame.loadInt(index));
- if (type == char.class)
- return Character.valueOf((char) frame.loadInt(index));
- if (type == int.class)
- return Integer.valueOf(frame.loadInt(index));
- if (type == long.class)
- return Long.valueOf(frame.loadLong(index));
- if (type == float.class)
- return Float.valueOf(frame.loadFloat(index));
- if (type == double.class)
- return Double.valueOf(frame.loadDouble(index));
- }
- else if (type.isArray())
- {
- throw new IllegalStateException();
- }
- int ref = frame.loadReference(index);
- if (InterpreterProcess.isJavaReference(ref))
- return frame.thread.process.heap.lookupObject(ref);
- return Integer.valueOf(ref);
- }
- public static Object[] loadValuesFromLocals(ExecutionFrame frame, boolean isStatic, Class< ? >[] paramTypes)
- {
- Object[] args = new Object[paramTypes.length];
- for (int i = 0; i < args.length; i++)
- args[i] = loadValueFromLocals(frame, (isStatic ? 0 : 1) + i, paramTypes[i]);
- return args;
- }
- public static Object[] popValuesFromStack(ExecutionFrame frame, Class< ? >[] paramTypes)
- {
- Object[] args = new Object[paramTypes.length];
- for (int i = args.length - 1; i >= 0; i--)
- args[i] = popValueFromStack(frame, paramTypes[i]);
- return args;
- }
- public static boolean isNarrow(Class< ? > type)
- {
- return !(type == long.class || type == double.class);
- }
- public static void fromCallSiteStackToTargetLocal(ExecutionFrame frame, Class< ? >[] paramTypes, ExecutionFrame target, boolean isStatic)
- {
- for (int i = paramTypes.length - 1, t = (isStatic ? 0 : 1); i >= 0; i--, t++)
- {
- Class< ? > pt = paramTypes[i];
- if (isNarrow(pt))
- target.storeInt(t, frame.popInt());
- else
- target.storeLong(t, frame.popLong());
- }
- if (!isStatic)
- {
- int self = frame.popReference();
- if (InterpreterProcess.isJavaReference(self))
- {
- if (frame.thread.process.heap.lookupObject(self) == null)
- throw new NullPointerException();
- }
- target.storeReference(0, self);
- }
- }
- public static void pushTypedValueOnStack(ExecutionFrame frame, Class< ? > type, Object value)
- {
- if (type == void.class)
- {
- return;
- }
- if (value == null)
- {
- frame.pushReference(0);
- }
- else if (type.isPrimitive())
- {
- if (type == boolean.class)
- frame.pushInt(((Boolean) value).booleanValue() ? 1 : 0);
- else if (type == byte.class)
- frame.pushInt(((Byte) value).byteValue());
- else if (type == short.class)
- frame.pushInt(((Short) value).shortValue());
- else if (type == char.class)
- frame.pushInt(((Character) value).charValue());
- else if (type == int.class)
- frame.pushInt(((Integer) value).intValue());
- else if (type == long.class)
- frame.pushLong(((Long) value).longValue());
- else if (type == float.class)
- frame.pushFloat(((Float) value).floatValue());
- else if (type == double.class)
- frame.pushDouble(((Double) value).doubleValue());
- }
- else if (type.isArray())
- {
- throw new IllegalStateException();
- }
- else
- {
- int ref = ((Integer) value).intValue();
- if (InterpreterProcess.isJavaReference(ref))
- {
- frame.thread.process.heap.lookupObject(ref); // TODO
- }
- frame.pushReference(ref);
- }
- }
- public static void returnTypedValue(ExecutionThread stack, Class< ? > type)
- {
- if (type == void.class)
- {
- stack.vreturn();
- return;
- }
- if (type.isPrimitive())
- {
- if (isNarrow(type))
- stack.ireturn();
- else
- stack.lreturn();
- //if (type == boolean.class)
- // stack.ireturn();
- //else if (type == byte.class)
- // stack.ireturn();
- //else if (type == short.class)
- // stack.ireturn();
- // else if (type == char.class)
- // stack.ireturn();
- //else if (type == int.class)
- // stack.ireturn();
- //else if (type == long.class)
- // stack.lreturn();
- //else if (type == float.class)
- // stack.freturn();
- //else if (type == double.class)
- // stack.dreturn();
- }
- else if (type.isArray())
- {
- throw new IllegalStateException();
- }
- else
- {
- stack.areturn();
- }
- }
- // ------
- public static String typeToTightString(Class< ? > type)
- {
- if (type == void.class)
- return "V";
- if (type == boolean.class)
- return "Z";
- if (type == byte.class)
- return "B";
- if (type == short.class)
- return "S";
- if (type == char.class)
- return "C";
- if (type == int.class)
- return "I";
- if (type == long.class)
- return "J";
- if (type == float.class)
- return "F";
- if (type == double.class)
- return "D";
- return "L" + type.getName() + ";";
- }
- public static Class< ? > returnTypeStringToType(String returnType)
- {
- Class< ? >[] array = InterpreterTypeUtil.parameterTypeStringToTypes(returnType);
- if (array.length != 1)
- throw new IllegalStateException();
- return array[0];
- }
- public static Class< ? >[] parameterTypeStringToTypes(String parameters)
- {
- List<Class< ? >> params = new ArrayList<Class< ? >>();
- StringBuilder nameBuilder = null;
- int dim = 0;
- for (char c : parameters.toCharArray())
- {
- if (c == '[')
- {
- dim++;
- continue;
- }
- Class< ? > ptype = null;
- if (nameBuilder != null)
- {
- if (c != ';')
- {
- nameBuilder.append(c);
- continue;
- }
- ptype = lookupClass(nameBuilder.toString());
- nameBuilder = null;
- }
- if (ptype == null)
- {
- if (c == 'V')
- ptype = void.class;
- else if (c == 'Z')
- ptype = boolean.class;
- else if (c == 'B')
- ptype = byte.class;
- else if (c == 'S')
- ptype = short.class;
- else if (c == 'C')
- ptype = char.class;
- else if (c == 'I')
- ptype = int.class;
- else if (c == 'J')
- ptype = long.class;
- else if (c == 'F')
- ptype = float.class;
- else if (c == 'D')
- ptype = double.class;
- else if (c == 'L') // class type
- {
- if (nameBuilder != null)
- throw new IllegalStateException();
- nameBuilder = new StringBuilder();
- continue;
- }
- else
- {
- throw new IllegalStateException("c=" + c + ", p=" + parameters);
- }
- }
- for (int i = 0; i < dim; i++)
- ptype = Array.newInstance(ptype, 0).getClass();
- params.add(ptype);
- dim = 0;
- }
- if (dim != 0)
- throw new IllegalStateException();
- if (nameBuilder != null)
- throw new IllegalStateException();
- return params.toArray(new Class[params.size()]);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement