Search in sources :

Example 1 with InvokeInstruction

use of org.apache.bcel.generic.InvokeInstruction in project jop by jop-devel.

the class SymbolicPointsTo method transfer.

public ContextMap<CallString, SymbolicAddressMap> transfer(InstructionHandle stmt, FlowEdge edge, ContextMap<CallString, SymbolicAddressMap> input, Interpreter<CallString, SymbolicAddressMap> interpreter, Map<InstructionHandle, ContextMap<CallString, SymbolicAddressMap>> state) {
    Context context = new Context(input.getContext());
    if (DEBUG_PRINT) {
        System.out.println("[S] " + context.callString.toStringList() + ": " + context.method() + " / " + stmt);
    }
    SymbolicAddressMap in = input.get(context.callString);
    ContextMap<CallString, SymbolicAddressMap> retval = new ContextMap<CallString, SymbolicAddressMap>(context, input);
    Instruction instruction = stmt.getInstruction();
    int newStackPtr = context.stackPtr + instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
    int opcode = instruction.getOpcode();
    switch(opcode) {
        /* Constants (boring) */
        case Constants.DCONST_0:
        case Constants.DCONST_1:
        case Constants.LCONST_0:
        case Constants.LCONST_1:
        /* Instructions above need two stack slots */
        case Constants.FCONST_0:
        case Constants.FCONST_1:
        case Constants.FCONST_2:
        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:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.ACONST_NULL:
            {
                // Null -> No reference
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.putStack(newStackPtr - 1, bsFactory.empty());
                retval.put(context.callString, result);
            }
            break;
        /* Long/Double Constants */
        case Constants.LDC2_W:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Int/Float/String Constants */
        case Constants.LDC:
        case Constants.LDC_W:
            {
                LDC ldc = (LDC) instruction;
                Type t = ldc.getType(context.constPool());
                if (t instanceof ReferenceType) {
                    SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                    /* FIXME: This is overly conservative, but class pointer not available here */
                    String classContext = context.getMethodInfo().getMemberID().toString();
                    SymbolicAddress addr = SymbolicAddress.stringLiteral(classContext, ldc.getIndex());
                    result.putStack(newStackPtr - 1, bsFactory.singleton(addr));
                    retval.put(context.callString, result);
                } else {
                    retval.put(context.callString, in.cloneFilterStack(newStackPtr));
                }
            }
            break;
        case Constants.DSTORE:
        case Constants.DSTORE_0:
        case Constants.DSTORE_1:
        case Constants.DSTORE_2:
        case Constants.DSTORE_3:
        case Constants.LSTORE:
        case Constants.LSTORE_0:
        case Constants.LSTORE_1:
        case Constants.LSTORE_2:
        case Constants.LSTORE_3:
        case Constants.FSTORE:
        case Constants.FSTORE_0:
        case Constants.FSTORE_1:
        case Constants.FSTORE_2:
        case Constants.FSTORE_3:
        case Constants.ISTORE_0:
        case Constants.ISTORE_1:
        case Constants.ISTORE_2:
        case Constants.ISTORE_3:
        case Constants.ISTORE:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // 
        case Constants.ASTORE_0:
        case Constants.ASTORE_1:
        case Constants.ASTORE_2:
        case Constants.ASTORE_3:
        case Constants.ASTORE:
            {
                // copy value to local variable
                StoreInstruction instr = (StoreInstruction) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (DEBUG_PRINT) {
                    System.out.println(String.format("[DD] Copy: stack[%d] <- stack[%d]", instr.getIndex(), context.stackPtr - 1));
                }
                result.copyStack(in, instr.getIndex(), context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        /* Load variables (boring) */
        case Constants.DLOAD_0:
        case Constants.DLOAD_1:
        case Constants.DLOAD_2:
        case Constants.DLOAD_3:
        case Constants.DLOAD:
        case Constants.LLOAD_0:
        case Constants.LLOAD_1:
        case Constants.LLOAD_2:
        case Constants.LLOAD_3:
        case Constants.LLOAD:
        /* Instructions above need two stack slots */
        case Constants.FLOAD_0:
        case Constants.FLOAD_1:
        case Constants.FLOAD_2:
        case Constants.FLOAD_3:
        case Constants.FLOAD:
        case Constants.ILOAD_0:
        case Constants.ILOAD_1:
        case Constants.ILOAD_2:
        case Constants.ILOAD_3:
        case Constants.ILOAD:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Floating Point Comparison (boring) */
        case Constants.DCMPG:
        case Constants.DCMPL:
        case Constants.LCMP:
        /* Instructions above need two stack slots */
        case Constants.FCMPG:
        case Constants.FCMPL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.ALOAD_0:
        case Constants.ALOAD_1:
        case Constants.ALOAD_2:
        case Constants.ALOAD_3:
        case Constants.ALOAD:
            {
                LoadInstruction instr = (LoadInstruction) instruction;
                // copy value from local variable
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.copyStack(in, context.stackPtr, instr.getIndex());
                retval.put(context.callString, result);
            }
            break;
        // Access Object Handle (area), top of stack
        case Constants.ARRAYLENGTH:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // Access Object Handle, second on stack
        case Constants.PUTFIELD:
            {
                PUTFIELD instr = (PUTFIELD) instruction;
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1 - instr.getType(context.constPool()).getSize()));
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                // Change alias information
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    String ty = instr.getFieldType(context.constPool()).getSignature();
                    result.addAlias(ty, in.getStack(context.stackPtr - 1));
                }
                retval.put(context.callString, result);
            }
            break;
        // Access Object Handle, top of stack
        case Constants.GETFIELD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
                GETFIELD instr = (GETFIELD) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    BoundedSet<SymbolicAddress> newMapping = SymbolicAddress.fieldAccess(bsFactory, in.getStack(context.stackPtr - 1), instr.getFieldName(context.constPool()));
                    newMapping.addAll(in.getAliases(instr.getFieldType(context.constPool()).getSignature()));
                    result.putStack(context.stackPtr - 1, newMapping);
                }
                retval.put(context.callString, result);
            }
            break;
        // Handles the same way as MOV
        case Constants.PUTSTATIC:
            {
                PUTSTATIC instr = (PUTSTATIC) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    BoundedSet<SymbolicAddress> pointers = in.getStack(context.stackPtr - 1);
                    result.putHeap(fieldSignature(context, instr), pointers);
                }
                retval.put(context.callString, result);
            }
            break;
        // Handled the same as MOV
        case Constants.GETSTATIC:
            {
                GETSTATIC instr = (GETSTATIC) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    result.putStack(context.stackPtr, in.getHeap(fieldSignature(context, instr)));
                }
                retval.put(context.callString, result);
            }
            break;
        case Constants.LASTORE:
        case Constants.DASTORE:
        case Constants.IASTORE:
        case Constants.FASTORE:
        case Constants.CASTORE:
        case Constants.SASTORE:
        case Constants.BASTORE:
            {
                int offset = 3;
                if (opcode == Constants.LASTORE || opcode == Constants.DASTORE)
                    offset = 4;
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - offset));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // changing the heap -> TOP
        case Constants.AASTORE:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 3));
                AASTORE instr = (AASTORE) stmt.getInstruction();
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                // Change alias information
                if (instr.getType(context.constPool()) instanceof ReferenceType) {
                    String ty = instr.getType(context.constPool()).getSignature();
                    result.addAlias(ty, in.getStack(context.stackPtr - 1));
                }
                retval.put(context.callString, result);
            }
            break;
        case Constants.DALOAD:
        case Constants.LALOAD:
        case Constants.IALOAD:
        case Constants.FALOAD:
        case Constants.CALOAD:
        case Constants.SALOAD:
        case Constants.BALOAD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // TODO: Use index info
        case Constants.AALOAD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
                //AALOAD instr = (AALOAD)instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                BoundedSet<SymbolicAddress> objectMapping = in.getStack(context.stackPtr - 2);
                BoundedSet<SymbolicAddress> newMapping;
                LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
                if (executedOnce.query(stmt)) {
                    newMapping = bsFactory.singleton(SymbolicAddress.newName());
                } else if (objectMapping.isSaturated() || bounds == null) {
                    newMapping = bsFactory.top();
                } else {
                    Interval interval = bounds.getArrayIndices(stmt, context.callString);
                    if (interval.hasLb() && interval.hasUb()) {
                        newMapping = bsFactory.empty();
                        for (SymbolicAddress addr : objectMapping.getSet()) {
                            for (int i = interval.getLb(); i <= interval.getUb(); i++) {
                                newMapping.add(addr.accessArray(i));
                            }
                        }
                    } else {
                        newMapping = bsFactory.top();
                    }
                }
                //				Doesn't work, but is probably stupid anyway :(
                //  			LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
                //              bounds.getArraySizes().get(stmt).get(context.callString);
                //			    newMapping = bsFactory.empty();
                //				Interval[] sizeBounds = { new Interval(2,3) }; 
                //				for(Interval i : sizeBounds) {
                //					if(! i.hasUb()) {
                //						newMapping = bsFactory.top();
                //					}
                //					int ub = i.getUb();
                //					for(int j = 0; j <= ub; j++) {
                //						for(SymbolicAddress addr: objectMapping.getSet()) {
                //							newMapping.add(addr.accessArray(j));
                //						}					
                //					}
                //				}
                //			}
                result.putStack(context.stackPtr - 2, newMapping);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP_X1:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 2);
                result.copyStack(in, context.stackPtr - 2, context.stackPtr - 1);
                result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP_X2:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 3);
                result.copyStack(in, context.stackPtr - 3, context.stackPtr - 1);
                result.copyStack(in, context.stackPtr - 2, context.stackPtr - 3);
                result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP2:
            {
                // v1,v2 -> v1,v2,v1,v2
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr);
                result.copyStack(in, context.stackPtr, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr + 1, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.POP:
        case Constants.POP2:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IINC:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IADD:
        case Constants.ISUB:
        case Constants.INEG:
        case Constants.IUSHR:
        case Constants.ISHR:
        case Constants.IAND:
        case Constants.IOR:
        case Constants.IXOR:
        case Constants.IMUL:
        case Constants.IDIV:
        case Constants.IREM:
        case Constants.ISHL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Long,Float and Double operations (boring) */
        case Constants.DADD:
        case Constants.DSUB:
        case Constants.DMUL:
        case Constants.DDIV:
        case Constants.DREM:
        case Constants.LADD:
        case Constants.LSUB:
        case Constants.LUSHR:
        case Constants.LSHR:
        case Constants.LAND:
        case Constants.LOR:
        case Constants.LXOR:
        case Constants.LMUL:
        case Constants.LDIV:
        case Constants.LREM:
        case Constants.LSHL:
        /* Instructions above need two stack slots */
        case Constants.DNEG:
        case Constants.LNEG:
        case Constants.FADD:
        case Constants.FSUB:
        case Constants.FNEG:
        case Constants.FMUL:
        case Constants.FDIV:
        case Constants.FREM:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Conversion of primitives (boring) */
        case Constants.D2F:
        case Constants.D2I:
        /* Instructions above need two stack slots */
        case Constants.D2L:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.L2F:
        case Constants.L2I:
        /* Instructions above need two stack slots */
        case Constants.L2D:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.F2D:
        case Constants.I2D:
        case Constants.F2L:
        case Constants.I2L:
        /* Instructions above need one stack slot less */
        case Constants.F2I:
        case Constants.I2B:
        case Constants.I2C:
        case Constants.I2F:
        case Constants.I2S:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.MONITORENTER:
            // not supported yet
            if (ASSUME_NO_CONC)
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            else
                retval.put(context.callString, SymbolicAddressMap.top());
            break;
        case Constants.MONITOREXIT:
            // not supported yet
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.CHECKCAST:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.INSTANCEOF:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.NEW:
        case Constants.NEWARRAY:
        case Constants.ANEWARRAY:
            {
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                BoundedSet<SymbolicAddress> newMapping;
                if (executedOnce.query(stmt)) {
                    newMapping = bsFactory.singleton(SymbolicAddress.newName());
                } else {
                    newMapping = bsFactory.top();
                }
                int objPtr = (instruction.getOpcode() == Constants.NEW) ? context.stackPtr : (context.stackPtr - 1);
                result.putStack(objPtr, newMapping);
                retval.put(context.callString, result);
            }
            break;
        case Constants.MULTIANEWARRAY:
            {
                // not supported yet
                retval.put(context.callString, SymbolicAddressMap.top());
            }
            break;
        case Constants.GOTO:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.IFNULL:
        case Constants.IFNONNULL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IF_ACMPEQ:
        case Constants.IF_ACMPNE:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IFEQ:
        case Constants.IFNE:
        case Constants.IFLT:
        case Constants.IFGE:
        case Constants.IFLE:
        case Constants.IFGT:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            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:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.LOOKUPSWITCH:
        case Constants.TABLESWITCH:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.INVOKEVIRTUAL:
        case Constants.INVOKEINTERFACE:
        case Constants.INVOKESTATIC:
        case Constants.INVOKESPECIAL:
            {
                DFATool p = interpreter.getDFATool();
                Set<String> receivers = p.getReceivers(stmt, context.callString);
                retval.put(context.callString, new SymbolicAddressMap(bsFactory));
                if (receivers == null || receivers.size() == 0) {
                    String errMsg = String.format("%s : invoke %s: %s receivers", context.method(), instruction.toString(context.constPool().getConstantPool()), (receivers == null ? "Unknown" : "No"));
                    // Get static receivers (FIXME: this just workarounds DFA bugs)
                    if (opcode == Constants.INVOKESTATIC) {
                        receivers = new HashSet<String>();
                        InvokeInstruction invInstruction = (InvokeInstruction) instruction;
                        String klass = invInstruction.getClassName(context.constPool());
                        String name = invInstruction.getMethodName(context.constPool());
                        String sig = invInstruction.getSignature(context.constPool());
                        String recv = klass + "." + name + sig;
                        Logger.getLogger(this.getClass()).info("Using static receiver: " + recv);
                        receivers.add(recv);
                    } else {
                        Logger.getLogger(this.getClass()).error(errMsg);
                        throw new AssertionError(errMsg);
                    }
                }
                if (instruction.getOpcode() == Constants.INVOKEVIRTUAL || instruction.getOpcode() == Constants.INVOKEINTERFACE) {
                    MethodInfo mi = p.getMethod(receivers.iterator().next());
                    int refPos = MethodHelper.getArgSize(mi);
                    //						mi.methodId,refPos,context.stackPtr,input.get(context.callString)));
                    try {
                        putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - refPos));
                    } catch (Error e) {
                        System.err.println("We have problems with method " + mi);
                        System.err.println(e.getMessage());
                    }
                }
                for (String methodName : receivers) {
                    doInvoke(methodName, stmt, context, input, interpreter, state, retval);
                }
            }
            break;
        case Constants.ARETURN:
            {
                SymbolicAddressMap result = in.cloneFilterStack(0);
                // store results
                result.copyStack(in, 0, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        /* The values of other return statements are not of interest here */
        case Constants.DRETURN:
        case Constants.LRETURN:
        case Constants.FRETURN:
        case Constants.IRETURN:
        case Constants.RETURN:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        default:
            System.err.println("unknown instruction: " + stmt + " in method " + context.method());
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
    }
    // DEBUGGING
    if (DEBUG_PRINT) {
        System.out.println("[F] " + context.method() + " / " + stmt);
        System.out.println("  Stackptr: " + context.stackPtr + " -> " + newStackPtr);
        System.out.println("  Before: ");
        input.get(context.callString).print(System.out, 4);
        System.out.println("  After: ");
        retval.get(context.callString).print(System.out, 4);
    }
    context.stackPtr = newStackPtr;
    return retval;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) LDC(org.apache.bcel.generic.LDC) CallString(com.jopdesign.common.code.CallString) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ArrayInstruction(org.apache.bcel.generic.ArrayInstruction) LoadInstruction(org.apache.bcel.generic.LoadInstruction) StoreInstruction(org.apache.bcel.generic.StoreInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) PUTSTATIC(org.apache.bcel.generic.PUTSTATIC) LoadInstruction(org.apache.bcel.generic.LoadInstruction) HashSet(java.util.HashSet) Context(com.jopdesign.dfa.framework.Context) DFATool(com.jopdesign.dfa.DFATool) PUTFIELD(org.apache.bcel.generic.PUTFIELD) AppInfoError(com.jopdesign.common.misc.AppInfoError) ContextMap(com.jopdesign.dfa.framework.ContextMap) CallString(com.jopdesign.common.code.CallString) GETFIELD(org.apache.bcel.generic.GETFIELD) BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) AASTORE(org.apache.bcel.generic.AASTORE) MethodInfo(com.jopdesign.common.MethodInfo) GETSTATIC(org.apache.bcel.generic.GETSTATIC) StoreInstruction(org.apache.bcel.generic.StoreInstruction)

