use of org.objectweb.asm.tree.analysis.BasicInterpreter in project jacoco by jacoco.
the class StructuredLockingTest method assertStructuredLocking.
private void assertStructuredLocking(String owner, MethodNode mn) throws Exception {
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new BasicInterpreter()) {
@Override
protected Frame<BasicValue> newFrame(int nLocals, int nStack) {
return new LockFrame(nLocals, nStack);
}
@Override
protected Frame<BasicValue> newFrame(Frame<? extends BasicValue> src) {
return new LockFrame(src);
}
};
Frame<BasicValue>[] frames = analyzer.analyze(owner, mn);
// Make sure no locks are left when method exits:
for (int i = 0; i < frames.length; i++) {
AbstractInsnNode insn = mn.instructions.get(i);
switch(insn.getOpcode()) {
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.ARETURN:
case Opcodes.RETURN:
((LockFrame) frames[i]).assertNoLock("Exit with lock");
break;
case Opcodes.ATHROW:
List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
if (handlers == null || handlers.isEmpty()) {
((LockFrame) frames[i]).assertNoLock("Exit with lock");
}
break;
}
}
// Only instructions protected by a catch-all handler can hold locks:
for (int i = 0; i < frames.length; i++) {
AbstractInsnNode insn = mn.instructions.get(i);
if (insn.getOpcode() > 0) {
boolean catchAll = false;
List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
if (handlers != null) {
for (TryCatchBlockNode node : handlers) {
catchAll |= node.type == null;
}
}
if (!catchAll) {
((LockFrame) frames[i]).assertNoLock("No handlers for insn with lock");
}
}
}
}
use of org.objectweb.asm.tree.analysis.BasicInterpreter in project narchy by automenta.
the class ControlFlowGraph method create.
/**
* Creates a new {@link ControlFlowGraph} and populates it with the flow
* control for the given method. If the optional {@code initial} parameter is
* provided with an existing graph, then the graph is simply populated, not
* created. This allows subclassing of the graph instance, if necessary.
*
* @param initial usually null, but can point to an existing instance of a
* {@link ControlFlowGraph} in which that graph is reused (but
* populated with new edges)
* @param classNode the class containing the method to be analyzed
* @param method the method to be analyzed
* @return a {@link ControlFlowGraph} with nodes for the control flow in the
* given method
* @throws AnalyzerException if the underlying bytecode library is unable to
* analyze the method bytecode
*/
public static ControlFlowGraph create(ControlFlowGraph initial, ClassNode classNode, MethodNode method) throws AnalyzerException {
ControlFlowGraph graph = initial != null ? initial : new ControlFlowGraph();
InsnList instructions = method.instructions;
graph.mNodeMap = Maps.newHashMapWithExpectedSize(instructions.size());
// Create a flow control graph using ASM4's analyzer. According to the ASM 4 guide
// (download.forge.objectweb.org/asm/asm4-guide.pdf) there are faster ways to construct
// it, but those require a lot more code.
Analyzer analyzer = new Analyzer(new BasicInterpreter()) {
@Override
protected void newControlFlowEdge(int insn, int successor) {
// Update the information as of whether the this object has been
// initialized at the given instruction.
AbstractInsnNode from = instructions.get(insn);
AbstractInsnNode to = instructions.get(successor);
graph.add(from, to);
}
@Override
protected boolean newControlFlowExceptionEdge(int insn, TryCatchBlockNode tcb) {
AbstractInsnNode from = instructions.get(insn);
graph.exception(from, tcb);
return super.newControlFlowExceptionEdge(insn, tcb);
}
@Override
protected boolean newControlFlowExceptionEdge(int insn, int successor) {
AbstractInsnNode from = instructions.get(insn);
AbstractInsnNode to = instructions.get(successor);
graph.exception(from, to);
return super.newControlFlowExceptionEdge(insn, successor);
}
};
analyzer.analyze(classNode.name, method);
return graph;
}
use of org.objectweb.asm.tree.analysis.BasicInterpreter in project jacoco by jacoco.
the class StructuredLockingTest method assertStructuredLocking.
private void assertStructuredLocking(String owner, MethodNode mn) throws Exception {
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new BasicInterpreter()) {
@Override
protected Frame<BasicValue> newFrame(int nLocals, int nStack) {
return new LockFrame(nLocals, nStack);
}
@Override
protected Frame<BasicValue> newFrame(Frame<? extends BasicValue> src) {
return new LockFrame(src);
}
};
Frame<BasicValue>[] frames = analyzer.analyze(owner, mn);
// Make sure no locks are left when method exits:
for (int i = 0; i < frames.length; i++) {
AbstractInsnNode insn = mn.instructions.get(i);
switch(insn.getOpcode()) {
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.ARETURN:
case Opcodes.RETURN:
((LockFrame) frames[i]).assertNoLock("Exit with lock");
break;
case Opcodes.ATHROW:
List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
if (handlers == null || handlers.isEmpty()) {
((LockFrame) frames[i]).assertNoLock("Exit with lock");
}
break;
}
}
// Only instructions protected by a catch-all handler can hold locks:
for (int i = 0; i < frames.length; i++) {
AbstractInsnNode insn = mn.instructions.get(i);
if (insn.getOpcode() > 0) {
boolean catchAll = false;
List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
if (handlers != null) {
for (TryCatchBlockNode node : handlers) {
catchAll |= node.type == null;
}
}
if (!catchAll) {
((LockFrame) frames[i]).assertNoLock("No handlers for insn with lock");
}
}
}
}
Aggregations