summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Bruneton <ebruneton@free.fr>2022-05-26 11:57:47 +0000
committerEric Bruneton <ebruneton@free.fr>2022-05-26 11:57:47 +0000
commit2607e4cb1256014487f565bf6c4c18e60a6d4366 (patch)
treee8c9976c314bfe46c1de09764837f3a6691905dd
parentd51146fca938d353c96d1aa4781f83eb4a9657ac (diff)
downloadow2-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.java64
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