Search in sources :

Example 1 with CPInstruction

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

the class OldClinitOrder method findDependencies.

private Set findDependencies(OldClassInfo cli, OldMethodInfo mi, boolean inRec) {
    // System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
    Method method = mi.getMethod();
    Set depends = new HashSet();
    if (method.isNative() || method.isAbstract()) {
        // subclasses???? :-(
        return depends;
    }
    ConstantPool cpool = cli.clazz.getConstantPool();
    ConstantPoolGen cpoolgen = new ConstantPoolGen(cpool);
    MethodGen mg = new MethodGen(method, cli.clazz.getClassName(), cpoolgen);
    InstructionList il = mg.getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // find instructions that access the constant pool
    // collect all indices to constants in ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle first = match[0];
        CPInstruction ii = (CPInstruction) first.getInstruction();
        int idx = ii.getIndex();
        Constant co = cpool.getConstant(idx);
        ConstantClass cocl = null;
        Set addDepends = null;
        String clname;
        OldClassInfo clinfo;
        OldMethodInfo minfo;
        switch(co.getTag()) {
            case Constants.CONSTANT_Class:
                cocl = (ConstantClass) co;
                clname = cocl.getBytes(cpool).replace('/', '.');
                clinfo = (OldClassInfo) ai.cliMap.get(clname);
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo("<init>()V");
                    if (minfo != null) {
                        addDepends = findDependencies(clinfo, minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_InterfaceMethodref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantInterfaceMethodref) co).getClassIndex());
                break;
            case Constants.CONSTANT_Methodref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantMethodref) co).getClassIndex());
                clname = cocl.getBytes(cpool).replace('/', '.');
                clinfo = (OldClassInfo) ai.cliMap.get(clname);
                int sigidx = ((ConstantMethodref) co).getNameAndTypeIndex();
                ConstantNameAndType signt = (ConstantNameAndType) cpool.getConstant(sigidx);
                String sigstr = signt.getName(cpool) + signt.getSignature(cpool);
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo(sigstr);
                    if (minfo != null) {
                        addDepends = findDependencies(clinfo, minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_Fieldref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantFieldref) co).getClassIndex());
                break;
        }
        if (cocl != null) {
            clname = cocl.getBytes(cpool).replace('/', '.');
            OldClassInfo clinf = (OldClassInfo) ai.cliMap.get(clname);
            if (clinf != null) {
                if (clinf.getMethodInfo(OldAppInfo.clinitSig) != null) {
                    // don't add myself as dependency
                    if (clinf != cli) {
                        depends.add(clinf);
                    }
                }
            }
        }
        if (addDepends != null) {
            Iterator itAddDep = addDepends.iterator();
            while (itAddDep.hasNext()) {
                OldClassInfo addCli = (OldClassInfo) itAddDep.next();
                if (addCli == cli) {
                    throw new Error("cyclic indirect <clinit> dependency");
                }
                depends.add(addCli);
            }
        }
    }
    il.dispose();
    return depends;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) Method(org.apache.bcel.classfile.Method) InstructionFinder(org.apache.bcel.util.InstructionFinder) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantNameAndType(org.apache.bcel.classfile.ConstantNameAndType) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) CPInstruction(org.apache.bcel.generic.CPInstruction) ConstantMethodref(org.apache.bcel.classfile.ConstantMethodref) ConstantPool(org.apache.bcel.classfile.ConstantPool) Iterator(java.util.Iterator) ConstantClass(org.apache.bcel.classfile.ConstantClass) HashSet(java.util.HashSet)

Example 2 with CPInstruction

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

the class ClinitOrder method findDependencies.

