Search in sources :

Example 51 with AbstractInsnNode

use of org.objectweb.asm.tree.AbstractInsnNode in project DynamicSurroundings by OreCruncher.

the class SoundCrashFixLibrary method transmorgrify.

@Override
public boolean transmorgrify(final ClassNode cn) {
    final String name = "removeSource";
    final String sig = "(Ljava/lang/String;)V";
    final MethodNode m = findMethod(cn, sig, name);
    if (m != null) {
        for (final Iterator<?> iterator = m.instructions.iterator(); iterator.hasNext(); ) {
            final AbstractInsnNode insn = (AbstractInsnNode) iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") && ((MethodInsnNode) insn).name.equals("cleanup")) {
                m.instructions.insertBefore(insn, new MethodInsnNode(Opcodes.INVOKESTATIC, "org/blockartistry/DynSurround/client/sound/fix/SoundFixMethods", "cleanupSource", "(Lpaulscode/sound/Source;)V", false));
                m.instructions.remove(insn);
                return true;
            }
        }
    } else {
        Transformer.log().error("Unable to locate method {}{}", name, sig);
    }
    Transformer.log().info("Unable to patch [{}]!", getClassName());
    return false;
}
Also used : MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 52 with AbstractInsnNode

use of org.objectweb.asm.tree.AbstractInsnNode in project soot by Sable.

the class AsmMethodSource method getBody.

@Override
public Body getBody(SootMethod m, String phaseName) {
    if (!m.isConcrete())
        return null;
    JimpleBody jb = Jimple.v().newBody(m);
    /* initialize */
    int nrInsn = instructions.size();
    nextLocal = maxLocals;
    locals = new HashMap<Integer, Local>(maxLocals + (maxLocals / 2));
    labels = ArrayListMultimap.create(4, 1);
    units = new HashMap<AbstractInsnNode, Unit>(nrInsn);
    frames = new HashMap<AbstractInsnNode, StackFrame>(nrInsn);
    trapHandlers = ArrayListMultimap.create(tryCatchBlocks.size(), 1);
    body = jb;
    /* retrieve all trap handlers */
    for (TryCatchBlockNode tc : tryCatchBlocks) trapHandlers.put(tc.handler, Jimple.v().newStmtBox(null));
    /* convert instructions */
    try {
        convert();
    } catch (Throwable t) {
        throw new RuntimeException("Failed to convert " + m, t);
    }
    /* build body (add units, locals, traps, etc.) */
    emitLocals();
    emitTraps();
    emitUnits();
    /* clean up */
    locals = null;
    labels = null;
    units = null;
    stack = null;
    frames = null;
    body = null;
    // Make sure to inline patterns of the form to enable proper variable
    // splitting and type assignment:
    // a = new A();
    // goto l0;
    // l0:
    // b = (B) a;
    // return b;
    castAndReturnInliner.transform(jb);
    try {
        PackManager.v().getPack("jb").apply(jb);
    } catch (Throwable t) {
        throw new RuntimeException("Failed to apply jb to " + m, t);
    }
    return jb;
}
Also used : TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) Local(soot.Local) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) Unit(soot.Unit) JimpleBody(soot.jimple.JimpleBody)

Example 53 with AbstractInsnNode

use of org.objectweb.asm.tree.AbstractInsnNode in project soot by Sable.

the class AsmMethodSource method addEdges.

