Package org.objectweb.asm.tree

Examples of org.objectweb.asm.tree.AbstractInsnNode


        pn("MaxLocals: " + method.maxLocals);
        ArrayList<BasicBlock> bbs = method.getBasicBlocks();
        Collections.sort(bbs);
        indent(2);
        for (BasicBlock bb: bbs) {
            AbstractInsnNode ainode = bb.getInstruction(bb.startPos);
            if (ainode instanceof MethodInsnNode) {
                MethodInsnNode m = (MethodInsnNode)ainode;
                int n = getNumArgs(m); // This many will get consumed from stack
                pn("Call(" + n + "): " + m.owner + "." + m.name + m.desc);
                indent(2);
View Full Code Here


        String nInvokeSpecialDescriptor = null;
        int oUninitCount = 0;
        int nUninitCount = 0;
        boolean codeChange = false;
        for (int i = 0, max = oInstructions.size(); i < max; i++) {
          AbstractInsnNode oInstruction = oInstructions.get(i);
          AbstractInsnNode nInstruction = nInstructions.get(i);
          if (!codeChange) {
            if (!sameInstruction(oInstruction, nInstruction)) {
              codeChange = true;
            }

          }
          if (oInstruction.getType() == AbstractInsnNode.TYPE_INSN) {
            if (oInstruction.getOpcode() == Opcodes.NEW) {
              oUninitCount++;
            }
          }
          if (nInstruction.getType() == AbstractInsnNode.TYPE_INSN) {
            if (nInstruction.getOpcode() == Opcodes.NEW) {
              nUninitCount++;
            }
          }
          if (oInstruction.getType() == AbstractInsnNode.METHOD_INSN) {
            MethodInsnNode mi = (MethodInsnNode) oInstruction;
            if (mi.getOpcode() == INVOKESPECIAL && mi.name.equals("<init>")) {
              if (oUninitCount == 0) {
                // this is the one!
                oInvokeSpecialDescriptor = mi.desc;
              } else {
                oUninitCount--;
              }
            }
          }
          if (nInstruction.getType() == AbstractInsnNode.METHOD_INSN) {
            MethodInsnNode mi = (MethodInsnNode) nInstruction;
            if (mi.getOpcode() == INVOKESPECIAL && mi.name.equals("<init>")) {
              if (nUninitCount == 0) {
                // this is the one!
                nInvokeSpecialDescriptor = mi.desc;
View Full Code Here

     *            part of this subroutine or any previously computed subroutine.
     */
    private void markSubroutineWalkDFS(final BitSet sub, int index,
            final BitSet anyvisited) {
        while (true) {
            AbstractInsnNode node = instructions.get(index);

            // don't visit a node twice
            if (sub.get(index)) {
                return;
            }
            sub.set(index);

            // check for those nodes already visited by another subroutine
            if (anyvisited.get(index)) {
                dualCitizens.set(index);
                if (LOGGING) {
                    log("Instruction #" + index + " is dual citizen.");
                }
            }
            anyvisited.set(index);

            if (node.getType() == AbstractInsnNode.JUMP_INSN
                    && node.getOpcode() != JSR) {
                // we do not follow recursively called subroutines here; but any
                // other sort of branch we do follow
                JumpInsnNode jnode = (JumpInsnNode) node;
                int destidx = instructions.indexOf(jnode.label);
                markSubroutineWalkDFS(sub, destidx, anyvisited);
            }
            if (node.getType() == AbstractInsnNode.TABLESWITCH_INSN) {
                TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
                int destidx = instructions.indexOf(tsnode.dflt);
                markSubroutineWalkDFS(sub, destidx, anyvisited);
                for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
                    LabelNode l = tsnode.labels.get(i);
                    destidx = instructions.indexOf(l);
                    markSubroutineWalkDFS(sub, destidx, anyvisited);
                }
            }
            if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
                LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
                int destidx = instructions.indexOf(lsnode.dflt);
                markSubroutineWalkDFS(sub, destidx, anyvisited);
                for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
                    LabelNode l = lsnode.labels.get(i);
View Full Code Here

        }

        // Emit the relevant instructions for this instantiation, translating
        // labels and jump targets as we go:
        for (int i = 0, c = instructions.size(); i < c; i++) {
            AbstractInsnNode insn = instructions.get(i);
            Instantiation owner = instant.findOwner(i);

            // Always remap labels:
            if (insn.getType() == AbstractInsnNode.LABEL) {
                // Translate labels into their renamed equivalents.
                // Avoid adding the same label more than once. Note
                // that because we own this instruction the gotoTable
                // and the rangeTable will always agree.
                LabelNode ilbl = (LabelNode) insn;
                LabelNode remap = instant.rangeLabel(ilbl);
                if (LOGGING) {
                    // TODO use of default toString().
                    log("Translating lbl #" + i + ':' + ilbl + " to " + remap);
                }
                if (remap != duplbl) {
                    newInstructions.add(remap);
                    duplbl = remap;
                }
                continue;
            }

            // We don't want to emit instructions that were already
            // emitted by a subroutine higher on the stack. Note that
            // it is still possible for a given instruction to be
            // emitted twice because it may belong to two subroutines
            // that do not invoke each other.
            if (owner != instant) {
                continue;
            }

            if (LOGGING) {
                log("Emitting inst #" + i);
            }

            if (insn.getOpcode() == RET) {
                // Translate RET instruction(s) to a jump to the return label
                // for the appropriate instantiation. The problem is that the
                // subroutine may "fall through" to the ret of a parent
                // subroutine; therefore, to find the appropriate ret label we
                // find the lowest subroutine on the stack that claims to own
                // this instruction. See the class javadoc comment for an
                // explanation on why this technique is safe (note: it is only
                // safe if the input is verifiable).
                LabelNode retlabel = null;
                for (Instantiation p = instant; p != null; p = p.previous) {
                    if (p.subroutine.get(i)) {
                        retlabel = p.returnLabel;
                    }
                }
                if (retlabel == null) {
                    // This is only possible if the mainSubroutine owns a RET
                    // instruction, which should never happen for verifiable
                    // code.
                    throw new RuntimeException("Instruction #" + i
                            + " is a RET not owned by any subroutine");
                }
                newInstructions.add(new JumpInsnNode(GOTO, retlabel));
            } else if (insn.getOpcode() == JSR) {
                LabelNode lbl = ((JumpInsnNode) insn).label;
                BitSet sub = subroutineHeads.get(lbl);
                Instantiation newinst = new Instantiation(instant, sub);
                LabelNode startlbl = newinst.gotoLabel(lbl);

                if (LOGGING) {
                    log(" Creating instantiation of subr " + sub);
                }

                // Rather than JSRing, we will jump to the inline version and
                // push NULL for what was once the return value. This hack
                // allows us to avoid doing any sort of data flow analysis to
                // figure out which instructions manipulate the old return value
                // pointer which is now known to be unneeded.
                newInstructions.add(new InsnNode(ACONST_NULL));
                newInstructions.add(new JumpInsnNode(GOTO, startlbl));
                newInstructions.add(newinst.returnLabel);

                // Insert this new instantiation into the queue to be emitted
                // later.
                worklist.add(newinst);
            } else {
                newInstructions.add(insn.clone(instant));
            }
        }

        // Emit try/catch blocks that are relevant to this method.
        for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it
View Full Code Here

            // this is fairly common as we are often ignoring large chunks of
            // instructions, so what were previously distinct labels become
            // duplicates.
            LabelNode duplbl = null;
            for (int i = 0, c = instructions.size(); i < c; i++) {
                AbstractInsnNode insn = instructions.get(i);

                if (insn.getType() == AbstractInsnNode.LABEL) {
                    LabelNode ilbl = (LabelNode) insn;

                    if (duplbl == null) {
                        // if we already have a label pointing at this spot,
                        // don't recreate it.
View Full Code Here

        }
    }

    /** Break apart large switch instructions so that they may fit in a fragment. Runs before {@link getInstructions} because it changes instruction sequence. */
    private void splitSwitches() {
        AbstractInsnNode ptr = instructions.getFirst();

        while (ptr != null) {
            int cutoff = 0;
            AbstractInsnNode left = null, right = null;

            switch (ptr.getType()) {
                case AbstractInsnNode.LOOKUPSWITCH_INSN:
                    {
                        LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) ptr;
View Full Code Here

        for (AbstractInsnNode n = instructions.getFirst(); n != null; n = n.getNext()) {
            insnMap.put(n, tempInsnList.size());
            if (isRealInsn(n)) tempInsnList.add(n);
            if (n.getType() == AbstractInsnNode.LINE) {
                LineNumberNode nn = (LineNumberNode) n;
                AbstractInsnNode start = nn.start;
                while (start != null && !isRealInsn(start)) start = start.getNext();
                linesMap.put(start, nn.line);
            }
        }
        insnList = tempInsnList.toArray(new AbstractInsnNode[0]);
View Full Code Here

        successors = new ControlEdge[insnList.length][];


        for (int insnNo = 0; insnNo < insnList.length; insnNo++) {
            AbstractInsnNode node = insnList[insnNo];

            List<ControlEdge> succTemp = new ArrayList< >();
            succTemps[insnNo] = succTemp;

            switch (node.getType()) {
                case AbstractInsnNode.JUMP_INSN:
                    JumpInsnNode ji = (JumpInsnNode) node;
                    succTemp.add(new ControlEdge(insnNo, insnMap.get(ji.label), null));
                    if (node.getOpcode() != Opcodes.GOTO)
                        succTemp.add(new ControlEdge(insnNo, insnNo+1, null));
                    break;

                case AbstractInsnNode.TABLESWITCH_INSN:
                    TableSwitchInsnNode tsi = (TableSwitchInsnNode) node;
                    succTemp.add(new ControlEdge(insnNo, insnMap.get(tsi.dflt), null));
                    for (int i = 0; i  < tsi.labels.size(); i++)
                        succTemp.add(new ControlEdge(insnNo, insnMap.get(tsi.labels.get(i)), null));
                    break;

                case AbstractInsnNode.LOOKUPSWITCH_INSN:
                    LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) node;
                    succTemp.add(new ControlEdge(insnNo, insnMap.get(lsi.dflt), null));
                    for (int i = 0; i  < lsi.labels.size(); i++)
                        succTemp.add(new ControlEdge(insnNo, insnMap.get(lsi.labels.get(i)), null));
                    break;

                default:
                    int opcode = node.getOpcode();

                    if (! (opcode == Opcodes.ATHROW || opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN))
                        succTemp.add(new ControlEdge(insnNo, insnNo+1, null));
                    break;
            }
View Full Code Here

        baselineSize = new int[insnList.length+1];

        int accum=0;

        for (int i = 0; i < insnList.length; i++) {
            AbstractInsnNode ai = insnList[i];
            MethodInsnNode mi;
            int size = insnSize(ai);

            // some of these require special handling
            switch (ai.getOpcode()) {
                case Opcodes.RETURN:
                    // iconst_m1; ireturn
                    size = 2;
                    break;
                case Opcodes.IRETURN:
View Full Code Here

    private String[] box_types = new String[] { "java/lang/Integer", "java/lang/Long", "java/lang/Float", "java/lang/Double" };
    private String[] box_descs = new String[] { "(I)V", "(J)V", "(F)V", "(D)V" };

    private void emitFragmentInsn(MethodVisitor v, int iix, int begin, Label[] insnLabels, Map<Integer,Label> exitTrampolineLabels, Set<String> spilledUTypes) {
        v.visitLabel(insnLabels[iix - begin]);
        AbstractInsnNode ai = insnList[iix];

        // some instructions require very special handling
        int opc = ai.getOpcode();
        if (opc == Opcodes.RETURN) {
            v.visitInsn(Opcodes.ICONST_M1);
            v.visitInsn(Opcodes.IRETURN);
            return;
        }

        if (opc >= Opcodes.IRETURN && opc <= Opcodes.ARETURN) {
            int t = opc - Opcodes.IRETURN;
            v.visitVarInsn(Opcodes.ISTORE + t, nlocal+1);
            v.visitVarInsn(Opcodes.ALOAD, nlocal);
            v.visitInsn(Opcodes.ICONST_0);
            if (opc != Opcodes.ARETURN) {
                v.visitTypeInsn(Opcodes.NEW, box_types[t]);
                v.visitInsn(Opcodes.DUP);
                v.visitVarInsn(Opcodes.ILOAD + t, nlocal+1);
                v.visitMethodInsn(Opcodes.INVOKESPECIAL, box_types[t], "<init>", box_descs[t]);
            } else {
                v.visitVarInsn(Opcodes.ILOAD + t, nlocal+1);
            }
            v.visitInsn(Opcodes.AASTORE);
            v.visitInsn(Opcodes.ICONST_M1);
            v.visitInsn(Opcodes.IRETURN);
            return;
        }

        if (opc == Opcodes.NEW) {
            Frame f = types[iix+1];
            if (spilledUTypes.contains(f.stack[f.sp-1])) {
                v.visitInsn(Opcodes.ACONST_NULL);
                return;
            }
        }

        if (opc == Opcodes.INVOKESPECIAL) {
            MethodInsnNode mi = (MethodInsnNode)ai;
            Frame f1 = types[iix];
            Frame f2 = types[iix+1];
            String uninit = f1.stack[f2.sp];
            if (mi.name.equals("<init>") && spilledUTypes.contains(uninit)) {
                if (!f2.stack[f2.sp-1].equals(uninit)) throw new RuntimeException("general case of INVOKESPECIAL spill not implemented");
                for (int i = 0; i < f2.sp-1; i++) if (f2.stack[i].equals(uninit)) throw new RuntimeException("general case of INVOKESPECIAL spill not implemented");

                int ltmp = nlocal+1;
                int argc = Type.getArgumentTypes(mi.desc).length;
                int[] spillarg = new int[argc];

                for (int d = 0; d < argc; d++) {
                    char ty0 = f1.stack[f1.sp-d-1].charAt(0);

                    spillarg[d] = ltmp;
                    v.visitVarInsn(ty0 == 'D' ? Opcodes.DSTORE : ty0 == 'J' ? Opcodes.LSTORE : ty0 == 'I' ? Opcodes.ISTORE : ty0 == 'F' ? Opcodes.FSTORE : Opcodes.ASTORE, ltmp);
                    ltmp += (ty0 == 'D' || ty0 == 'J') ? 2 : 1;
                }
                v.visitInsn(Opcodes.POP2);
                v.visitTypeInsn(Opcodes.NEW, mi.owner);
                v.visitInsn(Opcodes.DUP);

                for (int d = argc-1; d >= 0; d++) {
                    char ty0 = f1.stack[f1.sp-d-1].charAt(0);
                    v.visitVarInsn(ty0 == 'D' ? Opcodes.DLOAD : ty0 == 'J' ? Opcodes.LLOAD : ty0 == 'I' ? Opcodes.ILOAD : ty0 == 'F' ? Opcodes.FLOAD : Opcodes.ALOAD, spillarg[d]);
                }

                v.visitMethodInsn(Opcodes.INVOKESPECIAL, mi.owner, mi.name, mi.desc);
                return;
            }
        }

        // all other instructions can be processed normally, perhaps with some control-flow fudging

        switch (ai.getType()) {
            case AbstractInsnNode.JUMP_INSN:
                {
                    JumpInsnNode ji = (JumpInsnNode)ai;
                    v.visitJumpInsn(opc, mapLabel(ji.label, begin, insnLabels, exitTrampolineLabels));
                    break;
                }
            case AbstractInsnNode.TABLESWITCH_INSN:
                {
                    TableSwitchInsnNode si = (TableSwitchInsnNode)ai;
                    Label[] mapped = new Label[si.labels.size()];
                    for (int i = 0; i < mapped.length; i++)
                        mapped[i] = mapLabel((LabelNode)si.labels.get(i), begin, insnLabels, exitTrampolineLabels);
                    v.visitTableSwitchInsn(si.min, si.max, mapLabel(si.dflt, begin, insnLabels, exitTrampolineLabels), mapped);
                    break;
                }
            case AbstractInsnNode.LOOKUPSWITCH_INSN:
                {
                    LookupSwitchInsnNode si = (LookupSwitchInsnNode)ai;
                    Label[] mapped = new Label[si.labels.size()];
                    for (int i = 0; i < mapped.length; i++)
                        mapped[i] = mapLabel((LabelNode)si.labels.get(i), begin, insnLabels, exitTrampolineLabels);
                    int[] keys = new int[si.keys.size()];
                    for (int i = 0; i < keys.length; i++)
                        keys[i] = (int)si.keys.get(i);
                    v.visitLookupSwitchInsn(mapLabel(si.dflt, begin, insnLabels, exitTrampolineLabels), keys, mapped);
                    break;
                }
            default:
                ai.accept(v);
                break;
        }
    }
View Full Code Here

TOP

Related Classes of org.objectweb.asm.tree.AbstractInsnNode

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.