Example 2 with InvokeInstruction

use of org.apache.bcel.generic.InvokeInstruction 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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) NEW(org.apache.bcel.generic.NEW) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) MULTIANEWARRAY(org.apache.bcel.generic.MULTIANEWARRAY) ANEWARRAY(org.apache.bcel.generic.ANEWARRAY) CHECKCAST(org.apache.bcel.generic.CHECKCAST) LDC(org.apache.bcel.generic.LDC) CallString(com.jopdesign.common.code.CallString) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) LoadInstruction(org.apache.bcel.generic.LoadInstruction) StoreInstruction(org.apache.bcel.generic.StoreInstruction) Instruction(org.apache.bcel.generic.Instruction) ReferenceType(org.apache.bcel.generic.ReferenceType) AppInfoError(com.jopdesign.common.misc.AppInfoError) PUTSTATIC(org.apache.bcel.generic.PUTSTATIC) LoadInstruction(org.apache.bcel.generic.LoadInstruction) MethodRef(com.jopdesign.common.type.MethodRef) LinkedList(java.util.LinkedList) List(java.util.List) MissingClassError(com.jopdesign.common.misc.MissingClassError) Context(com.jopdesign.dfa.framework.Context) MULTIANEWARRAY(org.apache.bcel.generic.MULTIANEWARRAY) ANEWARRAY(org.apache.bcel.generic.ANEWARRAY) NEWARRAY(org.apache.bcel.generic.NEWARRAY) DFATool(com.jopdesign.dfa.DFATool) FieldRef(com.jopdesign.common.type.FieldRef) PUTFIELD(org.apache.bcel.generic.PUTFIELD) MULTIANEWARRAY(org.apache.bcel.generic.MULTIANEWARRAY) ContextMap(com.jopdesign.dfa.framework.ContextMap) CallString(com.jopdesign.common.code.CallString) GETFIELD(org.apache.bcel.generic.GETFIELD) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) INVOKEINTERFACE(org.apache.bcel.generic.INVOKEINTERFACE) MethodInfo(com.jopdesign.common.MethodInfo) GETSTATIC(org.apache.bcel.generic.GETSTATIC) StoreInstruction(org.apache.bcel.generic.StoreInstruction) INVOKEVIRTUAL(org.apache.bcel.generic.INVOKEVIRTUAL) ClassInfo(com.jopdesign.common.ClassInfo)