private void addEdges(AbstractInsnNode cur, AbstractInsnNode tgt1, List<LabelNode> tgts) {
    int lastIdx = tgts == null ? -1 : tgts.size() - 1;
    Operand[] stackss = (new ArrayList<Operand>(stack)).toArray(new Operand[stack.size()]);
    AbstractInsnNode tgt = tgt1;
    int i = 0;
    tgt_loop: do {
        Edge edge = edges.get(cur, tgt);
        if (edge == null) {
            edge = new Edge(tgt);
            edge.prevStacks.add(stackss);
            edges.put(cur, tgt, edge);
            conversionWorklist.add(edge);
            continue;
        }
        if (edge.stack != null) {
            ArrayList<Operand> stackTemp = edge.stack;
            if (stackTemp.size() != stackss.length) {
                throw new AssertionError("Multiple un-equal stacks!");
            }
            for (int j = 0; j != stackss.length; j++) {
                if (!stackTemp.get(j).equivTo(stackss[j]))
                    throw new AssertionError("Multiple un-equal stacks!");
            }
            continue;
        }
        for (Operand[] ps : edge.prevStacks) {
            if (Arrays.equals(ps, stackss))
                continue tgt_loop;
        }
        edge.stack = new ArrayList<Operand>(stack);
        edge.prevStacks.add(stackss);
        conversionWorklist.add(edge);
    } while (i <= lastIdx && (tgt = tgts.get(i++)) != null);
}
Also used : ArrayList(java.util.ArrayList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 54 with AbstractInsnNode

use of org.objectweb.asm.tree.AbstractInsnNode in project soot by Sable.

the class AsmMethodSource method emitUnits.

private void emitUnits() {
    AbstractInsnNode insn = instructions.getFirst();
    ArrayDeque<LabelNode> labls = new ArrayDeque<LabelNode>();
    while (insn != null) {
        // Save the label to assign it to the next real unit
        if (insn instanceof LabelNode)
            labls.add((LabelNode) insn);
        // Get the unit associated with the current instruction
        Unit u = units.get(insn);
        if (u == null) {
            insn = insn.getNext();
            continue;
        }
        emitUnits(u);
        // If this is an exception handler, register the starting unit for it
        {
            IdentityStmt caughtEx = null;
            if (u instanceof IdentityStmt)
                caughtEx = (IdentityStmt) u;
            else if (u instanceof UnitContainer)
                caughtEx = getIdentityRefFromContrainer((UnitContainer) u);
            if (insn instanceof LabelNode && caughtEx != null && caughtEx.getRightOp() instanceof CaughtExceptionRef) {
                // We directly place this label
                Collection<UnitBox> traps = trapHandlers.get((LabelNode) insn);
                for (UnitBox ub : traps) ub.setUnit(caughtEx);
            }
        }
        // Register this unit for all targets of the labels ending up at it
        while (!labls.isEmpty()) {
            LabelNode ln = labls.poll();
            Collection<UnitBox> boxes = labels.get(ln);
            if (boxes != null) {
                for (UnitBox box : boxes) {
                    box.setUnit(u instanceof UnitContainer ? ((UnitContainer) u).getFirstUnit() : u);
                }
            }
        }
        insn = insn.getNext();
    }
    // Emit the inline exception handlers
    for (LabelNode ln : this.inlineExceptionHandlers.keySet()) {
        Unit handler = this.inlineExceptionHandlers.get(ln);
        emitUnits(handler);
        Collection<UnitBox> traps = trapHandlers.get(ln);
        for (UnitBox ub : traps) ub.setUnit(handler);
        // We need to jump to the original implementation
        Unit targetUnit = units.get(ln);
        GotoStmt gotoImpl = Jimple.v().newGotoStmt(targetUnit);
        body.getUnits().add(gotoImpl);
    }
    /* set remaining labels & boxes to last unit of chain */
    if (labls.isEmpty())
        return;
    Unit end = Jimple.v().newNopStmt();
    body.getUnits().add(end);
    while (!labls.isEmpty()) {
        LabelNode ln = labls.poll();
        Collection<UnitBox> boxes = labels.get(ln);
        if (boxes != null) {
            for (UnitBox box : boxes) box.setUnit(end);
        }
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) UnitBox(soot.UnitBox) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) GotoStmt(soot.jimple.GotoStmt) Collection(java.util.Collection) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) Unit(soot.Unit) ArrayDeque(java.util.ArrayDeque) IdentityStmt(soot.jimple.IdentityStmt)

Example 55 with AbstractInsnNode

use of org.objectweb.asm.tree.AbstractInsnNode in project soot by Sable.

the class AsmMethodSource method convert.

