Search in sources :

Example 26 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project quasar by puniverse.

the class InstrumentMethod method isForwardingToSuspendable.

private boolean isForwardingToSuspendable(int[] susCallsBcis) {
    if (susCallsBcis.length != 1)
        // we allow exactly one suspendable call
        return false;
    final int susCallBci = susCallsBcis[0];
    final AbstractInsnNode susCall = mn.instructions.get(susCallBci);
    assert isSuspendableCall(db, susCall);
    if (isYieldMethod(getMethodOwner(susCall), getMethodName(susCall)))
        // yield calls require instrumentation (to skip the call when resuming)
        return false;
    if (isReflectInvocation(getMethodOwner(susCall), getMethodName(susCall)))
        // Reflective calls require instrumentation to handle SuspendExecution wrapped in InvocationTargetException
        return false;
    if (hasSuspendableTryCatchBlocksAround(susCallBci))
        // Catching `SuspendableExecution needs instrumentation in order to propagate it
        return false;
    // before suspendable call:
    for (int i = 0; i < susCallBci; i++) {
        final AbstractInsnNode ins = mn.instructions.get(i);
        if (ins.getType() == AbstractInsnNode.METHOD_INSN || ins.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN)
            // methods calls might have side effects
            return false;
        if (ins.getType() == AbstractInsnNode.FIELD_INSN)
            // side effects
            return false;
        if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= i)
            // back branches may be costly, so we'd rather capture state
            return false;
        if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
            // we need collectCodeBlocks to warn about monitors
            return false;
    }
    // after suspendable call
    for (int i = susCallBci + 1; i <= mn.instructions.size() - 1; i++) {
        final AbstractInsnNode ins = mn.instructions.get(i);
        if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= susCallBci)
            // if we jump before the suspendable call we suspend more than once -- need instrumentation
            return false;
        if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
            // we need collectCodeBlocks to warn about monitors
            return false;
        if (!db.isAllowBlocking() && (ins instanceof MethodInsnNode && blockingCallIdx((MethodInsnNode) ins) != -1))
            // we need collectCodeBlocks to warn about blocking calls
            return false;
    }
    return true;
}
Also used : MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 27 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project maple-ir by LLVM-but-worse.

the class ReflectiveFunctorFactory method branch.

@Override
public EvaluationFunctor<Boolean> branch(Type lt, Type rt, ConditionalJumpStmt.ComparisonType type) {
    Type opType = TypeUtils.resolveBinOpType(lt, rt);
    String name = lt.getClassName() + type.name() + rt.getClassName() + "OPTYPE" + opType.getClassName() + "RETbool";
    String desc = "(" + lt.getDescriptor() + rt.getDescriptor() + ")Z";
    if (cache.containsKey(name)) {
        return _get(name);
    }
    MethodNode m = makeBase(name, desc);
    {
        InsnList insns = new InsnList();
        insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(lt), 0));
        cast(insns, lt, opType);
        insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(rt), lt.getSize()));
        cast(insns, rt, opType);
        LabelNode trueSuccessor = new LabelNode();
        if (opType == Type.INT_TYPE) {
            insns.add(new JumpInsnNode(Opcodes.IF_ICMPEQ + type.ordinal(), trueSuccessor));
        } else if (opType == Type.LONG_TYPE) {
            insns.add(new InsnNode(Opcodes.LCMP));
            insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
        } else if (opType == Type.FLOAT_TYPE) {
            insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.FCMPL : Opcodes.FCMPG));
            insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
        } else if (opType == Type.DOUBLE_TYPE) {
            insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.DCMPL : Opcodes.DCMPG));
            insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
        } else {
            throw new IllegalArgumentException(opType.toString());
        }
        branchReturn(insns, trueSuccessor);
        m.instructions = insns;
    }
    return buildBridge(m);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 28 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project flink by apache.

the class ModifiedASMAnalyzer method newControlFlowEdge.