private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
    // System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
    Set<ClassInfo> depends = new HashSet<ClassInfo>();
    if (method.isNative() || method.isAbstract()) {
        // subclasses???? :-(
        return depends;
    }
    ClassInfo classInfo = method.getClassInfo();
    ConstantPoolGen cpoolgen = method.getConstantPoolGen();
    InstructionList il = method.getCode().getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // TODO can we encounter an empty instruction list?
    // if(il.getStart() == null) {
    // return depends;
    // }
    // find instructions that access the constant pool
    // collect all indices to constants in ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle first = match[0];
        CPInstruction ii = (CPInstruction) first.getInstruction();
        int idx = ii.getIndex();
        Constant co = cpoolgen.getConstant(idx);
        ClassRef classRef = null;
        Set addDepends = null;
        ClassInfo clinfo;
        MethodInfo minfo;
        switch(co.getTag()) {
            case Constants.CONSTANT_Class:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                clinfo = classRef.getClassInfo();
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo("<init>()V");
                    if (minfo != null) {
                        addDepends = findDependencies(minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_Fieldref:
            case Constants.CONSTANT_InterfaceMethodref:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                break;
            case Constants.CONSTANT_Methodref:
                ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
                classRef = mref.getClassRef();
                minfo = mref.getMethodRef().getMethodInfo();
                if (minfo != null) {
                    addDepends = findDependencies(minfo, true);
                }
                break;
        }
        if (classRef != null) {
            ClassInfo clinf = classRef.getClassInfo();
            if (clinf != null) {
                if (clinf.getMethodInfo(clinitSig) != null) {
                    // don't add myself as dependency
                    if (!clinf.equals(method.getClassInfo())) {
                        depends.add(clinf);
                    }
                }
            }
        }
        if (addDepends != null) {
            for (Object addDepend : addDepends) {
                ClassInfo addCli = (ClassInfo) addDepend;
                if (addCli.equals(method.getClassInfo())) {
                    throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
                }
                depends.add(addCli);
            }
        }
    }
    return depends;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ClassRef(com.jopdesign.common.type.ClassRef) InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) InstructionFinder(org.apache.bcel.util.InstructionFinder) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) CPInstruction(org.apache.bcel.generic.CPInstruction) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Iterator(java.util.Iterator) MethodInfo(com.jopdesign.common.MethodInfo) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) ClassInfo(com.jopdesign.common.ClassInfo) HashSet(java.util.HashSet)

Example 3 with CPInstruction

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

the class ConstantPoolRebuilder method updateMethodGen.

public void updateMethodGen(MethodInfo methodInfo, MethodGen methodGen) {
    methodGen.setConstantPool(newPool);
    if (methodInfo.hasCode()) {
        // update all instructions
        InstructionList il = methodInfo.getCode().getInstructionList();
        class InstructionVisitor extends EmptyVisitor {

            @Override
            public void visitCPInstruction(CPInstruction obj) {
                obj.setIndex(mapIndex(obj.getIndex()));
            }
        }
        InstructionVisitor iv = new InstructionVisitor();
        for (InstructionHandle ih : il.getInstructionHandles()) {
            ih.getInstruction().accept(iv);
        }
        updateAttributes(methodInfo, methodGen.getCodeAttributes());
    }
    updateAttributes(methodInfo, methodGen.getAttributes());
}
Also used : CPInstruction(org.apache.bcel.generic.CPInstruction) InstructionList(org.apache.bcel.generic.InstructionList) InstructionHandle(org.apache.bcel.generic.InstructionHandle) EmptyVisitor(org.apache.bcel.generic.EmptyVisitor)

Example 4 with CPInstruction

use of org.apache.bcel.generic.CPInstruction 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)

Example 5 with CPInstruction

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

the class ReplaceNativeAndCPIdx method replace.