private void convert() {
    ArrayDeque<Edge> worklist = new ArrayDeque<Edge>();
    for (LabelNode ln : trapHandlers.keySet()) {
        if (checkInlineExceptionHandler(ln))
            handleInlineExceptionHandler(ln, worklist);
        else
            worklist.add(new Edge(ln, new ArrayList<Operand>()));
    }
    worklist.add(new Edge(instructions.getFirst(), new ArrayList<Operand>()));
    conversionWorklist = worklist;
    edges = HashBasedTable.create(1, 1);
    do {
        Edge edge = worklist.pollLast();
        AbstractInsnNode insn = edge.insn;
        stack = edge.stack;
        edge.stack = null;
        do {
            int type = insn.getType();
            if (type == FIELD_INSN) {
                convertFieldInsn((FieldInsnNode) insn);
            } else if (type == IINC_INSN) {
                convertIincInsn((IincInsnNode) insn);
            } else if (type == INSN) {
                convertInsn((InsnNode) insn);
                int op = insn.getOpcode();
                if ((op >= IRETURN && op <= RETURN) || op == ATHROW) {
                    break;
                }
            } else if (type == INT_INSN) {
                convertIntInsn((IntInsnNode) insn);
            } else if (type == LDC_INSN) {
                convertLdcInsn((LdcInsnNode) insn);
            } else if (type == JUMP_INSN) {
                JumpInsnNode jmp = (JumpInsnNode) insn;
                convertJumpInsn(jmp);
                int op = jmp.getOpcode();
                if (op == JSR)
                    throw new UnsupportedOperationException("JSR!");
                if (op != GOTO) {
                    /* ifX opcode, i.e. two successors */
                    AbstractInsnNode next = insn.getNext();
                    addEdges(insn, next, Collections.singletonList(jmp.label));
                } else {
                    addEdges(insn, jmp.label, null);
                }
                break;
            } else if (type == LOOKUPSWITCH_INSN) {
                LookupSwitchInsnNode swtch = (LookupSwitchInsnNode) insn;
                convertLookupSwitchInsn(swtch);
                LabelNode dflt = swtch.dflt;
                addEdges(insn, dflt, swtch.labels);
                break;
            } else if (type == METHOD_INSN) {
                convertMethodInsn((MethodInsnNode) insn);
            } else if (type == INVOKE_DYNAMIC_INSN) {
                convertInvokeDynamicInsn((InvokeDynamicInsnNode) insn);
            } else if (type == MULTIANEWARRAY_INSN) {
                convertMultiANewArrayInsn((MultiANewArrayInsnNode) insn);
            } else if (type == TABLESWITCH_INSN) {
                TableSwitchInsnNode swtch = (TableSwitchInsnNode) insn;
                convertTableSwitchInsn(swtch);
                LabelNode dflt = swtch.dflt;
                addEdges(insn, dflt, swtch.labels);
            } else if (type == TYPE_INSN) {
                convertTypeInsn((TypeInsnNode) insn);
            } else if (type == VAR_INSN) {
                if (insn.getOpcode() == RET)
                    throw new UnsupportedOperationException("RET!");
                convertVarInsn((VarInsnNode) insn);
            } else if (type == LABEL) {
                convertLabel((LabelNode) insn);
            } else if (type == LINE) {
                convertLine((LineNumberNode) insn);
            } else if (type == FRAME) {
            // we can ignore it
            } else
                throw new RuntimeException("Unknown instruction type: " + type);
        } while ((insn = insn.getNext()) != null);
    } while (!worklist.isEmpty());
    conversionWorklist = null;
    edges = null;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TableSwitchInsnNode(org.objectweb.asm.tree.TableSwitchInsnNode) MultiANewArrayInsnNode(org.objectweb.asm.tree.MultiANewArrayInsnNode) ArrayList(java.util.ArrayList) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) ArrayDeque(java.util.ArrayDeque) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IincInsnNode(org.objectweb.asm.tree.IincInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LookupSwitchInsnNode(org.objectweb.asm.tree.LookupSwitchInsnNode)

Aggregations

AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)185 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)68 MethodNode (org.objectweb.asm.tree.MethodNode)54 InsnList (org.objectweb.asm.tree.InsnList)53 InsnNode (org.objectweb.asm.tree.InsnNode)41 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)38 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)37 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)35 ClassNode (org.objectweb.asm.tree.ClassNode)33 LabelNode (org.objectweb.asm.tree.LabelNode)27 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)26 Test (org.junit.Test)25 Label (org.objectweb.asm.Label)25 ClassReader (org.objectweb.asm.ClassReader)23 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)23 HashSet (java.util.HashSet)16 Type (org.objectweb.asm.Type)15 Frame (org.objectweb.asm.tree.analysis.Frame)13 ArrayList (java.util.ArrayList)12 TryCatchBlockNode (org.objectweb.asm.tree.TryCatchBlockNode)11