@Override
protected void newControlFlowEdge(int insn, int successor) {
    try {
        if (jumpModificationState == PRE_STATE) {
            jumpModificationState = MOD_STATE;
        } else if (jumpModificationState == MOD_STATE) {
            // for a later merge
            if (jumpModification == IFEQ_MOD) {
                final int top = accessField(Analyzer.class, "top").getInt(this);
                final int[] queue = (int[]) accessField(Analyzer.class, "queue").get(this);
                final int tmp = queue[top - 2];
                queue[top - 2] = queue[top - 1];
                queue[top - 1] = tmp;
                eventInsn = queue[top - 2] - 1;
                final InsnList insns = (InsnList) accessField(Analyzer.class, "insns").get(this);
                // if yes this is loop structure
                if (insns.get(eventInsn) instanceof JumpInsnNode) {
                    jumpModificationState = WAIT_FOR_INSN_STATE;
                } else // no loop -> end of modification
                {
                    jumpModificationState = DO_NOTHING;
                }
            } else // this modification changes the merge priority of certain frames (the expression part of the IF)
            if (jumpModification == IFNE_MOD) {
                final Frame[] frames = (Frame[]) accessField(Analyzer.class, "frames").get(this);
                final Field indexField = accessField(AbstractInsnNode.class, "index");
                final InsnList insns = (InsnList) accessField(Analyzer.class, "insns").get(this);
                final AbstractInsnNode gotoInsnn = insns.get(successor - 1);
                // check for a loop
                if (gotoInsnn instanceof JumpInsnNode) {
                    jumpModificationState = WAIT_FOR_INSN_STATE;
                    // sets a merge priority for all instructions (the expression of the IF)
                    // from the label the goto instruction points to until the evaluation with IFEQ
                    final int idx = indexField.getInt(accessField(JumpInsnNode.class, "label").get(gotoInsnn));
                    for (int i = idx; i <= insn; i++) {
                        ((ModifiedASMFrame) frames[i]).mergePriority = true;
                    }
                    eventInsn = idx - 2;
                } else {
                    jumpModificationState = DO_NOTHING;
                }
            }
        } else // wait for the goto instruction
        if (jumpModificationState == WAIT_FOR_INSN_STATE && insn == eventInsn) {
            jumpModificationState = DO_NOTHING;
            final Frame[] frames = (Frame[]) accessField(Analyzer.class, "frames").get(this);
            // this ensures that local variables are kept
            if (jumpModification == IFEQ_MOD) {
                interpreter.rightMergePriority = true;
                final Field top = accessField(Frame.class, "top");
                top.setInt(frames[eventInsn], top.getInt(frames[eventInsn + 1]));
                frames[eventInsn + 1].merge(frames[eventInsn], interpreter);
            } else // finally set a merge priority for the last instruction of the loop (before the IF expression)
            if (jumpModification == IFNE_MOD) {
                ((ModifiedASMFrame) frames[eventInsn + 1]).mergePriority = true;
            }
        }
    } catch (Exception e) {
        throw new CodeAnalyzerException("Unable to do jump modifications.", e);
    }
}
Also used : Field(java.lang.reflect.Field) Frame(org.objectweb.asm.tree.analysis.Frame) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) Analyzer(org.objectweb.asm.tree.analysis.Analyzer) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 29 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project Bookshelf by Darkhax-Minecraft.

the class TransformerEnchantmentHelper method transform.

public static byte[] transform(String name, String transformedName, byte[] classBytes) {
    final ClassNode clazz = ASMUtils.createClassFromByteArray(classBytes);
    final MethodNode method = METHOD_GET_ENCH_LEVEL.getMethodNode(clazz);
    final InsnList n1 = new InsnList();
    final LabelNode start = new LabelNode();
    n1.add(start);
    n1.add(new TypeInsnNode(Opcodes.NEW, "net/darkhax/bookshelf/events/EnchantmentModifierEvent"));
    n1.add(new InsnNode(Opcodes.DUP));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 0));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 1));
    n1.add(METHOD_INIT_EVENT.getMethodInsn(Opcodes.INVOKESPECIAL, false));
    n1.add(new VarInsnNode(Opcodes.ASTORE, 2));
    final LabelNode l1 = new LabelNode();
    n1.add(l1);
    n1.add(FIELD_EVENT_BUS.getFieldNode(Opcodes.GETSTATIC));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_POST.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    n1.add(new InsnNode(Opcodes.POP));
    final LabelNode l2 = new LabelNode();
    n1.add(l2);
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_CANCELED.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    final LabelNode vanillaLogic = new LabelNode();
    n1.add(new JumpInsnNode(Opcodes.IFEQ, vanillaLogic));
    final LabelNode l4 = new LabelNode();
    n1.add(l4);
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_GET_LEVELS.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    n1.add(new InsnNode(Opcodes.IRETURN));
    n1.add(vanillaLogic);
    method.instructions.insertBefore(method.instructions.getFirst(), n1);
    return ASMUtils.createByteArrayFromClass(clazz, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 30 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project bytecode-viewer by Konloch.

the class Subroutine method merge.

public boolean merge(final Subroutine subroutine) throws AnalyzerException {
    boolean changes = false;
    for (int i = 0; i < access.length; ++i) {
        if (subroutine.access[i] && !access[i]) {
            access[i] = true;
            changes = true;
        }
    }
    if (subroutine.start == start) {
        for (int i = 0; i < subroutine.callers.size(); ++i) {
            JumpInsnNode caller = subroutine.callers.get(i);
            if (!callers.contains(caller)) {
                callers.add(caller);
                changes = true;
            }
        }
    }
    return changes;
}
Also used : JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode)

Aggregations

JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)49 LabelNode (org.objectweb.asm.tree.LabelNode)36 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)28 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)26 InsnNode (org.objectweb.asm.tree.InsnNode)25 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)24 InsnList (org.objectweb.asm.tree.InsnList)22 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)19 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)18 MethodNode (org.objectweb.asm.tree.MethodNode)18 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)15 ClassNode (org.objectweb.asm.tree.ClassNode)14 ClassReader (org.objectweb.asm.ClassReader)12 Label (org.objectweb.asm.Label)11 Type (org.objectweb.asm.Type)9 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)6 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)4 LinkedList (java.util.LinkedList)3 Mutation (org.evosuite.coverage.mutation.Mutation)3 FieldNode (org.objectweb.asm.tree.FieldNode)3