Clashsoft
Clashsoft

Reputation: 11882

JVM Verify Error 'Illegal type at constant pool'

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?

Upvotes: 4

Views: 12024

Answers (2)

nickl-
nickl-

Reputation: 8731

With ASM you will see this error because of an incorrect isInterface flag. The argument isInterface of visitMethodInsn refers to the target/owner/destination and not the current context.

i.o.w when using INVOKEVIRTUAL, isInterface is false.

see issue here for more details.

Upvotes: 2

Clashsoft
Clashsoft

Reputation: 11882

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.

Upvotes: 9

Related Questions