Search in sources :

Example 21 with InstructionList

use of org.apache.bcel.generic.InstructionList in project fb-contrib by mebigfatguy.

the class CopiedOverriddenMethod method codeEquals.

/**
 * compares two code blocks to see if they are equal with regard to instructions and field accesses
 *
 * @param child
 *            the first code block
 * @param parent
 *            the second code block
 *
 * @return whether the code blocks are the same
 */
private boolean codeEquals(Code child, Code parent) {
    if (parent == null) {
        return false;
    }
    byte[] childBytes = child.getCode();
    byte[] parentBytes = parent.getCode();
    if ((childBytes == null) || (parentBytes == null)) {
        return false;
    }
    if (childBytes.length != parentBytes.length) {
        return false;
    }
    InstructionHandle[] childihs = new InstructionList(childBytes).getInstructionHandles();
    InstructionHandle[] parentihs = new InstructionList(parentBytes).getInstructionHandles();
    if (childihs.length != parentihs.length) {
        return false;
    }
    for (int i = 0; i < childihs.length; i++) {
        InstructionHandle childih = childihs[i];
        InstructionHandle parentih = parentihs[i];
        Instruction childin = childih.getInstruction();
        Instruction parentin = parentih.getInstruction();
        if (!childin.getName().equals(parentin.getName())) {
            return false;
        }
        if (childin instanceof FieldInstruction) {
            String childFName = ((FieldInstruction) childin).getFieldName(childPoolGen);
            String parentFName = ((FieldInstruction) parentin).getFieldName(parentPoolGen);
            if (!childFName.equals(parentFName)) {
                return false;
            }
            String childFSig = ((FieldInstruction) childin).getSignature(childPoolGen);
            String parentFSig = ((FieldInstruction) parentin).getSignature(parentPoolGen);
            if (!childFSig.equals(parentFSig)) {
                return false;
            }
            if (childFSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX) || childFSig.startsWith(Values.SIG_ARRAY_PREFIX)) {
                ReferenceType childRefType = ((FieldInstruction) childin).getReferenceType(childPoolGen);
                ReferenceType parentRefType = ((FieldInstruction) parentin).getReferenceType(parentPoolGen);
                if (!childRefType.getSignature().equals(parentRefType.getSignature())) {
                    return false;
                }
            }
        } else if (childin instanceof InvokeInstruction) {
            String childClassName = ((InvokeInstruction) childin).getClassName(childPoolGen);
            String parentClassName = ((InvokeInstruction) parentin).getClassName(parentPoolGen);
            if (!childClassName.equals(parentClassName)) {
                return false;
            }
            String childMethodName = ((InvokeInstruction) childin).getMethodName(childPoolGen);
            String parentMethodName = ((InvokeInstruction) parentin).getMethodName(parentPoolGen);
            if (!childMethodName.equals(parentMethodName)) {
                return false;
            }
            String childSignature = ((InvokeInstruction) childin).getSignature(childPoolGen);
            String parentSignature = ((InvokeInstruction) parentin).getSignature(parentPoolGen);
            if (!childSignature.equals(parentSignature)) {
                return false;
            }
        } else if (childin instanceof LDC) {
            Type childType = ((LDC) childin).getType(childPoolGen);
            Type parentType = ((LDC) parentin).getType(parentPoolGen);
            if (!childType.equals(parentType)) {
                return false;
            }
            Object childValue = ((LDC) childin).getValue(childPoolGen);
            Object parentValue = ((LDC) parentin).getValue(parentPoolGen);
            if (childValue instanceof ConstantClass) {
                ConstantClass childClass = (ConstantClass) childValue;
                ConstantClass parentClass = (ConstantClass) parentValue;
                if (!childClass.getBytes(childPoolGen.getConstantPool()).equals(parentClass.getBytes(parentPoolGen.getConstantPool()))) {
                    return false;
                }
            } else if (!childValue.equals(parentValue)) {
                return false;
            }
        // TODO: Other Constant types
        } else if (childin instanceof LDC2_W) {
            Type childType = ((LDC2_W) childin).getType(childPoolGen);
            Type parentType = ((LDC2_W) parentin).getType(parentPoolGen);
            if (!childType.equals(parentType)) {
                return false;
            }
            Object childValue = ((LDC2_W) childin).getValue(childPoolGen);
            Object parentValue = ((LDC2_W) parentin).getValue(parentPoolGen);
            if (!childValue.equals(parentValue)) {
                return false;
            }
        } else {
            if (!childin.equals(parentin)) {
                return false;
            }
        }
    }
    return true;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) LDC(org.apache.bcel.generic.LDC) ToString(com.mebigfatguy.fbcontrib.utils.ToString) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReferenceType(org.apache.bcel.generic.ReferenceType) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) BugType(com.mebigfatguy.fbcontrib.utils.BugType) LDC2_W(org.apache.bcel.generic.LDC2_W) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ConstantClass(org.apache.bcel.classfile.ConstantClass)

Example 22 with InstructionList

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

the class FindUsedConstants method find.

