diff --git a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/ModifyMethodParams.java b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/ModifyMethodParams.java index 8f2dcc9..da6efe5 100644 --- a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/ModifyMethodParams.java +++ b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/ModifyMethodParams.java @@ -14,6 +14,7 @@ import dev.su5ed.sinytra.adapter.patch.fixes.BytecodeFixerUpper; import dev.su5ed.sinytra.adapter.patch.fixes.TypeAdapter; import dev.su5ed.sinytra.adapter.patch.selector.AnnotationHandle; +import dev.su5ed.sinytra.adapter.patch.transformer.param.ParameterTransformer; import dev.su5ed.sinytra.adapter.patch.util.AdapterUtil; import dev.su5ed.sinytra.adapter.patch.util.LocalVariableLookup; import dev.su5ed.sinytra.adapter.patch.util.MethodQualifier; @@ -185,8 +186,8 @@ public Result apply(ClassNode classNode, MethodNode methodNode, MethodContext me LOGGER.info("Substituting parameter {} for {} in {}.{}", paramIndex, substituteParamIndex, classNode.name, methodNode.name); methodNode.parameters.remove(paramIndex); newParameterTypes.remove(paramIndex); - int substituteIndex = calculateLVTIndex(newParameterTypes, isNonStatic, substituteParamIndex); methodNode.localVariables.removeIf(lvn -> lvn.index == localIndex); + int substituteIndex = ParameterTransformer.calculateLocalLVTIndex(methodNode.localVariables, isNonStatic, substituteParamIndex); for (AbstractInsnNode insn : methodNode.instructions) { SingleValueHandle handle = AdapterUtil.handleLocalVarInsnValue(insn); if (handle == null) continue; diff --git a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/ParameterTransformer.java b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/ParameterTransformer.java index 585b993..58c08ed 100644 --- a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/ParameterTransformer.java +++ b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/ParameterTransformer.java @@ -16,6 +16,7 @@ import org.objectweb.asm.tree.*; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -238,6 +239,17 @@ static int calculateLVTIndex(List parameters, boolean nonStatic, int index return lvt; } + static int calculateLocalLVTIndex(List locals, boolean nonStatic, int index) { + locals = new ArrayList<>(locals); + locals.sort(Comparator.comparing(l -> l.index)); + if (nonStatic) locals.remove(0); + int lvt = nonStatic ? 1 : 0; + for (int i = 0; i < index; i++) { + lvt += Type.getType(locals.get(i).desc).getSize(); + } + return lvt; + } + default Codec codec() { throw new UnsupportedOperationException("This transform is not serializable"); } diff --git a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/SubstituteParameterTransformer.java b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/SubstituteParameterTransformer.java index 9c8f0b6..7983862 100644 --- a/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/SubstituteParameterTransformer.java +++ b/definition/src/main/java/dev/su5ed/sinytra/adapter/patch/transformer/param/SubstituteParameterTransformer.java @@ -27,7 +27,7 @@ public Patch.Result apply(ClassNode classNode, MethodNode methodNode, MethodCont final int paramIndex = this.target + offset; final int substituteParamIndex = this.substitute + offset; final boolean isNonStatic = !methodContext.isStatic(methodNode); - final int localIndex = ParameterTransformer.calculateLVTIndex(parameters, isNonStatic, paramIndex); + final int localIndex = ParameterTransformer.calculateLocalLVTIndex(methodNode.localVariables, isNonStatic, paramIndex); if (methodNode.parameters.size() <= paramIndex) { return Patch.Result.PASS; @@ -35,11 +35,13 @@ public Patch.Result apply(ClassNode classNode, MethodNode methodNode, MethodCont withLVTSnapshot(methodNode, () -> { LOGGER.info("Substituting parameter {} for {} in {}.{}", paramIndex, substituteParamIndex, classNode.name, methodNode.name); - parameters.remove(paramIndex); - methodNode.parameters.remove(paramIndex); - methodNode.localVariables.removeIf(lvn -> lvn.index == localIndex); + if (paramIndex < parameters.size()) { + parameters.remove(paramIndex); + methodNode.parameters.remove(paramIndex); + } - final int substituteIndex = ParameterTransformer.calculateLVTIndex(parameters, isNonStatic, substituteParamIndex); + final int substituteIndex = ParameterTransformer.calculateLocalLVTIndex(methodNode.localVariables, isNonStatic, substituteParamIndex); + methodNode.localVariables.removeIf(lvn -> lvn.index == localIndex); AdapterUtil.replaceLVT(methodNode, idx -> idx == localIndex ? substituteIndex : idx); });