From cd31f066b707da49117b480cb6e1375d5ce3dd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B0=D1=87?= Date: Wed, 17 Jun 2020 13:21:18 +0500 Subject: [PATCH 1/2] Allow @Invoker usage for interfaces --- .../asm/mixin/gen/AccessorGeneratorMethodProxy.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java b/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java index c8504c761..573d3d6c4 100644 --- a/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java +++ b/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java @@ -26,6 +26,7 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; @@ -38,9 +39,14 @@ public class AccessorGeneratorMethodProxy extends AccessorGenerator { /** - * The target field, identified by the accessor info + * The target method, identified by the accessor info */ protected final MethodNode targetMethod; + + /** + * Where original method was located + */ + protected final ClassNode methodLocation; /** * Accessor method argument types (raw, from method) @@ -55,6 +61,7 @@ public class AccessorGeneratorMethodProxy extends AccessorGenerator { public AccessorGeneratorMethodProxy(AccessorInfo info) { super(info, Bytecode.isStatic(info.getTargetMethod())); this.targetMethod = info.getTargetMethod(); + this.methodLocation = info.getClassNode(); this.argTypes = info.getArgTypes(); this.returnType = info.getReturnType(); this.checkModifiers(); @@ -63,6 +70,7 @@ public AccessorGeneratorMethodProxy(AccessorInfo info) { protected AccessorGeneratorMethodProxy(AccessorInfo info, boolean isStatic) { super(info, isStatic); this.targetMethod = info.getTargetMethod(); + this.methodLocation = info.getClassNode(); this.argTypes = info.getArgTypes(); this.returnType = info.getReturnType(); } @@ -76,7 +84,8 @@ public MethodNode generate() { } Bytecode.loadArgs(this.argTypes, method.instructions, this.targetIsStatic ? 0 : 1); boolean isPrivate = Bytecode.hasFlag(this.targetMethod, Opcodes.ACC_PRIVATE); - int opcode = this.targetIsStatic ? Opcodes.INVOKESTATIC : (isPrivate ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); + boolean isInterface = Bytecode.hasFlag(this.methodLocation, Opcodes.ACC_INTERFACE); + int opcode = this.targetIsStatic ? Opcodes.INVOKESTATIC : (isPrivate ? Opcodes.INVOKESPECIAL : (isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL)); method.instructions.add(new MethodInsnNode(opcode, this.info.getClassNode().name, this.targetMethod.name, this.targetMethod.desc, false)); method.instructions.add(new InsnNode(this.returnType.getOpcode(Opcodes.IRETURN))); return method; From af2d241b48b37555d6477fe64b9fcce8126c52df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B0=D1=87?= Date: Thu, 18 Jun 2020 01:02:42 +0500 Subject: [PATCH 2/2] Use InterfaceMethodRef instead of MethodRef --- .../asm/mixin/gen/AccessorGeneratorMethodProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java b/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java index 573d3d6c4..47d40787d 100644 --- a/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java +++ b/src/main/java/org/spongepowered/asm/mixin/gen/AccessorGeneratorMethodProxy.java @@ -86,7 +86,7 @@ public MethodNode generate() { boolean isPrivate = Bytecode.hasFlag(this.targetMethod, Opcodes.ACC_PRIVATE); boolean isInterface = Bytecode.hasFlag(this.methodLocation, Opcodes.ACC_INTERFACE); int opcode = this.targetIsStatic ? Opcodes.INVOKESTATIC : (isPrivate ? Opcodes.INVOKESPECIAL : (isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL)); - method.instructions.add(new MethodInsnNode(opcode, this.info.getClassNode().name, this.targetMethod.name, this.targetMethod.desc, false)); + method.instructions.add(new MethodInsnNode(opcode, this.info.getClassNode().name, this.targetMethod.name, this.targetMethod.desc, isInterface)); method.instructions.add(new InsnNode(this.returnType.getOpcode(Opcodes.IRETURN))); return method; }