Skip to content

Commit f7534f2

Browse files
committed
Make usedLocalNodes unique
Fix local ordinal resolution
1 parent 2c444de commit f7534f2

4 files changed

Lines changed: 20 additions & 16 deletions

File tree

core/src/main/java/org/sinytra/adapter/analysis/locals/LocalVarAnalyzer.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,16 @@
77
import org.jetbrains.annotations.Nullable;
88
import org.objectweb.asm.Type;
99
import org.objectweb.asm.tree.*;
10-
import org.sinytra.adapter.env.ctx.MixinContext;
11-
import org.sinytra.adapter.env.ctx.TargetPair;
1210
import org.sinytra.adapter.analysis.params.EnhancedParamsDiff;
1311
import org.sinytra.adapter.analysis.params.ParamsDiffSnapshot;
1412
import org.sinytra.adapter.env.ctx.LocalVariable;
13+
import org.sinytra.adapter.env.ctx.MixinContext;
14+
import org.sinytra.adapter.env.ctx.TargetPair;
1515
import org.sinytra.adapter.transform.param.TransformParameters;
1616
import org.sinytra.adapter.util.AdapterUtil;
1717
import org.sinytra.adapter.util.OpcodeUtil;
1818

19-
import java.util.ArrayList;
20-
import java.util.Collections;
21-
import java.util.List;
22-
import java.util.Map;
19+
import java.util.*;
2320
import java.util.stream.IntStream;
2421

2522
public final class LocalVarAnalyzer {
@@ -64,7 +61,7 @@ public static InsnList findInitializerInsns(MethodNode methodNode, int index) {
6461
public record CapturedLocalsUsage(LocalVariableLookup targetTable, Int2IntMap usageCount, Int2ObjectMap<InsnList> varInsnLists) {
6562
}
6663

67-
public record CapturedLocalsTransform(List<Integer> used, TransformParameters remover, List<LocalVariableNode> usedLocalNodes) {
64+
public record CapturedLocalsTransform(List<Integer> used, TransformParameters remover, Collection<LocalVariableNode> usedLocalNodes) {
6865
public CapturedLocalsUsage getUsage(AdapterUtil.CapturedLocals capturedLocals) {
6966
LocalVariableLookup targetTable = new LocalVariableLookup(capturedLocals.target().methodNode());
7067
Int2ObjectMap<InsnList> varInsnLists = new Int2ObjectOpenHashMap<>();
@@ -82,14 +79,15 @@ public static CapturedLocalsTransform analyzeCapturedLocals(AdapterUtil.Captured
8279
int paramLocalStart = capturedLocals.paramLocalStart();
8380
LocalVariableLookup table = capturedLocals.lvt();
8481
List<Integer> used = new ArrayList<>();
85-
List<LocalVariableNode> usedLocalNodes = new ArrayList<>();
82+
Set<LocalVariableNode> usedLocalNodes = new HashSet<>();
8683
for (AbstractInsnNode insn : methodNode.instructions) {
8784
if (insn instanceof VarInsnNode varInsn) {
8885
LocalVariableNode node = table.getByIndexOrNull(varInsn.var);
89-
if (node == null) {
86+
if (node == null)
9087
continue;
91-
}
9288
int ordinal = table.getParameterOrdinal(node);
89+
if (ordinal == -1)
90+
continue;
9391
if (ordinal >= paramLocalStart && ordinal <= capturedLocals.paramLocalEnd()) {
9492
used.add(ordinal);
9593
usedLocalNodes.add(node);

core/src/main/java/org/sinytra/adapter/analysis/locals/LocalVariableLookup.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
public class LocalVariableLookup {
1414
private final List<LocalVariableNode> sortedLocals;
1515
private final boolean isNonStatic;
16+
private final int lastParamLVTIndex;
1617
private final Int2ObjectMap<LocalVariableNode> byIndex = new Int2ObjectOpenHashMap<>();
1718
private final Map<Type, List<LocalVariableNode>> byType = new HashMap<>();
1819

@@ -22,6 +23,7 @@ public LocalVariableLookup(MethodNode methodNode) {
2223
for (LocalVariableNode node : this.sortedLocals) {
2324
this.byIndex.put(node.index, node);
2425
}
26+
this.lastParamLVTIndex = Type.getArgumentTypes(methodNode.desc).length + (this.isNonStatic ? 1 : 0);
2527
}
2628

2729
public LocalVariableNode getByOrdinal(int ordinal) {
@@ -46,6 +48,9 @@ public int getOrdinal(LocalVariableNode node) {
4648
}
4749

4850
public int getParameterOrdinal(LocalVariableNode node) {
51+
if (node.index > this.lastParamLVTIndex) {
52+
return -1;
53+
}
4954
return getOrdinal(node) - (this.isNonStatic ? 1 : 0);
5055
}
5156

core/src/main/java/org/sinytra/adapter/transform/preprocess/LocalCaptureUpgradeTransformer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ public PatchResult apply(MixinContext context, Configuration config) {
5959
if (cleanLocals.size() != dirtyLocals.size())
6060
return PatchResult.PASS;
6161

62-
List<LocalVariableNode> sameType = methodNode.localVariables.stream()
63-
.filter(l -> Type.getType(l.desc).equals(expected))
64-
.toList();
65-
int localOrdinal = sameType.indexOf(node);
62+
int localOrdinal = lookup.getTypedOrdinal(node).orElse(-1);
6663
if (localOrdinal == -1) return PatchResult.PASS;
6764

6865
int paramOrdinal = lookup.getParameterOrdinal(node);
69-
parameterToOrdinal.put(paramOrdinal, localOrdinal);
7066
usedOrdinals.add(paramOrdinal);
67+
68+
if (cleanLocals.size() > 1) {
69+
parameterToOrdinal.put(paramOrdinal, localOrdinal);
70+
}
7171
}
7272

7373
Type[] args = Type.getArgumentTypes(methodNode.desc);

core/src/main/java/org/sinytra/adapter/util/AdapterUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ public static CapturedLocals getCapturedLocals(MixinContext context, TargetPair
231231
int paramLocalPosVal = paramLocalPos.getAsInt();
232232
// Get expected local variables from method parameters
233233
List<Type> expected = AdapterUtil.summariseLocals(availableParams, paramLocalPosVal);
234-
return new CapturedLocals(dirtyTarget, isStatic, paramLocalPosVal, paramLocalPosVal + expected.size(), lvtOffset, expected, new LocalVariableLookup(methodNode));
234+
int paramLocalPosEnd = paramLocalPosVal + expected.size() - 1;
235+
return new CapturedLocals(dirtyTarget, isStatic, paramLocalPosVal, paramLocalPosEnd, lvtOffset, expected, new LocalVariableLookup(methodNode));
235236
}
236237

237238
private static OptionalInt getCapturedLocalStartingIndex(Type[] params) {

0 commit comments

Comments
 (0)