Search in sources :

Example 6 with InstructionList

use of org.apache.bcel.generic.InstructionList 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) HashSet(java.util.HashSet) ClassInfo(com.jopdesign.common.ClassInfo)

Example 7 with InstructionList

use of org.apache.bcel.generic.InstructionList 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 8 with InstructionList

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

the class DFATool method buildPrologue.

private MethodInfo buildPrologue(MethodInfo mainMethod, List<InstructionHandle> statements, Flow flow, List<ClassInfo> clinits) {
    // we use a prologue sequence for startup
    InstructionList prologue = new InstructionList();
    ConstantPoolGen prologueCP = mainMethod.getConstantPoolGen();
    Instruction instr;
    int idx;
    // add magic initializers to prologue sequence
    if (!analyzeBootMethod) {
        instr = new ICONST(0);
        prologue.append(instr);
        instr = new ICONST(0);
        prologue.append(instr);
        idx = prologueCP.addMethodref("com.jopdesign.sys.GC", "init", "(II)V");
        instr = new INVOKESTATIC(idx);
        prologue.append(instr);
    }
    // add class initializers
    for (ClassInfo clinit : clinits) {
        MemberID cSig = appInfo.getClinitSignature(clinit.getClassName());
        idx = prologueCP.addMethodref(cSig.getClassName(), cSig.getMemberName(), cSig.getDescriptor().toString());
        instr = new INVOKESTATIC(idx);
        prologue.append(instr);
    }
    if (analyzeBootMethod) {
        // Let's just analyze the full boot method, so that the callgraph-builder is happy.
        // Doing this after clinit, so that we have DFA infos on fields in JVMHelp.init()
        idx = prologueCP.addMethodref("com.jopdesign.sys.Startup", "boot", "()V");
        instr = new INVOKESTATIC(idx);
        prologue.append(instr);
    }
    // add main method
    instr = new ACONST_NULL();
    prologue.append(instr);
    idx = prologueCP.addMethodref(mainMethod.getClassName(), mainMethod.getShortName(), mainMethod.getDescriptor().toString());
    instr = new INVOKESTATIC(idx);
    prologue.append(instr);
    //      // invoke startMission() to ensure analysis of threads
    //      idx = prologueCP.addMethodref("joprt.RtThread", "startMission", "()V");
    //      instr = new INVOKESTATIC(idx);
    //      prologue.append(instr);
    instr = new NOP();
    prologue.append(instr);
    prologue.setPositions(true);
    // add prologue to program structure
    for (Iterator l = prologue.iterator(); l.hasNext(); ) {
        InstructionHandle handle = (InstructionHandle) l.next();
        statements.add(handle);
        if (handle.getInstruction() instanceof GOTO) {
            GOTO g = (GOTO) handle.getInstruction();
            flow.addEdge(new FlowEdge(handle, g.getTarget(), FlowEdge.NORMAL_EDGE));
        } else if (handle.getNext() != null) {
            flow.addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.NORMAL_EDGE));
        }
    }
    MemberID pSig = new MemberID(prologueName, Descriptor.parse(prologueSig));
    MethodInfo mi = mainMethod.getClassInfo().createMethod(pSig, null, prologue);
    mi.setAccessType(AccessType.ACC_PRIVATE);
    return mi;
}
Also used : FlowEdge(com.jopdesign.dfa.framework.FlowEdge) INVOKESTATIC(org.apache.bcel.generic.INVOKESTATIC) GOTO(org.apache.bcel.generic.GOTO) InstructionList(org.apache.bcel.generic.InstructionList) Instruction(org.apache.bcel.generic.Instruction) BranchInstruction(org.apache.bcel.generic.BranchInstruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) NOP(org.apache.bcel.generic.NOP) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) MemberID(com.jopdesign.common.type.MemberID) Iterator(java.util.Iterator) MethodInfo(com.jopdesign.common.MethodInfo) ACONST_NULL(org.apache.bcel.generic.ACONST_NULL) ICONST(org.apache.bcel.generic.ICONST) ClassInfo(com.jopdesign.common.ClassInfo)

Example 9 with InstructionList

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

the class BasicBlock method buildBasicBlocks.

