Package org.deuce.objectweb.asm.tree

Examples of org.deuce.objectweb.asm.tree.LabelNode


     * Detects a JSR instruction and sets a flag to indicate we will need to do
     * inlining.
     */
    public void visitJumpInsn(final int opcode, final Label lbl) {
        super.visitJumpInsn(opcode, lbl);
        LabelNode ln = ((JumpInsnNode) instructions.getLast()).label;
        if (opcode == JSR && !subroutineHeads.containsKey(ln)) {
            subroutineHeads.put(ln, new Subroutine());
        }
    }
View Full Code Here


        // Go through the head of each subroutine and find any nodes reachable
        // to that subroutine without following any JSR links.
        for (Iterator it = subroutineHeads.entrySet().iterator(); it.hasNext();)
        {
            Map.Entry entry = (Map.Entry) it.next();
            LabelNode lab = (LabelNode) entry.getKey();
            Subroutine sub = (Subroutine) entry.getValue();
            int index = instructions.indexOf(lab);
            markSubroutineWalk(sub, index, anyvisited);
        }
    }
View Full Code Here

            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 = (LabelNode) 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 = (LabelNode) lsnode.labels.get(i);
                    destidx = instructions.indexOf(l);
                    markSubroutineWalkDFS(sub, destidx, anyvisited);
                }
            }
View Full Code Here

        final List worklist,
        final InsnList newInstructions,
        final List newTryCatchBlocks,
        final List newLocalVariables)
    {
        LabelNode duplbl = null;

        if (LOGGING) {
            log("--------------------------------------------------------");
            log("Emitting instantiation of subroutine " + instant.subroutine);
        }

        // 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.ownsInstruction(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;
                Subroutine sub = (Subroutine) 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 it = tryCatchBlocks.iterator(); it.hasNext();) {
            TryCatchBlockNode trycatch = (TryCatchBlockNode) it.next();

            if (LOGGING) {
                // TODO use of default toString().
                log("try catch block original labels=" + trycatch.start + '-'
                        + trycatch.end + "->" + trycatch.handler);
            }

            final LabelNode start = instant.rangeLabel(trycatch.start);
            final LabelNode end = instant.rangeLabel(trycatch.end);

            // Ignore empty try/catch regions
            if (start == end) {
                if (LOGGING) {
                    log(" try catch block empty in this subroutine");
                }
                continue;
            }

            final LabelNode handler = instant.gotoLabel(trycatch.handler);

            if (LOGGING) {
                // TODO use of default toString().
                log(" try catch block new labels=" + start + '-' + end + "->"
                        + handler);
            }

            if (start == null || end == null || handler == null) {
                throw new RuntimeException("Internal error!");
            }

            newTryCatchBlocks.add(new TryCatchBlockNode(start,
                    end,
                    handler,
                    trycatch.type));
        }

        for (Iterator it = localVariables.iterator(); it.hasNext();) {
            LocalVariableNode lvnode = (LocalVariableNode) it.next();
            if (LOGGING) {
                log("local var " + lvnode.name);
            }
            final LabelNode start = instant.rangeLabel(lvnode.start);
            final LabelNode end = instant.rangeLabel(lvnode.end);
            if (start == end) {
                if (LOGGING) {
                    log("  local variable empty in this sub");
                }
                continue;
View Full Code Here

            }

            // Determine the label to return to when this subroutine terminates
            // via RET: note that the main subroutine never terminates via RET.
            if (prev != null) {
                returnLabel = new LabelNode();
            } else {
                returnLabel = null;
            }

            // Each instantiation will remap the labels from the code above to
            // refer to its particular copy of its own instructions. Note that
            // we collapse labels which point at the same instruction into one:
            // 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.
                        duplbl = new LabelNode();
                    }

                    // Add an entry in the rangeTable for every label
                    // in the original code which points at the next
                    // instruction of our own to be emitted.
View Full Code Here

                        LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
                        int jump = insns.indexOf(lsi.dflt);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                        for (int j = 0; j < lsi.labels.size(); ++j) {
                            LabelNode label = (LabelNode) lsi.labels.get(j);
                            jump = insns.indexOf(label);
                            merge(jump, current, subroutine);
                            newControlFlowEdge(insn, jump);
                        }
                    } else if (insnNode instanceof TableSwitchInsnNode) {
                        TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
                        int jump = insns.indexOf(tsi.dflt);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                        for (int j = 0; j < tsi.labels.size(); ++j) {
                            LabelNode label = (LabelNode) tsi.labels.get(j);
                            jump = insns.indexOf(label);
                            merge(jump, current, subroutine);
                            newControlFlowEdge(insn, jump);
                        }
                    } else if (insnOpcode == RET) {
View Full Code Here

                }
            } else if (node instanceof TableSwitchInsnNode) {
                TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
                findSubroutine(insns.indexOf(tsnode.dflt), sub, calls);
                for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
                    LabelNode l = (LabelNode) tsnode.labels.get(i);
                    findSubroutine(insns.indexOf(l), sub, calls);
                }
            } else if (node instanceof LookupSwitchInsnNode) {
                LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
                findSubroutine(insns.indexOf(lsnode.dflt), sub, calls);
                for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
                    LabelNode l = (LabelNode) lsnode.labels.get(i);
                    findSubroutine(insns.indexOf(l), sub, calls);
                }
            }

            // calls findSubroutine recursively on exception handler successors
View Full Code Here

TOP

Related Classes of org.deuce.objectweb.asm.tree.LabelNode

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.