Search in sources :

Example 16 with Instruction

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

the class InstructionInterpreter method getOutEdges.

private List<Edge> getOutEdges(InstructionHandle ih) {
    List<Edge> edges = new LinkedList<Edge>();
    Instruction instr = ih.getInstruction();
    if (instr instanceof BranchInstruction) {
        if (instr instanceof Select) {
            Select s = (Select) instr;
            InstructionHandle[] target = s.getTargets();
            for (InstructionHandle aTarget : target) {
                edges.add(new Edge(ih, aTarget, EdgeType.TRUE_EDGE));
            }
            edges.add(new Edge(ih, s.getTarget(), EdgeType.FALSE_EDGE));
        } else {
            BranchInstruction b = (BranchInstruction) instr;
            edges.add(new Edge(ih, b.getTarget(), EdgeType.TRUE_EDGE));
        }
    }
    // Check if we can fall through to the next instruction
    if (ih.getNext() != null && !(instr instanceof UnconditionalBranch || instr instanceof Select || instr instanceof ReturnInstruction)) {
        if (instr instanceof BranchInstruction) {
            edges.add(new Edge(ih, ih.getNext(), EdgeType.FALSE_EDGE));
        } else {
            edges.add(new Edge(ih, ih.getNext(), EdgeType.NORMAL_EDGE));
        }
    }
    if (instr instanceof ReturnInstruction) {
        edges.add(new Edge(ih, getExitInstruction(), EdgeType.EXIT_EDGE));
    }
    if (instr instanceof ATHROW) {
    // TODO should we handle this somehow? Insert edges to the exception handlers or to an return-by-exception
    //      exit instruction?
    // for now, just ignore them
    }
    //      but for now, we just ignore them too.. in a safe way :)
    if (instr instanceof RET || instr instanceof JSR || instr instanceof JSR_W) {
        throw new JavaClassFormatError("Unsupported instruction " + instr + " in " + methodInfo);
    }
    return edges;
}
Also used : RET(org.apache.bcel.generic.RET) UnconditionalBranch(org.apache.bcel.generic.UnconditionalBranch) BranchInstruction(org.apache.bcel.generic.BranchInstruction) JSR(org.apache.bcel.generic.JSR) ATHROW(org.apache.bcel.generic.ATHROW) BranchInstruction(org.apache.bcel.generic.BranchInstruction) Instruction(org.apache.bcel.generic.Instruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) LinkedList(java.util.LinkedList) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Select(org.apache.bcel.generic.Select) JSR_W(org.apache.bcel.generic.JSR_W)

Example 17 with Instruction

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

the class MethodCode method replace.

/**
     * Replace instructions in this code with an instruction list or a part of it.
     * If the number of instructions to replace differs from the number of source instructions, instruction
     * handles will be removed or inserted appropriately and the targets will be updated.
     * <p>
     *     Instruction handles will be reused, so attached values and targets will not be lost if the new length is not
     *     shorter than the old length. Else instruction handles are removed and the targeters to removed instructions
     *     are updated to the instruction after the next instruction after the deleted instructions.
     * </p>
     *
     * @param replaceStart the first instruction in this code to replace
     * @param replaceCount the number of instructions in this code to replace
     * @param sourceInfo the MethodInfo containing the source instruction. If non-null, the instructions will be copied
     *                   using the constant pool from the given MethodInfo. If null, the instructions will not be copied.
     * @param sourceStart the first instruction in the source list to use for replacing the code.
     * @param sourceCount the number of instructions to use from the source.
     * @param copyCustomValues if true copy the custom values from the source.
     * @return the first handle in the target list after the inserted code, or null if the last instruction in this
     *         list has been replaced.
     */