private Method replace(Method method) {
    MethodGen mg = new MethodGen(method, clazz.getClassName(), cpoolgen);
    InstructionList il = mg.getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    String methodId = method.getName() + method.getSignature();
    OldMethodInfo mi = getCli().getMethodInfo(methodId);
    // find invokes first and replace call to Native by
    // JOP native instructions.
    String invokeStr = "InvokeInstruction";
    for (Iterator i = f.search(invokeStr); i.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) i.next();
        InstructionHandle first = match[0];
        InvokeInstruction ii = (InvokeInstruction) first.getInstruction();
        if (ii.getClassName(cpoolgen).equals(JOPizer.nativeClass)) {
            short opid = (short) JopInstr.getNative(ii.getMethodName(cpoolgen));
            if (opid == -1) {
                System.err.println(method.getName() + ": cannot locate " + ii.getMethodName(cpoolgen) + ". Replacing with NOP.");
                first.setInstruction(new NOP());
            } else {
                first.setInstruction(new NativeInstruction(opid, (short) 1));
                ((JOPizer) ai).outTxt.println("\t" + first.getPosition());
                // then we remove pc+2 and pc+1 from the MGCI info
                if (JOPizer.dumpMgci) {
                    il.setPositions();
                    int pc = first.getPosition();
                    // important: take the high one first
                    GCRTMethodInfo.removePC(pc + 2, mi);
                    GCRTMethodInfo.removePC(pc + 1, mi);
                }
            }
        }
        if (ii instanceof INVOKESPECIAL) {
            // not an initializer
            if (!ii.getMethodName(cpoolgen).equals("<init>")) {
                // check if this is a super invoke
                // TODO this is just a hack, use InvokeSite.isInvokeSuper() when this is ported to the new framework!
                boolean isSuper = false;
                String declaredType = ii.getClassName(cpoolgen);
                JopClassInfo cls = getCli();
                OldClassInfo superClass = cls.superClass;
                while (superClass != null) {
                    if (superClass.clazz.getClassName().equals(declaredType)) {
                        isSuper = true;
                        break;
                    }
                    if ("java.lang.Object".equals(superClass.clazz.getClassName())) {
                        break;
                    }
                    superClass = superClass.superClass;
                }
                if (isSuper) {
                    Integer idx = ii.getIndex();
                    int new_index = getCli().cpoolUsed.indexOf(idx) + 1;
                    first.setInstruction(new JOPSYS_INVOKESUPER((short) new_index));
                // System.err.println("invokesuper "+ii.getClassName(cpoolgen)+"."+ii.getMethodName(cpoolgen));
                }
            }
        }
    }
    if (JOPizer.CACHE_INVAL) {
        f = new InstructionFinder(il);
        // find volatile reads and insert cache invalidation bytecode
        String fieldInstr = "GETFIELD|GETSTATIC|PUTFIELD|PUTSTATIC";
        for (Iterator i = f.search(fieldInstr); i.hasNext(); ) {
            InstructionHandle[] match = (InstructionHandle[]) i.next();
            InstructionHandle ih = match[0];
            FieldInstruction fi = (FieldInstruction) ih.getInstruction();
            JavaClass jc = JOPizer.jz.cliMap.get(fi.getClassName(cpoolgen)).clazz;
            Field field = null;
            while (field == null) {
                Field[] fields = jc.getFields();
                for (int k = 0; k < fields.length; k++) {
                    if (fields[k].getName().equals(fi.getFieldName(cpoolgen))) {
                        field = fields[k];
                        break;
                    }
                }
                if (field == null) {
                    try {
                        jc = jc.getSuperClass();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        throw new Error();
                    }
                }
            }
            if (field.isVolatile()) {
                if (field.getType().getSize() < 2) {
                    if (fi instanceof GETFIELD || fi instanceof GETSTATIC) {
                        ih.setInstruction(new InvalidateInstruction());
                        ih = il.append(ih, fi);
                    }
                } else {
                    // this only works because we do not throw a
                    // NullPointerException for monitorenter/-exit!
                    ih.setInstruction(new ACONST_NULL());
                    ih = il.append(ih, new MONITORENTER());
                    ih = il.append(ih, fi);
                    ih = il.append(ih, new ACONST_NULL());
                    ih = il.append(ih, new MONITOREXIT());
                }
            }
        }
    }
    f = new InstructionFinder(il);
    // find instructions that access the constant pool
    // and replace the index by the new value from ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle ih = match[0];
        CPInstruction cpii = (CPInstruction) ih.getInstruction();
        int index = cpii.getIndex();
        // we have to grab the information before we change
        // the CP index.
        FieldInstruction fi = null;
        Type ft = null;
        if (cpii instanceof FieldInstruction) {
            fi = (FieldInstruction) ih.getInstruction();
            ft = fi.getFieldType(cpoolgen);
        }
        Integer idx = new Integer(index);
        // pos is the new position in the reduced constant pool
        // idx is the position in the 'original' unresolved cpool
        int pos = getCli().cpoolUsed.indexOf(idx);
        int new_index = pos + 1;
        // and putfield and by address for getstatic and putstatic
        if (cpii instanceof GETFIELD || cpii instanceof PUTFIELD || cpii instanceof GETSTATIC || cpii instanceof PUTSTATIC) {
            // we use the offset instead of the CP index
            new_index = getFieldOffset(cp, index);
        } else {
            if (pos == -1) {
                System.out.println("Error: constant " + index + " " + cpoolgen.getConstant(index) + " not found");
                System.out.println("new cpool: " + getCli().cpoolUsed);
                System.out.println("original cpool: " + cpoolgen);
                System.exit(-1);
            }
        }
        // set new index, position starts at
        // 1 as cp points to the length of the pool
        cpii.setIndex(new_index);
        if (cpii instanceof FieldInstruction) {
            boolean isRef = ft instanceof ReferenceType;
            boolean isLong = ft == BasicType.LONG || ft == BasicType.DOUBLE;
            if (fi instanceof GETSTATIC) {
                if (isRef) {
                    ih.setInstruction(new GETSTATIC_REF((short) new_index));
                } else if (isLong) {
                    ih.setInstruction(new GETSTATIC_LONG((short) new_index));
                }
            } else if (fi instanceof PUTSTATIC) {
                if (isRef) {
                    if (!com.jopdesign.build.JOPizer.USE_RTTM) {
                        ih.setInstruction(new PUTSTATIC_REF((short) new_index));
                    }
                } else if (isLong) {
                    ih.setInstruction(new PUTSTATIC_LONG((short) new_index));
                }
            } else if (fi instanceof GETFIELD) {
                if (isRef) {
                    ih.setInstruction(new GETFIELD_REF((short) new_index));
                } else if (isLong) {
                    ih.setInstruction(new GETFIELD_LONG((short) new_index));
                }
            } else if (fi instanceof PUTFIELD) {
                if (isRef) {
                    if (!com.jopdesign.build.JOPizer.USE_RTTM) {
                        ih.setInstruction(new PUTFIELD_REF((short) new_index));
                    }
                } else if (isLong) {
                    ih.setInstruction(new PUTFIELD_LONG((short) new_index));
                }
            }
        }
    }
    Method m = mg.getMethod();
    il.dispose();
    return m;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) InstructionFinder(org.apache.bcel.util.InstructionFinder) MONITORENTER(org.apache.bcel.generic.MONITORENTER) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReferenceType(org.apache.bcel.generic.ReferenceType) PUTSTATIC(org.apache.bcel.generic.PUTSTATIC) Field(org.apache.bcel.classfile.Field) CPInstruction(org.apache.bcel.generic.CPInstruction) Iterator(java.util.Iterator) MONITOREXIT(org.apache.bcel.generic.MONITOREXIT) ACONST_NULL(org.apache.bcel.generic.ACONST_NULL) PUTFIELD(org.apache.bcel.generic.PUTFIELD) Method(org.apache.bcel.classfile.Method) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL) NOP(org.apache.bcel.generic.NOP) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) GETFIELD(org.apache.bcel.generic.GETFIELD) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) BasicType(org.apache.bcel.generic.BasicType) ConstantNameAndType(org.apache.bcel.classfile.ConstantNameAndType) JavaClass(org.apache.bcel.classfile.JavaClass) FieldInstruction(org.apache.bcel.generic.FieldInstruction) GETSTATIC(org.apache.bcel.generic.GETSTATIC)

Aggregations

CPInstruction (org.apache.bcel.generic.CPInstruction)7 InstructionHandle (org.apache.bcel.generic.InstructionHandle)5 InstructionList (org.apache.bcel.generic.InstructionList)5 Iterator (java.util.Iterator)4 InstructionFinder (org.apache.bcel.util.InstructionFinder)4 Constant (org.apache.bcel.classfile.Constant)3 FieldInstruction (org.apache.bcel.generic.FieldInstruction)3 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)3 MethodGen (org.apache.bcel.generic.MethodGen)3 HashSet (java.util.HashSet)2 Set (java.util.Set)2 ConstantNameAndType (org.apache.bcel.classfile.ConstantNameAndType)2 Method (org.apache.bcel.classfile.Method)2 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)2 Type (org.apache.bcel.generic.Type)2 ClassInfo (com.jopdesign.common.ClassInfo)1 MethodInfo (com.jopdesign.common.MethodInfo)1 AppInfoError (com.jopdesign.common.misc.AppInfoError)1 JavaClassFormatError (com.jopdesign.common.misc.JavaClassFormatError)1 ClassRef (com.jopdesign.common.type.ClassRef)1