use of org.apache.bcel.generic.NEW in project jop by jop-devel.
the class CallStringReceiverTypes method transfer.
public ContextMap<CallString, Set<TypeMapping>> transfer(InstructionHandle stmt, FlowEdge edge, ContextMap<CallString, Set<TypeMapping>> input, Interpreter<CallString, Set<TypeMapping>> interpreter, Map<InstructionHandle, ContextMap<CallString, Set<TypeMapping>>> state) {
Context context = new Context(input.getContext());
Set<TypeMapping> in = input.get(context.callString);
ContextMap<CallString, Set<TypeMapping>> retval = new ContextMap<CallString, Set<TypeMapping>>(context, new LinkedHashMap<CallString, Set<TypeMapping>>());
Set<TypeMapping> result = new LinkedHashSet<TypeMapping>();
retval.put(context.callString, result);
Instruction instruction = stmt.getInstruction();
switch(instruction.getOpcode()) {
case Constants.NOP:
result = in;
retval.put(context.callString, result);
break;
case Constants.ACONST_NULL:
case Constants.ICONST_M1:
case Constants.ICONST_0:
case Constants.ICONST_1:
case Constants.ICONST_2:
case Constants.ICONST_3:
case Constants.ICONST_4:
case Constants.ICONST_5:
case Constants.BIPUSH:
case Constants.SIPUSH:
case Constants.FCONST_0:
case Constants.FCONST_1:
case Constants.FCONST_2:
case Constants.LCONST_0:
case Constants.LCONST_1:
case Constants.DCONST_0:
case Constants.DCONST_1:
case Constants.LDC2_W:
result = in;
retval.put(context.callString, result);
break;
case Constants.LDC:
case Constants.LDC_W:
{
LDC instr = (LDC) instruction;
result = new LinkedHashSet<TypeMapping>(in);
retval.put(context.callString, result);
Type type = instr.getType(context.constPool());
if (type.equals(Type.STRING)) {
result.add(new TypeMapping(context.stackPtr, type.toString()));
String value = type.toString() + ".value";
String name = "char[]";
name += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(value, name));
}
}
break;
case Constants.DUP:
{
for (TypeMapping m : in) {
result.add(m);
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr, m.type));
}
}
}
break;
case Constants.DUP_X1:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 2) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
result.add(new TypeMapping(context.stackPtr, m.type));
}
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
}
}
break;
case Constants.DUP_X2:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 3) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr - 3, m.type));
result.add(new TypeMapping(context.stackPtr, m.type));
}
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
if (m.stackLoc == context.stackPtr - 3) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
}
}
}
break;
case Constants.DUP2:
{
for (TypeMapping m : in) {
result.add(m);
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr, m.type));
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr + 1, m.type));
}
}
}
break;
case Constants.DUP2_X1:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 3) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr - 3, m.type));
result.add(new TypeMapping(context.stackPtr, m.type));
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
result.add(new TypeMapping(context.stackPtr + 1, m.type));
}
if (m.stackLoc == context.stackPtr - 3) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
}
}
break;
case Constants.DUP2_X2:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 3) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr - 4, m.type));
result.add(new TypeMapping(context.stackPtr, m.type));
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr - 3, m.type));
result.add(new TypeMapping(context.stackPtr + 1, m.type));
}
if (m.stackLoc == context.stackPtr - 4) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
}
if (m.stackLoc == context.stackPtr - 3) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
}
}
break;
case Constants.SWAP:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 2) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 2) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
}
}
}
break;
case Constants.POP:
filterSet(in, result, context.stackPtr - 1);
break;
case Constants.POP2:
filterSet(in, result, context.stackPtr - 2);
break;
case Constants.GETFIELD:
{
GETFIELD instr = (GETFIELD) instruction;
List<String> receivers = new LinkedList<String>();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 1) {
result.add(m);
} else if (m.stackLoc == context.stackPtr - 1) {
receivers.add(m.type);
}
}
// if (receivers.isEmpty()
// && instr.getFieldType(context.constPool) != Type.INT) {
// System.out.println("GETFIELD not found: "+context.method+"@"+stmt+": "+instr.getFieldName(context.constPool));
// // System.exit(1);
// }
DFATool p = interpreter.getDFATool();
String fieldName = instr.getFieldName(context.constPool());
for (String receiver : receivers) {
// String heapLoc = receiver + "." + instr.getFieldName(context.constPool);
// String namedLoc = receiver.split("@")[0] + "." + instr.getFieldName(context.constPool);
String className = receiver.split("@")[0];
ClassInfo classInfo = p.classForField(className, fieldName);
if (classInfo != null) {
String heapLoc = classInfo.getClassName() + "." + fieldName;
recordReceiver(stmt, context, heapLoc);
for (TypeMapping m : in) {
if (heapLoc.equals(m.heapLoc)) {
result.add(new TypeMapping(context.stackPtr - 1, m.type));
}
}
}
}
}
break;
case Constants.PUTFIELD:
{
PUTFIELD instr = (PUTFIELD) instruction;
List<String> receivers = new LinkedList<String>();
int fieldSize = instr.getFieldType(context.constPool()).getSize();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 1 - fieldSize) {
result.add(m);
} else if (m.stackLoc == context.stackPtr - 1 - fieldSize) {
receivers.add(m.type);
}
}
// if (receivers.isEmpty()) {
// System.out.println("PUTFIELD not found: "+context.method+"@"+stmt+": "+instr.getFieldName(context.constPool));
// // System.exit(-1);
// }
DFATool p = interpreter.getDFATool();
String fieldName = instr.getFieldName(context.constPool());
for (String receiver : receivers) {
// String heapLoc = receiver + "." + instr.getFieldName(context.constPool);
// String namedLoc = receiver.split("@")[0] + "." + instr.getFieldName(context.constPool);
String className = receiver.split("@")[0];
ClassInfo classInfo = p.classForField(className, fieldName);
if (classInfo != null) {
String heapLoc = classInfo.getClassName() + "." + fieldName;
recordReceiver(stmt, context, heapLoc);
for (TypeMapping m : in) {
if (!heapLoc.equals(m.heapLoc) || context.threaded) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(heapLoc, m.type));
}
}
}
}
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
doInvokeStatic("com.jopdesign.sys.JVM.f_putfield_ref(III)V", stmt, context, input, interpreter, state, retval);
}
}
break;
case Constants.GETSTATIC:
{
GETSTATIC instr = (GETSTATIC) instruction;
DFATool p = interpreter.getDFATool();
FieldRef ref = context.getMethodInfo().getCode().getFieldRef(instr);
String fieldName = ref.getName();
String className = ref.getClassName();
ClassInfo classInfo = p.classForField(className, fieldName);
if (classInfo != null) {
String heapLoc = classInfo.getClassName() + "." + fieldName;
recordReceiver(stmt, context, heapLoc);
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr) {
result.add(m);
}
if (heapLoc.equals(m.heapLoc)) {
result.add(new TypeMapping(context.stackPtr, m.type));
}
}
} else {
// System.out.println("GETSTATIC not found: "+heapLoc);
// System.exit(1);
}
}
break;
case Constants.PUTSTATIC:
{
PUTSTATIC instr = (PUTSTATIC) instruction;
DFATool p = interpreter.getDFATool();
FieldRef ref = context.getMethodInfo().getCode().getFieldRef(instr);
String fieldName = ref.getName();
String className = ref.getClassName();
ClassInfo classInfo = p.classForField(className, fieldName);
if (classInfo != null) {
String heapLoc = classInfo.getClassName() + "." + fieldName;
recordReceiver(stmt, context, heapLoc);
for (TypeMapping m : in) {
if (m.stackLoc >= 0 && m.stackLoc < context.stackPtr - 1) {
result.add(m);
} else if (m.stackLoc == -1 && (!heapLoc.equals(m.heapLoc) || context.threaded)) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(heapLoc, m.type));
}
}
} else {
// System.out.println("PUTSTATIC not found: "+heapLoc);
// System.exit(1);
}
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
doInvokeStatic("com.jopdesign.sys.JVM.f_putstatic_ref(II)V", stmt, context, input, interpreter, state, retval);
}
}
break;
case Constants.ARRAYLENGTH:
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 1) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
recordReceiver(stmt, context, m.type);
}
}
break;
case Constants.IASTORE:
case Constants.BASTORE:
case Constants.CASTORE:
case Constants.SASTORE:
case Constants.FASTORE:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 3) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 3) {
recordReceiver(stmt, context, m.type);
}
}
}
break;
case Constants.LASTORE:
case Constants.DASTORE:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 4) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 4) {
recordReceiver(stmt, context, m.type);
}
}
}
break;
case Constants.AASTORE:
{
List<String> receivers = new LinkedList<String>();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 3) {
result.add(m);
} else if (m.stackLoc == context.stackPtr - 3) {
receivers.add(m.type);
recordReceiver(stmt, context, m.type);
}
}
for (String healLoc : receivers) {
for (TypeMapping m : in) {
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(healLoc, m.type));
}
}
}
doInvokeStatic("com.jopdesign.sys.JVM.f_aastore(III)V", stmt, context, input, interpreter, state, retval);
}
break;
case Constants.IALOAD:
case Constants.BALOAD:
case Constants.CALOAD:
case Constants.SALOAD:
case Constants.FALOAD:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 2) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 2) {
recordReceiver(stmt, context, m.type);
}
}
}
break;
case Constants.LALOAD:
case Constants.DALOAD:
{
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 2) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 2) {
recordReceiver(stmt, context, m.type);
}
}
}
break;
case Constants.AALOAD:
{
List<String> receivers = new LinkedList<String>();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 2) {
result.add(m);
} else if (m.stackLoc == context.stackPtr - 2) {
receivers.add(m.type);
recordReceiver(stmt, context, m.type);
}
}
for (String heapLoc : receivers) {
for (TypeMapping m : in) {
if (heapLoc.equals(m.heapLoc)) {
result.add(new TypeMapping(context.stackPtr - 2, m.type));
}
}
}
}
break;
case Constants.NEW:
{
NEW instr = (NEW) instruction;
filterSet(in, result, context.stackPtr);
String name = instr.getType(context.constPool()).toString();
name += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(context.stackPtr, name));
doInvokeStatic("com.jopdesign.sys.JVM.f_" + stmt.getInstruction().getName() + "(I)I", stmt, context, input, interpreter, state, retval);
}
break;
case Constants.ANEWARRAY:
{
ANEWARRAY instr = (ANEWARRAY) instruction;
filterSet(in, result, context.stackPtr - 1);
String name = instr.getType(context.constPool()).toString() + "[]";
name += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(context.stackPtr - 1, name));
doInvokeStatic("com.jopdesign.sys.JVM.f_" + stmt.getInstruction().getName() + "(II)I", stmt, context, input, interpreter, state, retval);
}
break;
case Constants.NEWARRAY:
{
NEWARRAY instr = (NEWARRAY) instruction;
filterSet(in, result, context.stackPtr - 1);
String name = instr.getType().toString();
name += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(context.stackPtr - 1, name));
doInvokeStatic("com.jopdesign.sys.JVM.f_" + stmt.getInstruction().getName() + "(II)I", stmt, context, input, interpreter, state, retval);
}
break;
case Constants.MULTIANEWARRAY:
{
MULTIANEWARRAY instr = (MULTIANEWARRAY) instruction;
int dim = instr.getDimensions();
filterSet(in, result, context.stackPtr - dim);
String type = instr.getType(context.constPool()).toString();
type = type.substring(0, type.indexOf("["));
for (int i = 1; i <= dim; i++) {
String type1 = type;
String type2 = type;
for (int k = 0; k < i; k++) {
type1 += "[]";
}
for (int k = 0; k < i - 1; k++) {
type2 += "[]";
}
type1 += "@" + context.method() + ":" + stmt.getPosition();
type2 += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(type1, type2));
}
String name = instr.getType(context.constPool()).toString();
name += "@" + context.method() + ":" + stmt.getPosition();
result.add(new TypeMapping(context.stackPtr - dim, name));
doInvokeStatic("com.jopdesign.sys.JVM.f_" + stmt.getInstruction().getName() + "()I", stmt, context, input, interpreter, state, retval);
}
break;
case Constants.ILOAD_0:
case Constants.ILOAD_1:
case Constants.ILOAD_2:
case Constants.ILOAD_3:
case Constants.ILOAD:
case Constants.FLOAD_0:
case Constants.FLOAD_1:
case Constants.FLOAD_2:
case Constants.FLOAD_3:
case Constants.FLOAD:
case Constants.LLOAD_0:
case Constants.LLOAD_1:
case Constants.LLOAD_2:
case Constants.LLOAD_3:
case Constants.LLOAD:
case Constants.DLOAD_0:
case Constants.DLOAD_1:
case Constants.DLOAD_2:
case Constants.DLOAD_3:
case Constants.DLOAD:
result = in;
retval.put(context.callString, result);
break;
case Constants.ALOAD_0:
case Constants.ALOAD_1:
case Constants.ALOAD_2:
case Constants.ALOAD_3:
case Constants.ALOAD:
{
LoadInstruction instr = (LoadInstruction) instruction;
int index = instr.getIndex();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr) {
result.add(m);
}
if (m.stackLoc == index) {
result.add(new TypeMapping(context.stackPtr, m.type));
}
}
}
break;
case Constants.ISTORE_0:
case Constants.ISTORE_1:
case Constants.ISTORE_2:
case Constants.ISTORE_3:
case Constants.ISTORE:
case Constants.FSTORE_0:
case Constants.FSTORE_1:
case Constants.FSTORE_2:
case Constants.FSTORE_3:
case Constants.FSTORE:
case Constants.LSTORE_0:
case Constants.LSTORE_1:
case Constants.LSTORE_2:
case Constants.LSTORE_3:
case Constants.LSTORE:
case Constants.DSTORE_0:
case Constants.DSTORE_1:
case Constants.DSTORE_2:
case Constants.DSTORE_3:
case Constants.DSTORE:
result = in;
retval.put(context.callString, result);
break;
case Constants.ASTORE_0:
case Constants.ASTORE_1:
case Constants.ASTORE_2:
case Constants.ASTORE_3:
case Constants.ASTORE:
{
StoreInstruction instr = (StoreInstruction) instruction;
int index = instr.getIndex();
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 1 && m.stackLoc != index) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(index, m.type));
}
}
}
break;
case Constants.FCMPL:
case Constants.FCMPG:
case Constants.LCMP:
case Constants.DCMPL:
case Constants.DCMPG:
result = in;
retval.put(context.callString, result);
break;
case Constants.IFEQ:
case Constants.IFNE:
case Constants.IFLT:
case Constants.IFGE:
case Constants.IFGT:
case Constants.IFLE:
case Constants.IFNULL:
case Constants.IFNONNULL:
filterSet(in, result, context.stackPtr - 1);
break;
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPNE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
filterSet(in, result, context.stackPtr - 2);
break;
case Constants.TABLESWITCH:
case Constants.LOOKUPSWITCH:
filterSet(in, result, context.stackPtr - 1);
break;
case Constants.GOTO:
result = in;
retval.put(context.callString, result);
break;
case Constants.IADD:
case Constants.ISUB:
case Constants.IMUL:
case Constants.IDIV:
case Constants.IREM:
case Constants.ISHL:
case Constants.ISHR:
case Constants.IUSHR:
case Constants.IAND:
case Constants.IOR:
case Constants.IXOR:
case Constants.FADD:
case Constants.FSUB:
case Constants.FMUL:
case Constants.FDIV:
case Constants.FREM:
case Constants.DADD:
case Constants.DSUB:
case Constants.DMUL:
case Constants.DDIV:
case Constants.DREM:
case Constants.IINC:
case Constants.INEG:
case Constants.FNEG:
case Constants.LNEG:
case Constants.DNEG:
case Constants.LADD:
case Constants.LAND:
case Constants.LOR:
case Constants.LXOR:
case Constants.LSUB:
case Constants.LSHL:
case Constants.LSHR:
case Constants.LUSHR:
result = in;
retval.put(context.callString, result);
break;
case Constants.LMUL:
case Constants.LDIV:
case Constants.LREM:
result = new LinkedHashSet<TypeMapping>(in);
retval.put(context.callString, result);
doInvokeStatic("com.jopdesign.sys.JVM.f_" + stmt.getInstruction().getName() + "(JJ)J", stmt, context, input, interpreter, state, retval);
break;
case Constants.I2B:
case Constants.I2C:
case Constants.I2S:
case Constants.I2F:
case Constants.F2I:
case Constants.I2L:
case Constants.I2D:
case Constants.F2L:
case Constants.F2D:
case Constants.L2I:
case Constants.D2I:
case Constants.L2F:
case Constants.D2F:
case Constants.L2D:
case Constants.D2L:
result = in;
retval.put(context.callString, result);
break;
case Constants.INSTANCEOF:
filterSet(in, result, context.stackPtr - 1);
break;
case Constants.CHECKCAST:
{
DFATool p = interpreter.getDFATool();
CHECKCAST instr = (CHECKCAST) instruction;
for (TypeMapping m : in) {
if (m.stackLoc < context.stackPtr - 1) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
// check whether this class can possibly be cast
String constClassName = instr.getType(context.constPool()).toString();
ClassInfo staticClass = p.getAppInfo().getClassInfo(constClassName);
ClassInfo dynamicClass = p.getAppInfo().getClassInfo(m.type.split("@")[0]);
// System.out.println("CHECKCAST: "+context.callString.asList()+"/"+context.method+": "+stmt+": "+constClassName+" vs "+m.type);
if (dynamicClass.isSubclassOf(staticClass)) {
result.add(m);
// System.out.println("yay!");
}
}
}
}
break;
case Constants.MONITORENTER:
filterSet(in, result, context.stackPtr - 1);
context.syncLevel++;
break;
case Constants.MONITOREXIT:
filterSet(in, result, context.stackPtr - 1);
context.syncLevel--;
if (context.syncLevel < 0) {
System.err.println("Synchronization level mismatch.");
System.exit(-1);
}
break;
case Constants.INVOKEVIRTUAL:
case Constants.INVOKEINTERFACE:
{
InvokeInstruction instr = (InvokeInstruction) instruction;
int argSize = MethodHelper.getArgSize(instr, context.constPool());
DFATool p = interpreter.getDFATool();
MethodRef ref = context.getMethodInfo().getCode().getInvokeSite(stmt).getInvokeeRef();
ClassInfo constClass = ref.getClassInfo();
// find possible receiver types
List<String> receivers = new LinkedList<String>();
for (TypeMapping m : in) {
if (m.stackLoc == context.stackPtr - argSize) {
String clName = m.type.split("@")[0];
ClassInfo dynamicClass;
// check whether this class can possibly be a receiver
try {
dynamicClass = p.getAppInfo().getClassInfo(clName);
} catch (MissingClassError ex) {
logger.error("TRANSFER/" + instr + ": " + ex);
continue;
}
if ((instr instanceof INVOKEVIRTUAL && dynamicClass.isSubclassOf(constClass)) || (instr instanceof INVOKEINTERFACE && dynamicClass.isImplementationOf(constClass))) {
receivers.add(clName);
} else {
logger.debug(context.method() + ": class " + constClass + " is not a superclass of " + clName);
}
}
}
/* Get the actual set of invoked methods */
// ArrayList<MethodInfo> invokeCandidates = new ArrayList<MethodInfo>();
String signature = ref.getMethodSignature();
for (String receiver : receivers) {
// find receiving method
MethodInfo impl = p.getAppInfo().getMethodInfoInherited(receiver, signature);
if (impl == null) {
throw new AppInfoError("Could not find implementation for: " + receiver + "#" + signature);
}
doInvokeVirtual(receiver, impl, stmt, context, input, interpreter, state, retval);
}
// add relevant information to result
filterSet(in, result, context.stackPtr - argSize);
}
break;
case Constants.INVOKESTATIC:
case Constants.INVOKESPECIAL:
{
InvokeInstruction instr = (InvokeInstruction) instruction;
int argSize = MethodHelper.getArgSize(instr, context.constPool());
MethodRef ref = context.getMethodInfo().getCode().getInvokeSite(stmt).getInvokeeRef();
MethodInfo impl = ref.getMethodInfo();
if (impl == null) {
throw new AppInfoError("Cannot find implementation of " + ref);
} else if (impl.isPrivate() && !impl.isStatic()) {
doInvokeVirtual(ref.getClassName(), impl, stmt, context, input, interpreter, state, retval);
} else {
doInvokeStatic(impl.getMemberID().toString(), stmt, context, input, interpreter, state, retval);
}
// add relevant information to result
filterSet(in, result, context.stackPtr - argSize);
}
break;
case Constants.RETURN:
case Constants.IRETURN:
case Constants.FRETURN:
case Constants.LRETURN:
case Constants.DRETURN:
filterSet(in, result, 0);
break;
case Constants.ARETURN:
{
for (TypeMapping m : in) {
if (m.stackLoc < 0) {
result.add(m);
}
if (m.stackLoc == context.stackPtr - 1) {
result.add(new TypeMapping(0, m.type));
}
}
}
break;
default:
System.out.println("Unknown opcode: " + instruction.toString(context.constPool().getConstantPool()));
System.exit(-1);
}
// System.out.print(instruction+":\t{ ");
// for (Iterator k = result.iterator(); k.hasNext(); ) {
// ReceiverTypes.TypeMapping m = (ReceiverTypes.TypeMapping) k.next();
// if (m.stackLoc >= 0) {
// System.out.print("<stack[" + m.stackLoc + "], " + m.type +">, ");
// } else {
// System.out.print("<" + m.heapLoc + ", " + m.type +">, ");
// }
// }
// System.out.println("}");
// System.out.println("AFTER "+context.method+": "+stmt+" / "+context.callString.asList());
// System.out.print(stmt.getInstruction()+":\t{ ");
// System.out.print(context.callString.asList()+": "+retval.get(context.callString));
// System.out.println(" }");
context.stackPtr += instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
return retval;
}
use of org.apache.bcel.generic.NEW in project jop by jop-devel.
the class ValueMapAnalysis method transfer.
public void transfer(Instruction instruction) {
switch(instruction.getOpcode()) {
case Constants.NOP:
break;
case Constants.ACONST_NULL:
values.push(new ValueInfo(Type.NULL));
break;
case Constants.ICONST_M1:
case Constants.ICONST_0:
case Constants.ICONST_1:
case Constants.ICONST_2:
case Constants.ICONST_3:
case Constants.ICONST_4:
case Constants.ICONST_5:
case Constants.BIPUSH:
case Constants.SIPUSH:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
int value = instr.getValue().intValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantIntegerInfo(value)));
break;
}
case Constants.LCONST_0:
case Constants.LCONST_1:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
long value = instr.getValue().longValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantLongInfo(value)));
break;
}
case Constants.FCONST_0:
case Constants.FCONST_1:
case Constants.FCONST_2:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
float value = instr.getValue().floatValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantFloatInfo(value)));
break;
}
case Constants.DCONST_0:
case Constants.DCONST_1:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
double value = instr.getValue().doubleValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantDoubleInfo(value)));
break;
}
case Constants.LDC:
case Constants.LDC_W:
case Constants.LDC2_W:
{
CPInstruction instr = (CPInstruction) instruction;
values.push(new ValueInfo(methodInfo.getClassInfo().getConstantInfo(instr.getIndex())));
break;
}
case Constants.ISTORE_0:
case Constants.ISTORE_1:
case Constants.ISTORE_2:
case Constants.ISTORE_3:
case Constants.ISTORE:
case Constants.ASTORE_0:
case Constants.ASTORE_1:
case Constants.ASTORE_2:
case Constants.ASTORE_3:
case Constants.ASTORE:
case Constants.LSTORE_0:
case Constants.LSTORE_1:
case Constants.LSTORE_2:
case Constants.LSTORE_3:
case Constants.LSTORE:
case Constants.DSTORE_0:
case Constants.DSTORE_1:
case Constants.DSTORE_2:
case Constants.DSTORE_3:
case Constants.DSTORE:
case Constants.FSTORE_0:
case Constants.FSTORE_1:
case Constants.FSTORE_2:
case Constants.FSTORE_3:
case Constants.FSTORE:
{
StoreInstruction instr = (StoreInstruction) instruction;
int index = instr.getIndex();
values.setLocalValue(index, values.popValue());
break;
}
case Constants.ILOAD_0:
case Constants.ILOAD_1:
case Constants.ILOAD_2:
case Constants.ILOAD_3:
case Constants.ILOAD:
case Constants.LLOAD_0:
case Constants.LLOAD_1:
case Constants.LLOAD_2:
case Constants.LLOAD_3:
case Constants.LLOAD:
case Constants.FLOAD_0:
case Constants.FLOAD_1:
case Constants.FLOAD_2:
case Constants.FLOAD_3:
case Constants.FLOAD:
case Constants.DLOAD_0:
case Constants.DLOAD_1:
case Constants.DLOAD_2:
case Constants.DLOAD_3:
case Constants.DLOAD:
case Constants.ALOAD_0:
case Constants.ALOAD_1:
case Constants.ALOAD_2:
case Constants.ALOAD_3:
case Constants.ALOAD:
{
LoadInstruction instr = (LoadInstruction) instruction;
int index = instr.getIndex();
values.push(values.getLocalValue(index));
break;
}
case Constants.DUP:
values.push(values.top());
break;
case Constants.DUP_X1:
values.insert(2, values.top());
break;
case Constants.DUP_X2:
values.insert(3, values.top());
case Constants.DUP2:
values.push(values.top(1), false);
values.push(values.top(1), false);
break;
case Constants.DUP2_X1:
values.insert(3, values.top(1));
values.insert(3, values.top(0));
break;
case Constants.DUP2_X2:
values.insert(4, values.top(1));
values.insert(4, values.top(0));
break;
case Constants.POP:
values.pop();
break;
case Constants.POP2:
values.pop();
values.pop();
break;
case Constants.SWAP:
values.insert(1, values.pop());
break;
case Constants.IASTORE:
case Constants.LASTORE:
case Constants.FASTORE:
case Constants.DASTORE:
case Constants.CASTORE:
case Constants.SASTORE:
case Constants.BASTORE:
case Constants.AASTORE:
values.popValue();
values.pop();
values.pop();
break;
case Constants.IALOAD:
case Constants.LALOAD:
case Constants.FALOAD:
case Constants.DALOAD:
case Constants.CALOAD:
case Constants.SALOAD:
case Constants.BALOAD:
case Constants.AALOAD:
{
values.pop();
values.pop();
Type t = ((ArrayInstruction) instruction).getType(cpg);
values.push(new ValueInfo(t));
break;
}
case Constants.IINC:
{
int i = ((IINC) instruction).getIndex();
ValueInfo old = values.getLocalValue(i);
if (old.isConstantValue() && old.getConstantValue() instanceof ConstantIntegerInfo) {
ConstantIntegerInfo value = (ConstantIntegerInfo) old.getConstantValue();
int newval = value.getValue() + ((IINC) instruction).getIncrement();
values.setLocalValue(i, new ValueInfo(new ConstantIntegerInfo(newval)));
} else {
values.setLocalValue(i, new ValueInfo(Type.INT));
}
break;
}
case Constants.IADD:
case Constants.ISUB:
case Constants.IMUL:
case Constants.IDIV:
case Constants.IREM:
case Constants.IAND:
case Constants.IOR:
case Constants.IXOR:
case Constants.ISHL:
case Constants.ISHR:
case Constants.IUSHR:
values.pop();
case Constants.INEG:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.FADD:
case Constants.FSUB:
case Constants.FMUL:
case Constants.FDIV:
case Constants.FREM:
values.pop();
case Constants.FNEG:
values.pop();
values.push(new ValueInfo(Type.FLOAT));
break;
case Constants.LADD:
case Constants.LSUB:
case Constants.LMUL:
case Constants.LDIV:
case Constants.LREM:
case Constants.LAND:
case Constants.LOR:
case Constants.LXOR:
values.pop();
values.pop();
case Constants.LNEG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.LONG));
break;
case Constants.DADD:
case Constants.DSUB:
case Constants.DMUL:
case Constants.DDIV:
case Constants.DREM:
values.pop();
values.pop();
case Constants.DNEG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.DOUBLE));
break;
case Constants.LSHL:
case Constants.LSHR:
case Constants.LUSHR:
values.pop();
values.pop();
values.pop();
values.push(new ValueInfo(Type.LONG));
break;
case Constants.I2B:
case Constants.I2C:
case Constants.I2S:
case Constants.I2L:
case Constants.I2F:
case Constants.I2D:
case Constants.L2I:
case Constants.L2F:
case Constants.L2D:
case Constants.F2I:
case Constants.F2L:
case Constants.F2D:
case Constants.D2I:
case Constants.D2L:
case Constants.D2F:
{
values.popValue();
values.push(new ValueInfo(((ConversionInstruction) instruction).getType(cpg)));
break;
}
case Constants.LCMP:
case Constants.DCMPL:
case Constants.DCMPG:
values.pop();
values.pop();
case Constants.FCMPL:
case Constants.FCMPG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPNE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
values.pop();
case Constants.IFEQ:
case Constants.IFNE:
case Constants.IFLT:
case Constants.IFGE:
case Constants.IFLE:
case Constants.IFGT:
case Constants.IFNULL:
case Constants.IFNONNULL:
values.pop();
break;
case Constants.GOTO:
case Constants.RET:
break;
case Constants.JSR:
// This is of type 'returnAddress'
values.push(new ValueInfo(Type.INT));
break;
case Constants.ARETURN:
case Constants.IRETURN:
case Constants.LRETURN:
case Constants.FRETURN:
case Constants.DRETURN:
case Constants.RETURN:
values.clearStack();
break;
case Constants.LOOKUPSWITCH:
case Constants.TABLESWITCH:
values.pop();
break;
case Constants.GETFIELD:
values.pop();
case Constants.GETSTATIC:
{
FieldInstruction f = (FieldInstruction) instruction;
ConstantFieldInfo field = (ConstantFieldInfo) methodInfo.getClassInfo().getConstantInfo(f.getIndex());
values.push(new ValueInfo(f.getFieldType(cpg), field.getValue()));
break;
}
case Constants.PUTFIELD:
values.pop();
case Constants.PUTSTATIC:
{
FieldInstruction f = (FieldInstruction) instruction;
values.pop(f.getFieldType(cpg).getSize());
break;
}
case Constants.INVOKEVIRTUAL:
case Constants.INVOKEINTERFACE:
case Constants.INVOKESPECIAL:
values.pop();
case Constants.INVOKESTATIC:
{
InvokeInstruction invoke = (InvokeInstruction) instruction;
values.pop(TypeHelper.getNumSlots(invoke.getArgumentTypes(cpg)));
values.push(new ValueInfo(invoke.getReturnType(cpg)));
break;
}
case Constants.MONITORENTER:
case Constants.MONITOREXIT:
values.pop();
break;
case Constants.ATHROW:
ValueInfo ref = values.pop();
values.clearStack();
values.push(ref);
break;
case Constants.CHECKCAST:
break;
case Constants.INSTANCEOF:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.NEW:
values.push(new ValueInfo(((NEW) instruction).getType(cpg)));
break;
case Constants.NEWARRAY:
{
Type t = ((NEWARRAY) instruction).getType();
values.push(new ValueInfo(new ArrayType(t, 1)));
break;
}
case Constants.ANEWARRAY:
{
Type t = ((ANEWARRAY) instruction).getType(cpg);
values.push(new ValueInfo(new ArrayType(t, 1)));
break;
}
case Constants.MULTIANEWARRAY:
{
MULTIANEWARRAY instr = (MULTIANEWARRAY) instruction;
values.pop(instr.getDimensions());
values.push(new ValueInfo(new ArrayType(instr.getType(cpg), instr.getDimensions())));
break;
}
case Constants.ARRAYLENGTH:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
default:
throw new AppInfoError("Instruction not supported: " + instruction);
}
}
use of org.apache.bcel.generic.NEW in project servicemix-bundles by apache.
the class FunctionCall method translate.
/**
* Translate a function call. The compiled code will leave the function's
* return value on the JVM's stack.
*/
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
final int n = argumentCount();
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
final boolean isSecureProcessing = classGen.getParser().getXSLTC().isSecureProcessing();
int index;
// Translate calls to methods in the BasisLibrary
if (isStandard() || isExtension()) {
for (int i = 0; i < n; i++) {
final Expression exp = argument(i);
exp.translate(classGen, methodGen);
exp.startIterator(classGen, methodGen);
}
// append "F" to the function's name
final String name = _fname.toString().replace('-', '_') + "F";
String args = Constants.EMPTYSTRING;
// Special precautions for some method calls
if (name.equals("sumF")) {
args = DOM_INTF_SIG;
il.append(methodGen.loadDOM());
} else if (name.equals("normalize_spaceF")) {
if (_chosenMethodType.toSignature(args).equals("()Ljava/lang/String;")) {
args = "I" + DOM_INTF_SIG;
il.append(methodGen.loadContextNode());
il.append(methodGen.loadDOM());
}
}
// Invoke the method in the basis library
index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name, _chosenMethodType.toSignature(args));
il.append(new INVOKESTATIC(index));
} else // run-time error message for unsupported external functions
if (unresolvedExternal) {
index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "unresolved_externalF", "(Ljava/lang/String;)V");
il.append(new PUSH(cpg, _fname.toString()));
il.append(new INVOKESTATIC(index));
} else if (_isExtConstructor) {
if (isSecureProcessing)
translateUnallowedExtension(cpg, il);
final String clazz = _chosenConstructor.getDeclaringClass().getName();
Class[] paramTypes = _chosenConstructor.getParameterTypes();
LocalVariableGen[] paramTemp = new LocalVariableGen[n];
for (int i = 0; i < n; i++) {
final Expression exp = argument(i);
Type expType = exp.getType();
exp.translate(classGen, methodGen);
// Convert the argument to its Java type
exp.startIterator(classGen, methodGen);
expType.translateTo(classGen, methodGen, paramTypes[i]);
paramTemp[i] = methodGen.addLocalVariable("function_call_tmp" + i, expType.toJCType(), null, null);
paramTemp[i].setStart(il.append(expType.STORE(paramTemp[i].getIndex())));
}
il.append(new NEW(cpg.addClass(_className)));
il.append(InstructionConstants.DUP);
for (int i = 0; i < n; i++) {
final Expression arg = argument(i);
paramTemp[i].setEnd(il.append(arg.getType().LOAD(paramTemp[i].getIndex())));
}
final StringBuffer buffer = new StringBuffer();
buffer.append('(');
for (int i = 0; i < paramTypes.length; i++) {
buffer.append(getSignature(paramTypes[i]));
}
buffer.append(')');
buffer.append("V");
index = cpg.addMethodref(clazz, "<init>", buffer.toString());
il.append(new INVOKESPECIAL(index));
// Convert the return type back to our internal type
(Type.Object).translateFrom(classGen, methodGen, _chosenConstructor.getDeclaringClass());
} else // Invoke function calls that are handled in separate classes
{
if (isSecureProcessing)
translateUnallowedExtension(cpg, il);
final String clazz = _chosenMethod.getDeclaringClass().getName();
Class[] paramTypes = _chosenMethod.getParameterTypes();
// Push "this" if it is an instance method
if (_thisArgument != null) {
_thisArgument.translate(classGen, methodGen);
}
for (int i = 0; i < n; i++) {
final Expression exp = argument(i);
exp.translate(classGen, methodGen);
// Convert the argument to its Java type
exp.startIterator(classGen, methodGen);
exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
}
final StringBuffer buffer = new StringBuffer();
buffer.append('(');
for (int i = 0; i < paramTypes.length; i++) {
buffer.append(getSignature(paramTypes[i]));
}
buffer.append(')');
buffer.append(getSignature(_chosenMethod.getReturnType()));
if (_thisArgument != null && _clazz.isInterface()) {
index = cpg.addInterfaceMethodref(clazz, _fname.getLocalPart(), buffer.toString());
il.append(new INVOKEINTERFACE(index, n + 1));
} else {
index = cpg.addMethodref(clazz, _fname.getLocalPart(), buffer.toString());
il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) : (InvokeInstruction) new INVOKESTATIC(index));
}
// Convert the return type back to our internal type
_type.translateFrom(classGen, methodGen, _chosenMethod.getReturnType());
}
}
use of org.apache.bcel.generic.NEW in project jop by jop-devel.
the class AllocationWcetModel method getExecutionTime.
public long getExecutionTime(ExecutionContext context, InstructionHandle ih) {
int opcode = ih.getInstruction().getOpcode();
MethodInfo mCtx = context.getMethodInfo();
if (opcode == Constants.NEW) {
NEW insn = (NEW) ih.getInstruction();
ObjectType type = insn.getLoadClassType(mCtx.getConstantPoolGen());
return computeObjectSize(getFieldSize(getObjectFields(type.getClassName())));
} else if (opcode == Constants.NEWARRAY || opcode == Constants.ANEWARRAY) {
int typeSize = 1;
if (ih.getInstruction() instanceof NEWARRAY) {
NEWARRAY insn = (NEWARRAY) ih.getInstruction();
if (insn.getTypecode() == Constants.T_DOUBLE || insn.getTypecode() == Constants.T_LONG) {
typeSize = 2;
}
}
return computeArraySize(getArrayBound(context, ih, 0) * typeSize);
} else if (opcode == Constants.MULTIANEWARRAY) {
MULTIANEWARRAY insn = (MULTIANEWARRAY) ih.getInstruction();
int dim = insn.getDimensions();
long count = 1;
long size = 0;
for (int i = dim - 1; i >= 0; i--) {
long bound = getArrayBound(context, ih, i);
size += count * computeArraySize(bound);
count *= bound;
}
return size;
} else {
return 0;
}
}
Aggregations