Search in sources :

Example 1 with ConstantPoolGen

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

the class InlineHelper method checkJVMCall.

private boolean checkJVMCall(InvokeSite invokeSite, MethodInfo invokee) {
    if (!invokeSite.isJVMCall()) {
        return true;
    }
    if (inlineConfig.doInlineJVMCalls() == JVMInline.NONE) {
        return false;
    }
    if (inlineConfig.doInlineJVMCalls() == JVMInline.ALL) {
        return true;
    }
    // Check if params and return type match what is expected on the stack due to the instruction to replace
    ConstantPoolGen cpg = invokeSite.getInvoker().getConstantPoolGen();
    Instruction instr = invokeSite.getInstructionHandle().getInstruction();
    if (!TypeHelper.canAssign(StackHelper.consumeStack(cpg, instr), invokee.getArgumentTypes())) {
        return false;
    }
    if (!invokee.getType().equals(Type.VOID)) {
        if (!TypeHelper.canAssign(new Type[] { invokee.getType() }, StackHelper.produceStack(cpg, instr))) {
            return false;
        }
    }
    return true;
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) AccessType(com.jopdesign.common.MemberInfo.AccessType) Type(org.apache.bcel.generic.Type) 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)

Example 2 with ConstantPoolGen

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

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

the class ConstantPoolRebuilder method createNewConstantPool.

public ConstantPoolGen createNewConstantPool(ConstantPoolGen oldPool, Set<Integer> usedIndices) {
    // We add all used entries to the new pool in the same order as in the old pool
    // to avoid indices getting larger than before
    Integer[] ids = new ArrayList<Integer>(usedIndices).toArray(new Integer[usedIndices.size()]);
    Arrays.sort(ids);
    // First thing we need is a map, since we need to relink the constantpool entries
    idMap.clear();
    // Note that index 0 is not valid, so skip it
    List<Constant> constants = new ArrayList<Constant>(usedIndices.size() + 1);
    constants.add(null);
    int newPos = 1;
    for (int id : ids) {
        Constant c = oldPool.getConstant(id);
        // we cannot use newPool.addConstant here, because this would add all referenced constants too,
        // and we do not want that..
        constants.add(c);
        idMap.put(id, newPos++);
        if (c instanceof ConstantLong || c instanceof ConstantDouble) {
            // reserve an additional slot for those
            constants.add(null);
            newPos++;
        }
    }
    // now we create new constants and map the references
    Constant[] newConstants = new Constant[constants.size()];
    for (int i = 1; i < constants.size(); i++) {
        Constant c = constants.get(i);
        if (c == null)
            continue;
        newConstants[i] = copyConstant(idMap, c);
    }
    newPool = new ConstantPoolGen(newConstants);
    return newPool;
}
Also used : ConstantInteger(org.apache.bcel.classfile.ConstantInteger) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) ConstantLong(org.apache.bcel.classfile.ConstantLong) Constant(org.apache.bcel.classfile.Constant) ConstantDouble(org.apache.bcel.classfile.ConstantDouble) ArrayList(java.util.ArrayList)

Example 4 with ConstantPoolGen

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

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

the class DescendingClassTraverser method visitConstantPool.

///////////////////////////////////////////////////////////////////
// Other methods to visit only parts of a class
///////////////////////////////////////////////////////////////////
public void visitConstantPool(ClassInfo classInfo) {
    ConstantPoolGen cpg = classInfo.getConstantPoolGen();
    if (visitor.visitConstantPoolGen(classInfo, cpg)) {
        bcelVisitor.setClassInfo(classInfo);
        for (int i = 1; i < cpg.getSize(); i++) {
            Constant c = cpg.getConstant(i);
            // Some entries might be null (continuation of previous entry)
            if (c == null)
                continue;
            c.accept(bcelVisitor);
        }
        visitor.finishConstantPoolGen(classInfo, cpg);
    }
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) Constant(org.apache.bcel.classfile.Constant)

Aggregations

ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)28 Instruction (org.apache.bcel.generic.Instruction)6 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 FieldInstruction (org.apache.bcel.generic.FieldInstruction)5 InstructionList (org.apache.bcel.generic.InstructionList)5 CallString (com.jopdesign.common.code.CallString)4 Constant (org.apache.bcel.classfile.Constant)4 Method (org.apache.bcel.classfile.Method)4 ObjectType (org.apache.bcel.generic.ObjectType)4 Type (org.apache.bcel.generic.Type)4 MethodInfo (com.jopdesign.common.MethodInfo)3 AnnotationAttribute (com.jopdesign.common.bcel.AnnotationAttribute)3 ClassRef (com.jopdesign.common.type.ClassRef)3 HashSet (java.util.HashSet)3 Iterator (java.util.Iterator)3 ArrayInstruction (org.apache.bcel.generic.ArrayInstruction)3 BranchInstruction (org.apache.bcel.generic.BranchInstruction)3 MethodGen (org.apache.bcel.generic.MethodGen)3 ClassInfo (com.jopdesign.common.ClassInfo)2 HashedString (com.jopdesign.common.misc.HashedString)2