diff options
author | Eric Bruneton <ebruneton@free.fr> | 2022-05-26 11:57:47 +0000 |
---|---|---|
committer | Eric Bruneton <ebruneton@free.fr> | 2022-05-26 11:57:47 +0000 |
commit | 2607e4cb1256014487f565bf6c4c18e60a6d4366 (patch) | |
tree | e8c9976c314bfe46c1de09764837f3a6691905dd | |
parent | d51146fca938d353c96d1aa4781f83eb4a9657ac (diff) | |
download | ow2-asm-2607e4cb1256014487f565bf6c4c18e60a6d4366.tar.gz |
Extract a findSubroutines method from the long Analyzer.analyze() method.
-rw-r--r-- | asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java index 60c443fc..4c20ac16 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java @@ -132,32 +132,8 @@ public class Analyzer<V extends Value> implements Opcodes { } } - // For each instruction, compute the subroutine to which it belongs. - // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines. - Subroutine main = new Subroutine(null, method.maxLocals, null); - List<AbstractInsnNode> jsrInsns = new ArrayList<>(); - findSubroutine(0, main, jsrInsns); - // Follow the nested subroutines, and collect their own nested subroutines, until all - // subroutines are found. - Map<LabelNode, Subroutine> jsrSubroutines = new HashMap<>(); - while (!jsrInsns.isEmpty()) { - JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0); - Subroutine subroutine = jsrSubroutines.get(jsrInsn.label); - if (subroutine == null) { - subroutine = new Subroutine(jsrInsn.label, method.maxLocals, jsrInsn); - jsrSubroutines.put(jsrInsn.label, subroutine); - findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns); - } else { - subroutine.callers.add(jsrInsn); - } - } - // Clear the main 'subroutine', which is not a real subroutine (and was used only as an - // intermediate step above to find the real ones). - for (int i = 0; i < insnListSize; ++i) { - if (subroutines[i] != null && subroutines[i].start == null) { - subroutines[i] = null; - } - } + // Finds the method's subroutines. + findSubroutines(method.maxLocals); // Initializes the data structures for the control flow analysis. Frame<V> currentFrame = computeInitialFrame(owner, method); @@ -369,6 +345,42 @@ public class Analyzer<V extends Value> implements Opcodes { } /** + * Finds the subroutines of the currently analyzed method and stores them in {@link #subroutines}. + * + * @param maxLocals the maximum number of local variables of the currently analyzed method (long + * and double values count for two variables). + * @throws AnalyzerException if the control flow graph can fall off the end of the code. + */ + private void findSubroutines(final int maxLocals) throws AnalyzerException { + // For each instruction, compute the subroutine to which it belongs. + // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines. + Subroutine main = new Subroutine(null, maxLocals, null); + List<AbstractInsnNode> jsrInsns = new ArrayList<>(); + findSubroutine(0, main, jsrInsns); + // Follow the nested subroutines, and collect their own nested subroutines, until all + // subroutines are found. + Map<LabelNode, Subroutine> jsrSubroutines = new HashMap<>(); + while (!jsrInsns.isEmpty()) { + JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0); + Subroutine subroutine = jsrSubroutines.get(jsrInsn.label); + if (subroutine == null) { + subroutine = new Subroutine(jsrInsn.label, maxLocals, jsrInsn); + jsrSubroutines.put(jsrInsn.label, subroutine); + findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns); + } else { + subroutine.callers.add(jsrInsn); + } + } + // Clear the main 'subroutine', which is not a real subroutine (and was used only as an + // intermediate step above to find the real ones). + for (int i = 0; i < insnListSize; ++i) { + if (subroutines[i] != null && subroutines[i].start == null) { + subroutines[i] = null; + } + } + } + + /** * Follows the control flow graph of the currently analyzed method, starting at the given * instruction index, and stores a copy of the given subroutine in {@link #subroutines} for each * encountered instruction. Jumps to nested subroutines are <i>not</i> followed: instead, the |