Remap lambda calls

This commit is contained in:
IzzelAliz 2021-01-23 17:03:16 +08:00
parent a491fdc83b
commit 414085d5da

View File

@ -5,10 +5,12 @@ import io.izzel.arclight.common.mod.ArclightMod;
import io.izzel.arclight.common.mod.util.remapper.generated.ArclightReflectionHandler; import io.izzel.arclight.common.mod.util.remapper.generated.ArclightReflectionHandler;
import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.MarkerManager;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
@ -129,20 +131,22 @@ public class ArclightRedirectAdapter implements PluginTransformer {
AbstractInsnNode insnNode = iterator.next(); AbstractInsnNode insnNode = iterator.next();
if (insnNode instanceof MethodInsnNode) { if (insnNode instanceof MethodInsnNode) {
MethodInsnNode from = (MethodInsnNode) insnNode; MethodInsnNode from = (MethodInsnNode) insnNode;
for (Map.Entry<MethodInsnNode, MethodInsnNode> entry : METHOD_REDIRECTS.entrySet()) { MethodInsnNode newNode = find(from, generatedOwner);
MethodInsnNode key = entry.getKey(); if (newNode != null) {
if ( iterator.set(newNode);
key.getOpcode() == from.getOpcode() && }
Objects.equals(key.owner, from.owner) && } else if (insnNode.getOpcode() == Opcodes.INVOKEDYNAMIC) {
Objects.equals(key.name, from.name) && InvokeDynamicInsnNode invokeDynamic = (InvokeDynamicInsnNode) insnNode;
Objects.equals(key.desc, from.desc)) { Object[] bsmArgs = invokeDynamic.bsmArgs;
MethodInsnNode to = entry.getValue(); for (int i = 0; i < bsmArgs.length; i++) {
if (REPLACED_NAME.equals(to.owner)) { Object bsmArg = bsmArgs[i];
MethodInsnNode clone = (MethodInsnNode) to.clone(ImmutableMap.of()); if (bsmArg instanceof Handle) {
clone.owner = generatedOwner; Handle handle = (Handle) bsmArg;
iterator.set(clone); if (toOpcode(handle.getTag()) != -1) {
} else { MethodInsnNode node = find(handle, generatedOwner);
iterator.set(to); if (node != null) {
bsmArgs[i] = new Handle(toHandle(node.getOpcode()), node.owner, node.name, node.desc, node.itf);
}
} }
} }
} }
@ -170,6 +174,48 @@ public class ArclightRedirectAdapter implements PluginTransformer {
} }
} }
private static MethodInsnNode find(Handle handle, String generatedOwner) {
for (Map.Entry<MethodInsnNode, MethodInsnNode> entry : METHOD_REDIRECTS.entrySet()) {
MethodInsnNode key = entry.getKey();
if (
key.getOpcode() == toOpcode(handle.getTag()) &&
Objects.equals(key.owner, handle.getOwner()) &&
Objects.equals(key.name, handle.getName()) &&
Objects.equals(key.desc, handle.getDesc())) {
MethodInsnNode to = entry.getValue();
if (REPLACED_NAME.equals(to.owner)) {
MethodInsnNode clone = (MethodInsnNode) to.clone(ImmutableMap.of());
clone.owner = generatedOwner;
return clone;
} else {
return to;
}
}
}
return null;
}
private static MethodInsnNode find(MethodInsnNode from, String generatedOwner) {
for (Map.Entry<MethodInsnNode, MethodInsnNode> entry : METHOD_REDIRECTS.entrySet()) {
MethodInsnNode key = entry.getKey();
if (
key.getOpcode() == from.getOpcode() &&
Objects.equals(key.owner, from.owner) &&
Objects.equals(key.name, from.name) &&
Objects.equals(key.desc, from.desc)) {
MethodInsnNode to = entry.getValue();
if (REPLACED_NAME.equals(to.owner)) {
MethodInsnNode clone = (MethodInsnNode) to.clone(ImmutableMap.of());
clone.owner = generatedOwner;
return clone;
} else {
return to;
}
}
}
return null;
}
private static MethodInsnNode method(int opcode, Class<?> cl, String name, Class<?>... pTypes) { private static MethodInsnNode method(int opcode, Class<?> cl, String name, Class<?>... pTypes) {
try { try {
return method(opcode, cl.getMethod(name, pTypes)); return method(opcode, cl.getMethod(name, pTypes));
@ -188,4 +234,30 @@ public class ArclightRedirectAdapter implements PluginTransformer {
String desc = Type.getMethodDescriptor(method); String desc = Type.getMethodDescriptor(method);
return new MethodInsnNode(opcode, owner, name, desc); return new MethodInsnNode(opcode, owner, name, desc);
} }
private static int toOpcode(int handleType) {
switch (handleType) {
case Opcodes.H_INVOKEINTERFACE:
return Opcodes.INVOKEINTERFACE;
case Opcodes.H_INVOKEVIRTUAL:
return Opcodes.INVOKEVIRTUAL;
case Opcodes.H_INVOKESTATIC:
return Opcodes.INVOKESTATIC;
default:
return -1;
}
}
private static int toHandle(int opcode) {
switch (opcode) {
case Opcodes.INVOKEINTERFACE:
return Opcodes.H_INVOKEINTERFACE;
case Opcodes.INVOKESTATIC:
return Opcodes.H_INVOKESTATIC;
case Opcodes.INVOKEVIRTUAL:
return Opcodes.H_INVOKEVIRTUAL;
default:
return -1;
}
}
} }