public InstructionHandle replace(InstructionHandle replaceStart, int replaceCount, MethodInfo sourceInfo, InstructionHandle sourceStart, int sourceCount, boolean copyCustomValues) {
    InstructionList il = getInstructionList();
    InstructionHandle current = replaceStart;
    InstructionHandle currSource = sourceStart;
    // update the common prefix
    int cnt = Math.min(replaceCount, sourceCount);
    for (int i = 0; i < cnt; i++) {
        Instruction instr;
        if (sourceInfo != null) {
            instr = copyFrom(sourceInfo.getClassInfo(), currSource.getInstruction());
        } else {
            instr = currSource.getInstruction();
        }
        // TODO support branch instructions! need to replace the IH too
        current.setInstruction(instr);
        if (copyCustomValues) {
            copyCustomValues(sourceInfo, current, currSource);
        }
        current = current.getNext();
        currSource = currSource.getNext();
    }
    InstructionHandle next = current;
    // Case 1: delete unused handles, update targets to next instruction
    if (replaceCount > sourceCount) {
        int rest = replaceCount - sourceCount;
        for (int i = 1; i < rest; i++) {
            next = next.getNext();
        }
        InstructionHandle end = next;
        next = next.getNext();
        try {
            // we cannot use next.getPrev, since next might be null
            il.delete(current, end);
        } catch (TargetLostException e) {
            retarget(e, next);
        }
    }
    // Case 2: insert new handles for rest of source
    if (replaceCount < sourceCount) {
        int rest = sourceCount - replaceCount;
        for (int i = 0; i < rest; i++) {
            Instruction instr;
            if (sourceInfo != null) {
                instr = copyFrom(sourceInfo.getClassInfo(), currSource.getInstruction());
            } else {
                instr = currSource.getInstruction();
            }
            if (next == null) {
                current = il.append(instr);
            } else {
                current = il.insert(next, instr);
            }
            if (copyCustomValues) {
                copyCustomValues(sourceInfo, current, currSource);
            }
            currSource = currSource.getNext();
        }
    }
    return next;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) CPInstruction(org.apache.bcel.generic.CPInstruction) TargetLostException(org.apache.bcel.generic.TargetLostException) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 18 with Instruction

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

the class MethodCode method copyFrom.

/**
     * Create a copy of an instruction and if it uses the constantpool, copy and update the constantpool
     * reference too.
     * <p>Note that branch targets are not updated, so they will most likely be incorrect and need to be updated
     * manually.</p>                                                                                 d
     *
     * @param sourceClass the class containing the constantpool the instruction uses.
     * @param instruction the instruction to copy
     * @return a new copy of the instruction.
     */
public Instruction copyFrom(ClassInfo sourceClass, Instruction instruction) {
    Instruction newInstr = instruction.copy();
    if (instruction instanceof CPInstruction) {
        int oldIndex = ((CPInstruction) instruction).getIndex();
        int newIndex = getClassInfo().addConstantInfo(sourceClass.getConstantInfo(oldIndex));
        ((CPInstruction) newInstr).setIndex(newIndex);
    }
    return newInstr;
}
Also used : CPInstruction(org.apache.bcel.generic.CPInstruction) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) CPInstruction(org.apache.bcel.generic.CPInstruction)

Example 19 with Instruction

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

the class ReplaceAtomicAnnotation method getModifiedArguments.

protected static SortedSet<Integer> getModifiedArguments(MethodGen method) {
    SortedSet<Integer> result = new TreeSet<Integer>();
    int arguments = getArgsCount(method);
    for (Instruction in : method.getInstructionList().getInstructions()) {
        if (in instanceof IndexedInstruction) {
            IndexedInstruction i = (IndexedInstruction) in;
            if (i.getIndex() < arguments) {
                if (i instanceof DSTORE || i instanceof LSTORE) {
                    result.add(i.getIndex());
                    result.add(i.getIndex() + 1);
                } else if (i instanceof StoreInstruction || i instanceof IINC) {
                    result.add(i.getIndex());
                }
            }
        }
    }
    return result;
}
Also used : TreeSet(java.util.TreeSet) IINC(org.apache.bcel.generic.IINC) StoreInstruction(org.apache.bcel.generic.StoreInstruction) Instruction(org.apache.bcel.generic.Instruction) BranchInstruction(org.apache.bcel.generic.BranchInstruction) IndexedInstruction(org.apache.bcel.generic.IndexedInstruction) IndexedInstruction(org.apache.bcel.generic.IndexedInstruction) LSTORE(org.apache.bcel.generic.LSTORE) StoreInstruction(org.apache.bcel.generic.StoreInstruction) DSTORE(org.apache.bcel.generic.DSTORE)

Example 20 with Instruction

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

the class DFATool method loadMethod.

