Skip to content

Commit

Permalink
Unhardcode original call args
Browse files Browse the repository at this point in the history
  • Loading branch information
Su5eD committed Jan 24, 2024
1 parent 90d8d57 commit afc16b7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public ClassPatchBuilder divertRedirector(Consumer<InstructionAdapter> patcher)
@Override
public ClassPatchBuilder updateRedirectTarget(String originalTarget, String newTarget) {
return targetInjectionPoint(originalTarget)
.transform(new ModifyDelegatingRedirect(
.transform(new ModifyRedirectToWrapper(
MethodQualifier.create(originalTarget).orElseThrow(),
MethodQualifier.create(newTarget).orElseThrow()
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import dev.su5ed.sinytra.adapter.patch.api.MethodTransform;
import dev.su5ed.sinytra.adapter.patch.transformer.ModifyMethodParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public record ModifyDelegatingRedirect(MethodQualifier originalTarget, MethodQualifier newTarget) implements MethodTransform {
public record ModifyRedirectToWrapper(MethodQualifier originalTarget, MethodQualifier newTarget) implements MethodTransform {
private static final Type OPERATION_TYPE = Type.getObjectType("com/llamalad7/mixinextras/injector/wrapoperation/Operation");

@Override
Expand Down Expand Up @@ -55,28 +52,41 @@ public Patch.Result apply(ClassNode classNode, MethodNode methodNode, MethodCont
}
}

Type returnType = Type.getReturnType(this.newTarget.desc());
List<Type> args = ImmutableList.<Type>builder()
.add(sameOwnerType ? new Type[0] : new Type[]{newOwnerType})
.add(Type.getArgumentTypes(this.newTarget.desc()))
.build();
ModifyMethodParams patch = ModifyMethodParams.builder()
ModifyMethodParams removeOldParamsPatch = ModifyMethodParams.builder()
.chain(b -> {
for (int i = offset; i < Type.getArgumentTypes(methodNode.desc).length; i++) {
b.remove(i);
}
b.insert(1, OPERATION_TYPE);
for (Type type : Lists.reverse(args)) {
b.insert(1, type);
})
.ignoreOffset()
.build();
removeOldParamsPatch.apply(classNode, methodNode, methodContext, context);

List<Type> args = Lists.reverse(ImmutableList.<Type>builder()
.add(sameOwnerType ? new Type[0] : new Type[]{newOwnerType})
.add(Type.getArgumentTypes(this.newTarget.desc()))
.build());
ModifyMethodParams addNewParamsPatch = ModifyMethodParams.builder()
.chain(b -> {
for (int i = 0; i < args.size(); i++) {
Type type = args.get(i);
b.insert(i, type);
}
b.insert(args.size(), OPERATION_TYPE);
})
.ignoreOffset()
.build();
patch.apply(classNode, methodNode, methodContext, context);
addNewParamsPatch.apply(classNode, methodNode, methodContext, context);

LocalVariableLookup updatedLookup = new LocalVariableLookup(methodNode.localVariables);
List<LocalVariableNode> localVars = List.of(updatedLookup.getByOrdinal(1)); // TODO Unhardcode
LocalVariableNode operationVar = updatedLookup.getForType(OPERATION_TYPE).get(0);
int operationParamOrdinal = updatedLookup.getOrdinal(operationVar);
List<LocalVariableNode> localVars = new ArrayList<>();
for (int i = 1; i < operationParamOrdinal; i++) {
localVars.add(updatedLookup.getByOrdinal(i));
}
InsnList originalCallInsns = AdapterUtil.insnsWithAdapter(a -> {
a.load(offset + 2, OPERATION_TYPE);
a.load(operationVar.index, OPERATION_TYPE);
a.iconst(localVars.size());
a.newarray(Type.getObjectType("java/lang/Object"));
for (int i = 0; i < localVars.size(); i++) {
Expand All @@ -89,7 +99,7 @@ public Patch.Result apply(ClassNode classNode, MethodNode methodNode, MethodCont
a.visitInsn(Opcodes.AASTORE);
}
a.invokeinterface("com/llamalad7/mixinextras/injector/wrapoperation/Operation", "call", "([Ljava/lang/Object;)Ljava/lang/Object;");
OpcodeUtil.castObjectType(returnType, a);
OpcodeUtil.castObjectType(Type.getReturnType(this.newTarget.desc()), a);
});
for (List<AbstractInsnNode> list : insns) {
methodNode.instructions.insertBefore(list.get(0), originalCallInsns);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public List<LocalVariableNode> getForType(LocalVariableNode node) {

public List<LocalVariableNode> getForType(Type type) {
return this.byType.computeIfAbsent(type, t -> this.sortedLocals.stream()
.filter(l -> Type.getType(l.desc) == type)
.filter(l -> Type.getType(l.desc).equals(type))
.toList());
}

Expand Down

0 comments on commit afc16b7

Please sign in to comment.