Commit be2719e5 authored by Lubomir Bulej's avatar Lubomir Bulej

AsmHelper: new methods for traversing instruction lists

AsmHelper: various changes needed for WeavingCode to be merged

Remaining classes updated to reflect the change.
parent f9134799
......@@ -26,8 +26,10 @@ import ch.usi.dag.disl.localvar.LocalVars;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.Constants;
import ch.usi.dag.disl.util.FrameHelper;
import ch.usi.dag.disl.util.Insn;
/**
* Parses DiSL class with local variables
......@@ -210,7 +212,7 @@ abstract class AbstractParser {
// the next initialization block.
//
AbstractInsnNode firstInitInsn = initInsns.getFirst ();
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom (initInsns)) {
for (final AbstractInsnNode insn : Insns.selectAll (initInsns)) {
if (AsmHelper.isReturn (insn.getOpcode ())) {
break;
}
......@@ -272,7 +274,7 @@ abstract class AbstractParser {
//
// Clone only real instructions, we should not need labels.
//
if (! AsmHelper.isVirtualInstr (insn)) {
if (! Insn.isVirtual (insn)) {
result.add (insn.clone (dummy));
}
}
......
......@@ -13,7 +13,7 @@ import org.objectweb.asm.tree.VarInsnNode;
import ch.usi.dag.disl.exception.DiSLFatalException;
import ch.usi.dag.disl.exception.ParserException;
import ch.usi.dag.disl.exception.ReflectionException;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.ReflectionHelper;
// package visible
......@@ -84,7 +84,7 @@ abstract class ParserHelper {
}
// The following code assumes that all disl snippets are static
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom (instructions)) {
for (AbstractInsnNode instr : Insns.selectAll (instructions)) {
switch (instr.getOpcode()) {
// test if the context is stored somewhere else
......
......@@ -22,6 +22,7 @@ import ch.usi.dag.disl.localvar.LocalVars;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.Constants;
import ch.usi.dag.disl.util.ReflectionHelper;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
......@@ -55,7 +56,7 @@ public class UnprocessedCode {
Set <SyntheticLocalVar> slvList = new HashSet <SyntheticLocalVar> ();
Set <ThreadLocalVar> tlvList = new HashSet <ThreadLocalVar> ();
for (AbstractInsnNode insn : AsmHelper.allInsnsFrom (instructions)) {
for (AbstractInsnNode insn : Insns.selectAll (instructions)) {
// *** Parse synthetic local variables ***
SyntheticLocalVar slv = insnUsesField (insn, allLVs.getSyntheticLocals ());
if (slv != null) {
......@@ -89,7 +90,7 @@ public class UnprocessedCode {
Map<String, StaticContextMethod> staticContexts =
new HashMap<String, StaticContextMethod>();
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom (instructions)) {
for (AbstractInsnNode instr : Insns.selectAll (instructions)) {
// *** Parse static context methods in use ***
StaticContextMethod scm = insnInvokesStaticContext(
......
......@@ -9,11 +9,10 @@ import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
/**
* <p>
* Marks whole method body.
*
* Marks a method body after call to constructor.
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method. If the method is a constructor, the start is inserted after the
......@@ -33,7 +32,7 @@ public class AfterInitBodyMarker extends AbstractMarker {
// Add all instructions preceding the RETURN instructions
// as marked region ends.
//
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom(method.instructions)) {
for (final AbstractInsnNode insn : Insns.selectAll (method.instructions)) {
int opcode = insn.getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
region.addEnd(insn.getPrevious());
......
......@@ -6,13 +6,11 @@ import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.BasicBlockCalc;
/**
* <p>
* Marks basic block.
*
* Marks a basic block.
* <p>
* Sets the start at the beginning of a basic block and the end at the end of a
* basic block. Considers only jump instructions, lookup switch and table
......@@ -29,8 +27,9 @@ public class BasicBlockMarker extends AbstractDWRMarker {
List<AbstractInsnNode> seperators = BasicBlockCalc.getAll(
methodNode.instructions, methodNode.tryCatchBlocks, isPrecise);
AbstractInsnNode last = AsmHelper.skipVirtualInsns(
methodNode.instructions.getLast(), false);
AbstractInsnNode last = Insns.REVERSE.firstRealInsn (
methodNode.instructions.getLast()
);
seperators.add(last);
......@@ -43,8 +42,9 @@ public class BasicBlockMarker extends AbstractDWRMarker {
end = end.getPrevious();
}
regions.add(new MarkedRegion(start, AsmHelper.skipVirtualInsns(end,
false)));
regions.add(new MarkedRegion(
start, Insns.REVERSE.firstRealInsn (end)
));
}
return regions;
......
......@@ -8,12 +8,10 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
/**
* <p>
* Marks whole method body.
*
* Marks a method body.
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method.
......@@ -27,7 +25,7 @@ public class BodyMarker extends AbstractMarker {
MarkedRegion region =
new MarkedRegion(method.instructions.getFirst());
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom(method.instructions)) {
for (AbstractInsnNode instr : Insns.selectAll (method.instructions)) {
int opcode = instr.getOpcode();
......
......@@ -9,13 +9,11 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.exception.MarkerException;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.AsmOpcodes;
/**
* <p>
* Marks one java bytecode instruction.
*
* Marks one bytecode instruction.
* <p>
* Sets the start before a bytecode instruction and the end after a bytecode
* instruction. If the bytecode instruction is (conditional) jump the end is
......@@ -60,7 +58,7 @@ public class BytecodeMarker extends AbstractDWRMarker {
public List<MarkedRegion> markWithDefaultWeavingReg(MethodNode method) {
List<MarkedRegion> regions = new LinkedList<MarkedRegion>();
for (AbstractInsnNode instruction : AsmHelper.allInsnsFrom(method.instructions)) {
for (AbstractInsnNode instruction : Insns.selectAll (method.instructions)) {
if (searchedInstrNums.contains(instruction.getOpcode())) {
......
......@@ -7,13 +7,11 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
/**
* <p>
* Marks exception handler.
*
* Marks an exception handler.
* <p>
* Sets the start at the beginning of an exception handler and the end at the
* end of an exception handler.
......@@ -32,8 +30,9 @@ public class ExceptionHandlerMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
List<AbstractInsnNode> exits = cfg.visit(tcb.handler);
regions.add(new MarkedRegion(AsmHelper.skipVirtualInsns(tcb.handler,
true), exits));
regions.add(new MarkedRegion(
Insns.FORWARD.firstRealInsn (tcb.handler), exits
));
}
return regions;
......
......@@ -9,14 +9,12 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.exception.MarkerException;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
/**
* Marks bytecode instructions depending on the ASM class type.
* <p>
* <b>note:</b> This class is work in progress
*
* <p>
* Marks instruction depending on ASM class type.
* <b>Note:</b> This class is work in progress.
*/
public class InsnNodeMarker extends AbstractInsnMarker {
......@@ -56,7 +54,7 @@ public class InsnNodeMarker extends AbstractInsnMarker {
List<AbstractInsnNode> seleted = new LinkedList<AbstractInsnNode>();
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom(methodNode.instructions)) {
for (AbstractInsnNode instr : Insns.selectAll (methodNode.instructions)) {
for (Class<? extends AbstractInsnNode> clazz : classes) {
......
......@@ -8,19 +8,16 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.Constants;
/**
* <p>
* <b>note:</b> This class is work in progress
*
* <p>
* Marks object creation.
*
* <p>
* Sets the start before new instruction and the end after the constructor
* invocation.
* <p>
* <b>Note:</b> This class is work in progress.
*/
public class NewObjMarker extends AbstractDWRMarker {
......@@ -33,7 +30,7 @@ public class NewObjMarker extends AbstractDWRMarker {
int invokedNews = 0;
// find invocation of constructor after new instruction
for (AbstractInsnNode instruction : AsmHelper.allInsnsFrom(method.instructions)) {
for (AbstractInsnNode instruction : Insns.selectAll (method.instructions)) {
// track new instruction
if (instruction.getOpcode() == Opcodes.NEW) {
......
......@@ -7,12 +7,10 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
/**
* <p>
* Marks try block.
*
* Marks a try block.
* <p>
* Sets the start at the beginning of a try block and the end at the end of a
* try block.
......@@ -26,8 +24,10 @@ public class TryClauseMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
AbstractInsnNode start = AsmHelper.skipVirtualInsns(tcb.start, true);
AbstractInsnNode end = AsmHelper.skipVirtualInsns(tcb.end, false);
AbstractInsnNode start = Insns.FORWARD.firstRealInsn (tcb.start);
// RFC LB: Consider nextRealInsn, since TCB end is exclusive
// This depends on the semantics of marked region
AbstractInsnNode end = Insns.REVERSE.firstRealInsn (tcb.end);
regions.add(new MarkedRegion(start, end));
}
......
......@@ -31,6 +31,7 @@ import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.processorcontext.ArgumentProcessorContext;
import ch.usi.dag.disl.processorcontext.ArgumentProcessorMode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
/**
* Contains unprocessed code of the Snippet.
......@@ -97,7 +98,7 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
new HashMap<Integer, ProcInvocation>();
int insnIndex = 0;
for (AbstractInsnNode insn : AsmHelper.allInsnsFrom (instructions)) {
for (AbstractInsnNode insn : Insns.selectAll (instructions)) {
// *** Parse processors in use ***
// no other modifications to the code should be done before weaving
// otherwise, produced instruction reference can be invalid
......
......@@ -7,7 +7,7 @@ import java.util.Map;
import org.objectweb.asm.tree.AbstractInsnNode;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.Insn;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
/**
......@@ -59,7 +59,7 @@ public class BasicBlockStaticContext extends AbstractStaticContext {
while (!ends.contains(start)) {
if (! AsmHelper.isVirtualInstr(start)) {
if (! Insn.isVirtual (start)) {
count++;
}
......
This diff is collapsed.
......@@ -14,6 +14,8 @@ import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import ch.usi.dag.disl.util.AsmHelper.Insns;
public class BasicBlockCalc {
......@@ -38,7 +40,7 @@ public class BasicBlockCalc {
Set <AbstractInsnNode> bbStarts = new HashSet <AbstractInsnNode> () {
@Override
public boolean add (AbstractInsnNode insn) {
return super.add (AsmHelper.skipVirtualInsnsForward (insn));
return super.add (Insns.FORWARD.firstRealInsn (insn));
}
@Override
......@@ -62,7 +64,7 @@ public class BasicBlockCalc {
// block and collect the starting instructions of the basic blocks
// that follow them.
//
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom (instructions)) {
for (final AbstractInsnNode insn : Insns.selectAll (instructions)) {
SWITCH: switch (insn.getType ()) {
//
// IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
......@@ -76,7 +78,7 @@ public class BasicBlockCalc {
// also starts with the next instruction.
//
// The GOTO instruction changes the control flow unconditionally,
// so only one basic block follows it.
// so only one basic block follows from it.
//
case AbstractInsnNode.JUMP_INSN: {
bbStarts.add (((JumpInsnNode) insn).label);
......@@ -85,7 +87,7 @@ public class BasicBlockCalc {
// There must be a valid (non-virtual) instruction
// following a conditional/subroutine jump instruction.
//
AbstractInsnNode nextInsn = AsmHelper.nextNonVirtualInsn (insn);
AbstractInsnNode nextInsn = Insns.FORWARD.nextRealInsn (insn);
if (nextInsn != null) {
bbStarts.add (nextInsn);
}
......@@ -149,7 +151,7 @@ public class BasicBlockCalc {
// not help here, because we were adding entries out-of-order (jumps).
//
List <AbstractInsnNode> result = new ArrayList <AbstractInsnNode> ();
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom (instructions)) {
for (final AbstractInsnNode insn : Insns.selectAll (instructions)) {
if (bbStarts.contains (insn)) {
result.add (insn);
}
......
package ch.usi.dag.disl.util;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
/**
* Represents a Java bytecode instructions. This enum should be kept in sync
* with ASM {@link Opcodes}.
*/
public enum Insn {
//
// The instructions commented out are not used by ASM.
//
NOP (Opcodes.NOP),
ACONST_NULL (Opcodes.ACONST_NULL),
ICONST_M1 (Opcodes.ICONST_M1),
ICONST_0 (Opcodes.ICONST_0),
ICONST_1 (Opcodes.ICONST_1),
ICONST_2 (Opcodes.ICONST_2),
ICONST_3 (Opcodes.ICONST_3),
ICONST_4 (Opcodes.ICONST_4),
ICONST_5 (Opcodes.ICONST_5),
LCONST_0 (Opcodes.LCONST_0),
LCONST_1 (Opcodes.LCONST_1),
FCONST_0 (Opcodes.FCONST_0),
FCONST_1 (Opcodes.FCONST_1),
FCONST_2 (Opcodes.FCONST_2),
DCONST_0 (Opcodes.DCONST_0),
DCONST_1 (Opcodes.DCONST_1),
BIPUSH (Opcodes.BIPUSH),
SIPUSH (Opcodes.SIPUSH),
LDC (Opcodes.LDC),
// LDC_W (Opcodes.LDC_W),
// LDC2_W (Opcodes.LDC2_W),
ILOAD (Opcodes.ILOAD),
LLOAD (Opcodes.LLOAD),
FLOAD (Opcodes.FLOAD),
DLOAD (Opcodes.DLOAD),
ALOAD (Opcodes.ALOAD),
// ILOAD_0 (Opcodes.ILOAD_0),
// ILOAD_1 (Opcodes.ILOAD_1),
// ILOAD_2 (Opcodes.ILOAD_2),
// ILOAD_3 (Opcodes.ILOAD_3),
// LLOAD_0 (Opcodes.LLOAD_0),
// LLOAD_1 (Opcodes.LLOAD_1),
// LLOAD_2 (Opcodes.LLOAD_2),
// LLOAD_3 (Opcodes.LLOAD_3),
// FLOAD_0 (Opcodes.FLOAD_0),
// FLOAD_1 (Opcodes.FLOAD_1),
// FLOAD_2 (Opcodes.FLOAD_2),
// FLOAD_3 (Opcodes.FLOAD_3),
// DLOAD_0 (Opcodes.DLOAD_0),
// DLOAD_1 (Opcodes.DLOAD_1),
// DLOAD_2 (Opcodes.DLOAD_2),
// DLOAD_3 (Opcodes.DLOAD_3),
// ALOAD_0 (Opcodes.ALOAD_0),
// ALOAD_1 (Opcodes.ALOAD_1),
// ALOAD_2 (Opcodes.ALOAD_2),
// ALOAD_3 (Opcodes.ALOAD_3),
IALOAD (Opcodes.IALOAD),
LALOAD (Opcodes.LALOAD),
FALOAD (Opcodes.FALOAD),
DALOAD (Opcodes.DALOAD),
AALOAD (Opcodes.AALOAD),
BALOAD (Opcodes.BALOAD),
CALOAD (Opcodes.CALOAD),
SALOAD (Opcodes.SALOAD),
ISTORE (Opcodes.ISTORE),
LSTORE (Opcodes.LSTORE),
FSTORE (Opcodes.FSTORE),
DSTORE (Opcodes.DSTORE),
ASTORE (Opcodes.ASTORE),
// ISTORE_0 (Opcodes.ISTORE_0),
// ISTORE_1 (Opcodes.ISTORE_1),
// ISTORE_2 (Opcodes.ISTORE_2),
// ISTORE_3 (Opcodes.ISTORE_3),
// LSTORE_0 (Opcodes.LSTORE_0),
// LSTORE_1 (Opcodes.LSTORE_1),
// LSTORE_2 (Opcodes.LSTORE_2),
// LSTORE_3 (Opcodes.LSTORE_3),
// FSTORE_0 (Opcodes.FSTORE_0),
// FSTORE_1 (Opcodes.FSTORE_1),
// FSTORE_2 (Opcodes.FSTORE_2),
// FSTORE_3 (Opcodes.FSTORE_3),
// DSTORE_0 (Opcodes.DSTORE_0),
// DSTORE_1 (Opcodes.DSTORE_1),
// DSTORE_2 (Opcodes.DSTORE_2),
// DSTORE_3 (Opcodes.DSTORE_3),
// ASTORE_0 (Opcodes.ASTORE_0),
// ASTORE_1 (Opcodes.ASTORE_1),
// ASTORE_2 (Opcodes.ASTORE_2),
// ASTORE_3 (Opcodes.ASTORE_3),
IASTORE (Opcodes.IASTORE),
LASTORE (Opcodes.LASTORE),
FASTORE (Opcodes.FASTORE),
DASTORE (Opcodes.DASTORE),
AASTORE (Opcodes.AASTORE),
BASTORE (Opcodes.BASTORE),
CASTORE (Opcodes.CASTORE),
SASTORE (Opcodes.SASTORE),
POP (Opcodes.POP),
POP2 (Opcodes.POP2),
DUP (Opcodes.DUP),
DUP_X1 (Opcodes.DUP_X1),
DUP_X2 (Opcodes.DUP_X2),
DUP2 (Opcodes.DUP2),
DUP2_X1 (Opcodes.DUP2_X1),
DUP2_X2 (Opcodes.DUP2_X2),
SWAP (Opcodes.SWAP),
IADD (Opcodes.IADD),
LADD (Opcodes.LADD),
FADD (Opcodes.FADD),
DADD (Opcodes.DADD),
ISUB (Opcodes.ISUB),
LSUB (Opcodes.LSUB),
FSUB (Opcodes.FSUB),
DSUB (Opcodes.DSUB),
IMUL (Opcodes.IMUL),
LMUL (Opcodes.LMUL),
FMUL (Opcodes.FMUL),
DMUL (Opcodes.DMUL),
IDIV (Opcodes.IDIV),
LDIV (Opcodes.LDIV),
FDIV (Opcodes.FDIV),
DDIV (Opcodes.DDIV),
IREM (Opcodes.IREM),
LREM (Opcodes.LREM),
FREM (Opcodes.FREM),
DREM (Opcodes.DREM),
INEG (Opcodes.INEG),
LNEG (Opcodes.LNEG),
FNEG (Opcodes.FNEG),
DNEG (Opcodes.DNEG),
ISHL (Opcodes.ISHL),
LSHL (Opcodes.LSHL),
ISHR (Opcodes.ISHR),
LSHR (Opcodes.LSHR),
IUSHR (Opcodes.IUSHR),
LUSHR (Opcodes.LUSHR),
IAND (Opcodes.IAND),
LAND (Opcodes.LAND),
IOR (Opcodes.IOR),
LOR (Opcodes.LOR),
IXOR (Opcodes.IXOR),
LXOR (Opcodes.LXOR),
IINC (Opcodes.IINC),
I2L (Opcodes.I2L),
I2F (Opcodes.I2F),
I2D (Opcodes.I2D),
L2I (Opcodes.L2I),
L2F (Opcodes.L2F),
L2D (Opcodes.L2D),
F2I (Opcodes.F2I),
F2L (Opcodes.F2L),
F2D (Opcodes.F2D),
D2I (Opcodes.D2I),
D2L (Opcodes.D2L),
D2F (Opcodes.D2F),
I2B (Opcodes.I2B),
I2C (Opcodes.I2C),
I2S (Opcodes.I2S),
LCMP (Opcodes.LCMP),
FCMPL (Opcodes.FCMPL),
FCMPG (Opcodes.FCMPG),
DCMPL (Opcodes.DCMPL),
DCMPG (Opcodes.DCMPG),
IFEQ (Opcodes.IFEQ),
IFNE (Opcodes.IFNE),
IFLT (Opcodes.IFLT),
IFGE (Opcodes.IFGE),
IFGT (Opcodes.IFGT),
IFLE (Opcodes.IFLE),
IF_ICMPEQ (Opcodes.IF_ICMPEQ),
IF_ICMPNE (Opcodes.IF_ICMPNE),
IF_ICMPLT (Opcodes.IF_ICMPLT),
IF_ICMPGE (Opcodes.IF_ICMPGE),
IF_ICMPGT (Opcodes.IF_ICMPGT),
IF_ICMPLE (Opcodes.IF_ICMPLE),
IF_ACMPEQ (Opcodes.IF_ACMPEQ),
IF_ACMPNE (Opcodes.IF_ACMPNE),
GOTO (Opcodes.GOTO),
JSR (Opcodes.JSR),
RET (Opcodes.RET),
TABLESWITCH (Opcodes.TABLESWITCH),
LOOKUPSWITCH (Opcodes.LOOKUPSWITCH),
IRETURN (Opcodes.IRETURN),
LRETURN (Opcodes.LRETURN),
FRETURN (Opcodes.FRETURN),
DRETURN (Opcodes.DRETURN),
ARETURN (Opcodes.ARETURN),
RETURN (Opcodes.RETURN),
GETSTATIC (Opcodes.GETSTATIC),
PUTSTATIC (Opcodes.PUTSTATIC),
GETFIELD (Opcodes.GETFIELD),
PUTFIELD (Opcodes.PUTFIELD),
INVOKEVIRTUAL (Opcodes.INVOKEVIRTUAL),
INVOKESPECIAL (Opcodes.INVOKESPECIAL),
INVOKESTATIC (Opcodes.INVOKESTATIC),
INVOKEINTERFACE (Opcodes.INVOKEINTERFACE),
INVOKEDYNAMIC (Opcodes.INVOKEDYNAMIC),
NEW (Opcodes.NEW),
NEWARRAY (Opcodes.NEWARRAY),
ANEWARRAY (Opcodes.ANEWARRAY),
ARRAYLENGTH (Opcodes.ARRAYLENGTH),
ATHROW (Opcodes.ATHROW),
CHECKCAST (Opcodes.CHECKCAST),
INSTANCEOF (Opcodes.INSTANCEOF),
MONITORENTER (Opcodes.MONITORENTER),
MONITOREXIT (Opcodes.MONITOREXIT),
// WIDE (Opcodes.WIDE),
MULTIANEWARRAY (Opcodes.MULTIANEWARRAY),
IFNULL (Opcodes.IFNULL),
IFNONNULL (Opcodes.IFNONNULL),
// GOTO_W (Opcodes.GOTO_W),
// JSR_W (Opcodes.JSR_W),
;
private final int __opcode;
private static final Insn [] __insns;
static {
__insns = new Insn [1 << Byte.SIZE];
for (final Insn insn : Insn.values ()) {
__insns [insn.opcode ()] = insn;
}
}
private Insn (final int opcode) {
__opcode = opcode;
}
public int opcode () {
return __opcode;
}
public boolean matches (final AbstractInsnNode insn) {
return (insn != null && this == forNode (insn));
}
//
public static Insn forOpcode (final int opcode) {
return (0 <= opcode && opcode < __insns.length) ? __insns [opcode] : null;
}
public static Insn forNode (final AbstractInsnNode insn) {
return forOpcode (insn.getOpcode ());
}
public static boolean isVirtual (final AbstractInsnNode insn) {
return (insn.getOpcode() == -1);
}
}
......@@ -15,7 +15,7 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.Insns;
import ch.usi.dag.disl.util.BasicBlockCalc;
public class CtrlFlowGraph {
......@@ -60,7 +60,7 @@ public class CtrlFlowGraph {
end = end.getPrevious();
}
end = AsmHelper.skipVirtualInsns(end, false);
end = Insns.REVERSE.firstRealInsn (end);
nodes.add(new BasicBlock(i, start, end));
}
}
......@@ -91,7 +91,7 @@ public class CtrlFlowGraph {
// If not found, return null.
public BasicBlock getBB(AbstractInsnNode instr) {
instr = AsmHelper.skipVirtualInsns(instr, true);
instr = Insns.FORWARD.firstRealInsn (instr);
while (instr != null) {
......
......@@ -9,6 +9,7 @@ import org.objectweb.asm.tree.TryCatchBlockNode;