Skip to content

Commit aa1414e

Browse files
committed
Pull out value replacement method in ReFrame
1 parent 1ced047 commit aa1414e

File tree

2 files changed

+48
-22
lines changed

2 files changed

+48
-22
lines changed

recaf-core/src/main/java/software/coley/recaf/util/analysis/ReEvaluator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public ReValue evaluate(@Nonnull ClassNode classNode,
227227
private static class ExecutingFrame extends ReFrame implements Opcodes {
228228
private AbstractInsnNode next;
229229
private ReValue returnValue;
230-
private boolean isStatic;
230+
private final boolean isStatic;
231231

232232
public ExecutingFrame(@Nonnull MethodNode method) {
233233
super(method.maxLocals, method.maxStack);
Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package software.coley.recaf.util.analysis;
22

3+
import jakarta.annotation.Nonnull;
34
import org.objectweb.asm.Opcodes;
45
import org.objectweb.asm.tree.AbstractInsnNode;
56
import org.objectweb.asm.tree.analysis.AnalyzerException;
@@ -14,11 +15,25 @@
1415
* @author Matt Coley
1516
*/
1617
public class ReFrame extends Frame<ReValue> {
18+
/**
19+
* New frame with the given number of expected locals/stack-slots.
20+
*
21+
* @param numLocals
22+
* Available local variable slots.
23+
* @param maxStack
24+
* Available stack slots.
25+
*/
1726
public ReFrame(int numLocals, int maxStack) {
1827
super(numLocals, maxStack);
1928
}
2029

21-
public ReFrame(Frame<? extends ReValue> frame) {
30+
/**
31+
* New frame copying the state of the given frame.
32+
*
33+
* @param frame
34+
* Frame to copy stack/locals of.
35+
*/
36+
public ReFrame(@Nonnull Frame<? extends ReValue> frame) {
2237
super(frame);
2338
}
2439

@@ -38,29 +53,40 @@ public void execute(AbstractInsnNode insn, Interpreter<ReValue> interpreter) thr
3853
ReValue index = pop();
3954
ReValue array = pop();
4055
ReValue updatedArray = interpreter.ternaryOperation(insn, array, index, value);
41-
if (updatedArray != array) {
42-
for (int i = 0; i < getStackSize(); i++) {
43-
ReValue stack = getStack(i);
44-
if (stack == array) {
45-
setStack(i, updatedArray);
46-
} else if (stack instanceof ArrayValue stackArray) {
47-
ArrayValue updatedStackArray = stackArray.updatedCopyIfContained(array, updatedArray);
48-
setStack(i, updatedStackArray);
49-
}
50-
}
51-
for (int i = 0; i < getLocals(); i++) {
52-
ReValue local = getLocal(i);
53-
if (local == array) {
54-
setLocal(i, updatedArray);
55-
} else if (local instanceof ArrayValue stackArray) {
56-
ArrayValue updatedStackArray = stackArray.updatedCopyIfContained(array, updatedArray);
57-
setLocal(i, updatedStackArray);
58-
}
59-
}
60-
}
56+
if (updatedArray != array)
57+
replaceValue(array, updatedArray);
6158
break;
6259
default:
6360
super.execute(insn, interpreter);
6461
}
6562
}
63+
64+
/**
65+
* Replace all references to the given value with the replacement.
66+
*
67+
* @param existing
68+
* Some existing value that exists in this frame.
69+
* @param replacement
70+
* Instance to replace the existing value with.
71+
*/
72+
public void replaceValue(@Nonnull ReValue existing, @Nonnull ReValue replacement) {
73+
for (int i = 0; i < getStackSize(); i++) {
74+
ReValue stack = getStack(i);
75+
if (stack == existing) {
76+
setStack(i, replacement);
77+
} else if (stack instanceof ArrayValue stackArray) {
78+
ArrayValue updatedStackArray = stackArray.updatedCopyIfContained(existing, replacement);
79+
setStack(i, updatedStackArray);
80+
}
81+
}
82+
for (int i = 0; i < getLocals(); i++) {
83+
ReValue local = getLocal(i);
84+
if (local == existing) {
85+
setLocal(i, replacement);
86+
} else if (local instanceof ArrayValue stackArray) {
87+
ArrayValue updatedStackArray = stackArray.updatedCopyIfContained(existing, replacement);
88+
setLocal(i, updatedStackArray);
89+
}
90+
}
91+
}
6692
}

0 commit comments

Comments
 (0)