/**
     * Create a vector of basic blocks, annotated with flow information
     *
     * @param methodCode The MethodCode of the method from which basic blocks should be extracted.
     * @return A vector of BasicBlocks, which instruction handles annotated with
     *         flow information.
     */
static List<BasicBlock> buildBasicBlocks(MethodCode methodCode) {
    InstructionTargetVisitor itv = new InstructionTargetVisitor(methodCode);
    List<BasicBlock> basicBlocks = new LinkedList<BasicBlock>();
    // We do want to have the latest code, so we compile any existing, *attached* CFG first.
    // However, we do NOT want to remove this CFG, and we do *NOT* want to trigger the onBeforeCodeModify event,
    // else we might remove all CFGs for this method, which we want to avoid if we only modify the graph but do not
    // compile it (the event will be triggered when CFG#compile() is called).
    InstructionList il = methodCode.getInstructionList(true, false);
    il.setPositions(true);
    /* Step 1: compute flow info */
    for (InstructionHandle ih : il.getInstructionHandles()) {
        ih.addAttribute(InstrField.FLOW_INFO, itv.getFlowInfo(ih));
    }
    /* Step 2: create basic blocks */
    {
        BasicBlock bb = new BasicBlock(methodCode);
        InstructionHandle[] handles = il.getInstructionHandles();
        for (int i = 0; i < handles.length; i++) {
            InstructionHandle ih = handles[i];
            bb.addInstruction(ih);
            boolean doSplit = getFlowInfo(ih).doSplitAfter();
            if (i + 1 < handles.length) {
                doSplit |= itv.isTarget(handles[i + 1]);
                doSplit |= getFlowInfo(handles[i + 1]).doSplitBefore();
            }
            if (doSplit) {
                bb.setExitFlowInfo(getFlowInfo(ih));
                basicBlocks.add(bb);
                bb = new BasicBlock(methodCode);
            }
            ih.removeAttribute(InstrField.FLOW_INFO);
        }
        if (!bb.getInstructions().isEmpty()) {
            // be nice to DFA stuff, and ignore NOPs
            for (int i = bb.getInstructions().size() - 1; i >= 0; --i) {
                InstructionHandle x = bb.getInstructions().get(i);
                if (x.getInstruction().getOpcode() != Constants.NOP) {
                    throw new AssertionError("[INTERNAL ERROR] Last instruction " + x + " in code does not change control flow - this is impossible");
                }
            }
        }
    }
    return basicBlocks;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) LinkedList(java.util.LinkedList) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 10 with InstructionList

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

the class InstructionInterpreter method getExitInstruction.

public InstructionHandle getExitInstruction() {
    InstructionHandle exit = (InstructionHandle) methodInfo.getCustomValue(KEY_NOP);
    if (exit == null) {
        exit = new InstructionList().append(new NOP());
        methodInfo.setCustomValue(KEY_NOP, exit);
    }
    return exit;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) InstructionHandle(org.apache.bcel.generic.InstructionHandle) NOP(org.apache.bcel.generic.NOP)

Aggregations

InstructionList (org.apache.bcel.generic.InstructionList)37 InstructionHandle (org.apache.bcel.generic.InstructionHandle)27 Iterator (java.util.Iterator)9 MethodGen (org.apache.bcel.generic.MethodGen)8 Instruction (org.apache.bcel.generic.Instruction)7 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)7 Type (org.apache.bcel.generic.Type)7 InstructionFinder (org.apache.bcel.util.InstructionFinder)7 MethodCode (com.jopdesign.common.MethodCode)6 CPInstruction (org.apache.bcel.generic.CPInstruction)6 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)6 FieldInstruction (org.apache.bcel.generic.FieldInstruction)6 MethodInfo (com.jopdesign.common.MethodInfo)5 NOP (org.apache.bcel.generic.NOP)5 BranchInstruction (org.apache.bcel.generic.BranchInstruction)4 ReturnInstruction (org.apache.bcel.generic.ReturnInstruction)4 ClassInfo (com.jopdesign.common.ClassInfo)3 InvokeSite (com.jopdesign.common.code.InvokeSite)3 Constant (org.apache.bcel.classfile.Constant)3 JavaClass (org.apache.bcel.classfile.JavaClass)3