JVM Verify Error 'Illegal type at constant pool'

java, java-bytecode-asm, jvm

Solution

I figured out my mistake. The error lies here:

invokevirtual #40 // InterfaceMethod
      ^^^^^^^        ^^^^^^^^^

I am using invokevirtual on an interface method, which is generally not a good idea. However I think that the error thrown by the verifier should be a bit more clear about what is actually wrong.

Problem

I am currently writing my own compiler and I am trying to compile the following code: ``` List[String] list = List("a", "b", "c", "d") list stream map((String s) => s.toUpperCase()) System out println list ``` The compiler has no problem parsing, linking or compiling the code, but when it comes to executing it, the JVM throws the following error: ``` java.lang.VerifyError: Illegal type at constant pool entry 40 in class dyvil.test.Main Exception Details: Location: dyvil/test/Main.main([Ljava/lang/String;)V @29: invokevirtual Reason: Constant pool index 40 is invalid Bytecode: ... ``` I tried to use `javap` to find the problem, and this is the instruction `@29`: ``` 29: invokevirtual #40 // InterfaceMethod java/util/Collection.stream:()Ljava/util/stream/Stream; ``` And the entry in the Constant Pool (also using `javap`): ``` #37 = Utf8 stream #38 = Utf8 ()Ljava/util/stream/Stream; #39 = NameAndType #37:#38 // stream:()Ljava/util/stream/Stream; #40 = InterfaceMethodref #36.#39 // java/util/Collection.stream:()Ljava/util/stream/Stream; ``` When opening the class with the Eclipse Class File Viewer, the line where `@29` should be reads: ``` Class Format Exception ``` and all following instructions are not shown anymore (except for Locals, ...). However, the ASM Bytecode Plugin writes ``` INVOKEVIRTUAL java/util/Collection.stream ()Ljava/util/stream/Stream; ``` at that line, which appears to be valid. What am I doing wrong / missing here?

Original source