private void loadMethod(MethodInfo method) {
    MethodCode mcode = method.getCode();
    // TODO is there a better way to get an instruction handle? Do we need to keep the list somehow?
    InstructionHandle exit;
    exit = (InstructionHandle) method.getCustomValue(KEY_NOP);
    // we reuse the NOP if it exists, so that we can have multiple DFAs running at the same time
    if (exit == null) {
        exit = new InstructionList(new NOP()).getStart();
        // We do not really want to modify the REAL instruction list and append exit
        // (SH) Fixed :) Yep, we need the NOP somewhere, else doInvoke() will collect the wrong result state.
        //      But we can eliminate the NOP by adding the instruction not to the list, but instead to the
        //      MethodInfo, and also retrieve it from there.
        method.setCustomValue(KEY_NOP, exit);
    }
    this.getStatements().add(exit);
    // We do not modify the code, so we leave existing CFGs alone, just make sure the instruction list is uptodate
    InstructionList il = mcode.getInstructionList(true, false);
    // we need correct positions for the DFA cache serialization stuff
    il.setPositions();
    for (Iterator<?> l = il.iterator(); l.hasNext(); ) {
        InstructionHandle handle = (InstructionHandle) l.next();
        this.getStatements().add(handle);
        Instruction instr = handle.getInstruction();
        if (instr instanceof BranchInstruction) {
            if (instr instanceof Select) {
                Select s = (Select) instr;
                InstructionHandle[] target = s.getTargets();
                for (InstructionHandle aTarget : target) {
                    this.getFlow().addEdge(new FlowEdge(handle, aTarget, FlowEdge.TRUE_EDGE));
                }
                this.getFlow().addEdge(new FlowEdge(handle, s.getTarget(), FlowEdge.FALSE_EDGE));
            } else {
                BranchInstruction b = (BranchInstruction) instr;
                this.getFlow().addEdge(new FlowEdge(handle, b.getTarget(), FlowEdge.TRUE_EDGE));
            }
        }
        if (handle.getNext() != null && !(instr instanceof UnconditionalBranch || instr instanceof Select || instr instanceof ReturnInstruction)) {
            if (instr instanceof BranchInstruction) {
                this.getFlow().addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.FALSE_EDGE));
            } else {
                this.getFlow().addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.NORMAL_EDGE));
            }
        }
        if (instr instanceof ReturnInstruction) {
            this.getFlow().addEdge(new FlowEdge(handle, exit, FlowEdge.NORMAL_EDGE));
        }
    }
}
Also used : FlowEdge(com.jopdesign.dfa.framework.FlowEdge) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) UnconditionalBranch(org.apache.bcel.generic.UnconditionalBranch) BranchInstruction(org.apache.bcel.generic.BranchInstruction) InstructionList(org.apache.bcel.generic.InstructionList) Select(org.apache.bcel.generic.Select) MethodCode(com.jopdesign.common.MethodCode) Instruction(org.apache.bcel.generic.Instruction) BranchInstruction(org.apache.bcel.generic.BranchInstruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) NOP(org.apache.bcel.generic.NOP)

Aggregations

Instruction (org.apache.bcel.generic.Instruction)27 FieldInstruction (org.apache.bcel.generic.FieldInstruction)15 InstructionHandle (org.apache.bcel.generic.InstructionHandle)15 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)14 MethodInfo (com.jopdesign.common.MethodInfo)9 GETFIELD (org.apache.bcel.generic.GETFIELD)8 BranchInstruction (org.apache.bcel.generic.BranchInstruction)7 InstructionList (org.apache.bcel.generic.InstructionList)7 ReferenceType (org.apache.bcel.generic.ReferenceType)7 ReturnInstruction (org.apache.bcel.generic.ReturnInstruction)7 Type (org.apache.bcel.generic.Type)7 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)6 CallString (com.jopdesign.common.code.CallString)5 ConstantPushInstruction (org.apache.bcel.generic.ConstantPushInstruction)5 PUTFIELD (org.apache.bcel.generic.PUTFIELD)5 StoreInstruction (org.apache.bcel.generic.StoreInstruction)5 InvokeSite (com.jopdesign.common.code.InvokeSite)4 MethodRef (com.jopdesign.common.type.MethodRef)4 LDC (org.apache.bcel.generic.LDC)4 LocalVariableInstruction (org.apache.bcel.generic.LocalVariableInstruction)4