Example 3 with InvokeInstruction

use of org.apache.bcel.generic.InvokeInstruction in project jop by jop-devel.

the class InlineHelper method checkCode.

/**
     * check the code of the invoked method if it contains instructions which prevent inlining.
     *
     * @param invoker the method into which the invokee will be inlined.
     * @param invokee the invoked method.
     * @return true if the code can be inlined and {@link #prepareInlining(MethodInfo, MethodInfo)} will succeed.
     */
private boolean checkCode(MethodInfo invoker, MethodInfo invokee) {
    MethodCode code = invokee.getCode();
    // Go through code, check for access to fields and invocations
    for (InstructionHandle ih : code.getInstructionList(true, false).getInstructionHandles()) {
        Instruction instr = ih.getInstruction();
        if (instr instanceof InvokeInstruction) {
            InvokeSite invokeSite = code.getInvokeSite(ih);
            MethodRef ref = invokeSite.getInvokeeRef();
            MethodInfo method = ref.getMethodInfo();
            if (method == null) {
                // TODO perform basic check on classnames if invoked method must already be public?
                return false;
            }
            // invokespecial is somewhat, well, special..
            if (invokeSite.isInvokeSpecial()) {
                if (checkInvokeSpecial(invoker, invokee, invokeSite, ref.getClassInfo(), method) == CheckResult.SKIP) {
                    return false;
                }
            } else {
                // check if fields need to be set to public
                if (checkNeedsPublic(invoker, invokee, ref.getClassInfo(), method) == CheckResult.SKIP) {
                    return false;
                }
            }
        } else if (instr instanceof FieldInstruction) {
            FieldRef ref = code.getFieldRef(ih);
            FieldInfo field = ref.getFieldInfo();
            if (field == null) {
                // TODO perform basic check on classnames if field is already public?
                return false;
            }
            // check if fields need to be set to public
            if (checkNeedsPublic(invoker, invokee, ref.getClassInfo(), field) == CheckResult.SKIP) {
                return false;
            }
        }
    }
    return true;
}
Also used : InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) MethodRef(com.jopdesign.common.type.MethodRef) FieldRef(com.jopdesign.common.type.FieldRef) MethodInfo(com.jopdesign.common.MethodInfo) InvokeSite(com.jopdesign.common.code.InvokeSite) FieldInstruction(org.apache.bcel.generic.FieldInstruction) MethodCode(com.jopdesign.common.MethodCode) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ConstantPushInstruction(org.apache.bcel.generic.ConstantPushInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) LocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) FieldInfo(com.jopdesign.common.FieldInfo)