private void find(Method method) {
    MethodGen mg = new MethodGen(method, clazz.getClassName(), cpool);
    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);
        int len = 1;
        switch(co.getTag()) {
            case Constants.CONSTANT_Long:
            case Constants.CONSTANT_Double:
                len = 2;
                break;
        }
        // we don't need the field references in the cpool anymore
        if (co.getTag() != Constants.CONSTANT_Fieldref) {
            getCli().addUsedConst(idx, len);
        }
    // also modify the index!
    //			Constant cnst = cpool.getConstant(ii.getIndex());
    //			int newIndex = addConstant(cnst);
    //System.out.println(ii+" -> "+newIndex);
    //			ii.setIndex(newIndex);			
    }
    il.dispose();
    CodeExceptionGen[] et = mg.getExceptionHandlers();
    for (int i = 0; i < et.length; i++) {
        ObjectType ctype = et[i].getCatchType();
        if (ctype != null) {
            getCli().addUsedConst(cpool.lookupClass(ctype.getClassName()), 1);
        }
    }
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) InstructionFinder(org.apache.bcel.util.InstructionFinder) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) CPInstruction(org.apache.bcel.generic.CPInstruction) ObjectType(org.apache.bcel.generic.ObjectType) Iterator(java.util.Iterator) CodeExceptionGen(org.apache.bcel.generic.CodeExceptionGen)

Example 23 with InstructionList

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

the class InsertSynchronized method synchronize.

private void synchronize(MethodInfo method) {
    MethodCode mc = method.getCode();
    InstructionList il = mc.getInstructionList();
    InstructionFinder f;
    // prepend monitorenter (reversed order of opcodes)
    il.insert(new MONITORENTER());
    if (method.isStatic()) {
        // il.insert(new GET_CURRENT_CLASS());
        throw new JavaClassFormatError("synchronized on static methods not yet supported");
    } else {
        il.insert(new ALOAD(0));
    }
    il.setPositions();
    f = new InstructionFinder(il);
    // find return instructions and insert monitorexit
    String retInstr = "ReturnInstruction";
    for (Iterator iterator = f.search(retInstr); iterator.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) iterator.next();
        InstructionHandle ih = match[0];
        // handle for inserted sequence
        InstructionHandle newh;
        if (method.isStatic()) {
            // il.insert(ih, new GET_CURRENT_CLASS());
            throw new JavaClassFormatError("synchronized on static methods not yet supported");
        } else {
            // TODO this could become a bug if JCopter ever reassigns local variable slots, then
            // we could not be sure that slot 0 holds the this reference anymore.. To be on the safe side
            // we should check if there is an xSTORE_0 somewhere in the code
            newh = il.insert(ih, new ALOAD(0));
        }
        il.insert(ih, new MONITOREXIT());
        // correct jumps
        method.getCode().retarget(ih, newh);
    }
    il.setPositions();
    method.compile();
}
Also used : ALOAD(org.apache.bcel.generic.ALOAD) InstructionList(org.apache.bcel.generic.InstructionList) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Iterator(java.util.Iterator) MONITOREXIT(org.apache.bcel.generic.MONITOREXIT) InstructionFinder(org.apache.bcel.util.InstructionFinder) MethodCode(com.jopdesign.common.MethodCode) MONITORENTER(org.apache.bcel.generic.MONITORENTER) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 24 with InstructionList

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

the class ControlFlowGraph method compile.

/**
     * Compile the CFG back into an instruction list and store it in the associated
     * MethodCode.
     * <p>
     * We do not order the blocks here, this is a separate optimization
     * Also, we do not insert jump instructions if the fallthrough edge of a block does not
     * link to the next block in the block list. Instead an error is raised.
     * </p>
     * TODO create method to insert jump blocks where necessary
     */
public void compile() {
    InstructionList il = new InstructionList();
    Object[] attributes = { KEY_CFGNODE };
    Map<BasicBlock, BasicBlockNode> blockMap = buildBlockNodeMap();
    for (int i = 0; i < blocks.size(); i++) {
        BasicBlock bb = blocks.get(i);
        BasicBlockNode bbn = blockMap.get(bb);
        if (bbn == null) {
            // infeasible edges..
            continue;
        }
        for (CFGEdge e : graph.outgoingEdgesOf(bbn)) {
            if (e.getKind() != EdgeKind.NEXT_EDGE)
                continue;
            BasicBlock target = graph.getEdgeTarget(e).getBasicBlock();
            // TODO edge targets a SPLIT node, handle correctly ..
            if (target == null) {
                throw new ControlFlowError("Block " + i + " does fallthrough to a virtual node of type " + ((VirtualNode) graph.getEdgeTarget(e)).getKind() + " in " + methodInfo);
            }
            if (blocks.get(i + 1) != target) {
                throw new ControlFlowError("Block " + i + " does not fall through to the next block in " + methodInfo);
            }
        }
    }
// TODO compile is not yet fully implemented (retarget, exception-handlers, ..)
// methodInfo.getCode().setInstructionList(il);
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList)

Example 25 with InstructionList

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

the class InstructionInterpreter method interpret.

public void interpret(boolean initialize) {
    InstructionList il = methodInfo.getCode().getInstructionList(true, false);
    InstructionHandle entry = il.getStart();
    Map<InstructionHandle, T> start = new HashMap<InstructionHandle, T>();
    start.put(entry, initialize ? analysis.initial(entry) : analysis.bottom());
    // start at exception handler entries too?
    if (startAtExceptionHandlers) {
        for (CodeExceptionGen eg : methodInfo.getCode().getExceptionHandlers()) {
            InstructionHandle ih = eg.getHandlerPC();
            start.put(ih, initialize ? analysis.initial(eg) : analysis.bottom());
        }
    }
    interpret(il, start, initialize);
}
Also used : RET(org.apache.bcel.generic.RET) HashMap(java.util.HashMap) InstructionList(org.apache.bcel.generic.InstructionList) CodeExceptionGen(org.apache.bcel.generic.CodeExceptionGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

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