Java ASM "Type top (current frame, locals[0]) is not assignable to reference type"

Viewed 1531

I’m currently developing a java add-on for a minecraft client called "LabyMod". Because Labymod did not create all events I need I'm trying to create the missing event myself. For this I need to modify a class via asm but every time I make the modifications to this class I get the following error:

SEVERE: Unable to launch
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:131)
at net.minecraft.launchwrapper.Launch.main(Launch.java:27)
Caused by: java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
aip.a(Laed;Lakb;)Ljava/util/List; @1909: aload_0
Reason:
Type top (current frame, locals[0]) is not assignable to reference type
Current Frame:
bci: @1909
flags: { }
locals: { top, top, top, 'java/util/ArrayList' }
stack: { 'java/util/ArrayList' }

You can view my code here, all class and method names I transform are right because if I remove both "ALOAD" (and remove the required parameters of course) it works

public byte[] transform(String name, String transformedName, byte[] basicClass) {
        if (implementation == null) {
            return basicClass;
        }
        if (transformedName.equals(implementation.getTooltipClassName()) || transformedName.length() > 0) {
            ClassNode classNode = new ClassNode();
            ClassReader classReader = new ClassReader(basicClass);
            classReader.accept(classNode, 0);
            methodFor: for (MethodNode methodNode : classNode.methods) {

                if (methodNode.name.equals(implementation.getTooltipMethodName())) {

                    if (methodNode.desc.equals(implementation.getTooltipMethodDesc())) {
                        System.out.println("M:" + methodNode.name);
                        System.out.println("D: " + methodNode.desc);
                        for (int i = 0; i < methodNode.instructions.size(); i++) {
                            AbstractInsnNode node = methodNode.instructions.get(i);
                            if (node.getOpcode() == Opcodes.ARETURN) {
                                System.out.println("Method found");
                                AbstractInsnNode eventHook = new MethodInsnNode(Opcodes.INVOKESTATIC,
                                        "org/forengoetter/eventhandler/EventAdapter", "onItemTooltip",
                                        implementation.getTooltipEventMethodDesc(), false);
                                AbstractInsnNode loadHook = new VarInsnNode(Opcodes.ALOAD, 0);
                                AbstractInsnNode loadHookAdvanced = new VarInsnNode(Opcodes.ALOAD, 2);
                                methodNode.instructions.insertBefore(node, loadHook);
                                System.out.println("hook1");
                                methodNode.instructions.insertBefore(node, loadHookAdvanced);
                                System.out.println("hook2");
                                methodNode.instructions.insertBefore(node, eventHook);
                                System.out.println("hook3");
                                break methodFor;
                            }
                        }
                    }
                }
            }
            ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            classNode.accept(classWriter);
            return classWriter.toByteArray();
        }
        return basicClass;
    }

this is the method which should be called:

public static List<String> onItemTooltip(List<String> toolTip, ItemStack itemStack, ITooltipFlag advanced) {
        ItemTooltipEvent event = new ItemTooltipEvent(itemStack, toolTip, advanced.isAdvanced());
        // FOG.getInstance().getEventBus().post(event);
        event.toolTip.add("this is a test");
        return event.toolTip;

    }

and this is the signature of this method I'm using in the asm transformation (Ljava/util/List;Laip;Lakb;)Ljava/util/List; (the signature is obfuscated because of minecraft, but the class names are right, I've checked it several times)

I hope somebody can help me.

0 Answers
Related