Example 4 with InvokeInstruction

use of org.apache.bcel.generic.InvokeInstruction in project jop by jop-devel.

the class InlineHelper method prepareInlining.

/**
     * Prepare the invokee for inlining into the invokesite, by widening access restrictions or renaming
     * methods to prevent incorrect method resolving.
     * <p>
     * This may change the code of the invokee, so this needs to be done before inlining the code.
     * The CFG of the invokee will be removed.
     * </p><p>
     * This code assumes that {@link #canInline(CallString, InvokeSite, MethodInfo)} returned true for this invoke.
     * </p>
     *
     * @param invoker the method where the code will be inlined to.
     * @param invokee the method to inline.
     */
public void prepareInlining(MethodInfo invoker, MethodInfo invokee) {
    MethodCode code = invokee.getCode();
    InstructionList il = code.getInstructionList();
    for (InstructionHandle ih : il.getInstructionHandles()) {
        Instruction instr = ih.getInstruction();
        if (instr instanceof InvokeInstruction) {
            InvokeSite invokeSite = code.getInvokeSite(ih);
            MethodRef ref = invokeSite.getInvokeeRef();
            MethodInfo method = ref.getMethodInfo();
            // we already checked that everything can be resolved
            // nothing special to do for invokespecial here (checkInvokeSpecial only skips, no special return codes)
            // check what we need to do
            CheckResult rs = checkNeedsPublic(invoker, invokee, ref.getClassInfo(), method);
            if (rs == CheckResult.NEEDS_PUBLIC) {
                makePublic(method);
            }
            if (rs == CheckResult.NEEDS_PUBLIC_RENAME) {
                if (method.isPrivate()) {
                // TODO check the class for invokers, change to invokevirtual
                } else {
                // if the method is package visible, we need to rename all overriding methods
                // too (but not methods from subclasses in different packages which do not override this)
                // TODO update overriding methods
                // TODO need to update all possible call sites
                }
                makePublic(method);
                throw new AppInfoError("Implement me!");
            }
        } else if (instr instanceof FieldInstruction) {
            FieldRef ref = code.getFieldRef(ih);
            FieldInfo field = ref.getFieldInfo();
            // we already checked that everything can be resolved
            // check if fields need to be set to public
            CheckResult rs = checkNeedsPublic(invoker, invokee, ref.getClassInfo(), field);
            if (rs == CheckResult.NEEDS_PUBLIC) {
                makePublic(field);
            }
            if (rs == CheckResult.NEEDS_PUBLIC_RENAME) {
                throw new AppInfoError("Invalid returncode: renaming of fields not required");
            }
        }
    }
}
Also used : FieldRef(com.jopdesign.common.type.FieldRef) InstructionList(org.apache.bcel.generic.InstructionList) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ConstantPushInstruction(org.apache.bcel.generic.ConstantPushInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) LocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) AppInfoError(com.jopdesign.common.misc.AppInfoError) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) MethodRef(com.jopdesign.common.type.MethodRef) MethodInfo(com.jopdesign.common.MethodInfo) InvokeSite(com.jopdesign.common.code.InvokeSite) FieldInstruction(org.apache.bcel.generic.FieldInstruction) MethodCode(com.jopdesign.common.MethodCode) FieldInfo(com.jopdesign.common.FieldInfo)

