use of org.apache.bcel.generic.InstructionHandle 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();
}
use of org.apache.bcel.generic.InstructionHandle in project jop by jop-devel.
the class ControlFlowGraph method addBasicBlock.
/*---------------------------------------------------------------------------*
* CFG modify, compile, dispose
*---------------------------------------------------------------------------*/
/**
* Add a basic block to this graph. The instruction list of the block must not be empty.
*
* @param insertBefore insert the block at this position in the block list.
* @param bb block to add
* @return the new block node, either an InvokeNode, SpecialInvokeNode or BasicBlockNode, depending on the
* contained instructions.
*/
public BasicBlockNode addBasicBlock(int insertBefore, BasicBlock bb) {
BasicBlockNode n;
Instruction lastInstr = bb.getLastInstruction().getInstruction();
InstructionHandle theInvoke = bb.getTheInvokeInstruction();
// This needs to be done before creating the Node, else blocks.indexOf returns -1
blocks.add(insertBefore, bb);
if (theInvoke != null) {
n = new InvokeNode(bb, theInvoke);
} else if (appInfo.getProcessorModel().isImplementedInJava(methodInfo, lastInstr)) {
MethodInfo javaImpl = appInfo.getProcessorModel().getJavaImplementation(appInfo, bb.getMethodInfo(), lastInstr);
n = new SpecialInvokeNode(bb, javaImpl);
} else {
n = new BasicBlockNode(bb);
}
graph.addVertex(n);
return n;
}
use of org.apache.bcel.generic.InstructionHandle in project jop by jop-devel.
the class InstructionInterpreter method getInEdges.
private List<Edge> getInEdges(InstructionList il, InstructionHandle ih) {
List<Edge> edges = new LinkedList<Edge>();
InstructionHandle prev = ih.getPrev();
if (prev != null) {
// check if we can fall through from prev instruction
Instruction instr = prev.getInstruction();
if (!(instr instanceof UnconditionalBranch || instr instanceof Select || instr instanceof ReturnInstruction)) {
if (instr instanceof BranchInstruction) {
edges.add(new Edge(prev, ih, EdgeType.FALSE_EDGE));
} else {
edges.add(new Edge(prev, ih, EdgeType.NORMAL_EDGE));
}
}
}
// flow graph explicitly
for (InstructionHandle targeter = il.getStart(); targeter != null; targeter = targeter.getNext()) {
// for the instruction for the exception handler
if (!(targeter.getInstruction() instanceof BranchInstruction))
continue;
BranchInstruction bi = (BranchInstruction) targeter.getInstruction();
if (bi.containsTarget(ih)) {
edges.add(new Edge(targeter, ih, EdgeType.TRUE_EDGE));
}
}
return edges;
}
use of org.apache.bcel.generic.InstructionHandle in project jop by jop-devel.
the class InstructionInterpreter method reset.
public void reset(InstructionHandle from, InstructionHandle to) {
InstructionHandle ih = from;
while (ih != to) {
// we remove the entry, initial value will be set by interpret()
results.remove(ih);
ih = ih.getNext();
}
results.put(ih, analysis.bottom());
}
use of org.apache.bcel.generic.InstructionHandle 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;
}
Aggregations