Example 5 with InvokeInstruction

use of org.apache.bcel.generic.InvokeInstruction 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);
    }
}
Also used : NEW(org.apache.bcel.generic.NEW) ConstantDoubleInfo(com.jopdesign.common.type.ConstantDoubleInfo) MULTIANEWARRAY(org.apache.bcel.generic.MULTIANEWARRAY) ConstantIntegerInfo(com.jopdesign.common.type.ConstantIntegerInfo) ConstantFloatInfo(com.jopdesign.common.type.ConstantFloatInfo) ConstantFieldInfo(com.jopdesign.common.type.ConstantFieldInfo) ConstantLongInfo(com.jopdesign.common.type.ConstantLongInfo) AppInfoError(com.jopdesign.common.misc.AppInfoError) ArrayType(org.apache.bcel.generic.ArrayType) CPInstruction(org.apache.bcel.generic.CPInstruction) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) LoadInstruction(org.apache.bcel.generic.LoadInstruction) Type(org.apache.bcel.generic.Type) ArrayType(org.apache.bcel.generic.ArrayType) ValueInfo(com.jopdesign.common.type.ValueInfo) IINC(org.apache.bcel.generic.IINC) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ConstantPushInstruction(org.apache.bcel.generic.ConstantPushInstruction) StoreInstruction(org.apache.bcel.generic.StoreInstruction)

Aggregations

InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)11 FieldInstruction (org.apache.bcel.generic.FieldInstruction)7 Instruction (org.apache.bcel.generic.Instruction)7 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 Type (org.apache.bcel.generic.Type)6 InstructionList (org.apache.bcel.generic.InstructionList)5 MethodInfo (com.jopdesign.common.MethodInfo)4 AppInfoError (com.jopdesign.common.misc.AppInfoError)4 MethodRef (com.jopdesign.common.type.MethodRef)4 GETFIELD (org.apache.bcel.generic.GETFIELD)4 LDC (org.apache.bcel.generic.LDC)4 PUTFIELD (org.apache.bcel.generic.PUTFIELD)4 ReferenceType (org.apache.bcel.generic.ReferenceType)4 InvokeSite (com.jopdesign.common.code.InvokeSite)3 FieldRef (com.jopdesign.common.type.FieldRef)3 ConstantPushInstruction (org.apache.bcel.generic.ConstantPushInstruction)3 GETSTATIC (org.apache.bcel.generic.GETSTATIC)3 LoadInstruction (org.apache.bcel.generic.LoadInstruction)3 NEW (org.apache.bcel.generic.NEW)3 PUTSTATIC (org.apache.bcel.generic.PUTSTATIC)3