This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
RE: VerifyError when compiling jetty
Bjarni Thorisson writes:
> Hello, and thanks for the quick reply.
>
> Below is a simple class you can compile into bytecode with gcj and try to
> run it. Then this error should occurr:
>
> <--------------------clip----------------------------->
> Exception in thread "main" java.lang.VerifyError: (class: Smu$Foo, method:
> run signature: ()V) Illegal use of nonvirtual function call
> at Smu.start(Smu.java:28)
> at Smu.main(Smu.java:13)
> <-------------------/clip----------------------------->
I can confirm this.
We generate the same code for Smu.start.
Looking at Smu$Foo:
Method name:"run" public Signature: 17=()void Method name:"run" public Signature: 9=()void
Attribute "Code", length:115, max_stack:2, max_locals:4, code_length:55 Attribute "Code", length:116, max_stack:2, max_locals:3, code_length:56
0: goto 20 0: aload_0
3: ldc2_w #1=<Long 1000> 1: getfield #12=<Field Smu$Foo.this$0 Smu>
6: invokestatic #3=<Method java.lang.Thread.sleep (long)void> 4: invokevirtual #18=<Method Smu.isStarted ()boolean>
9: aload_0 7: ifeq 31
10: getfield #4=<Field Smu$Foo.this$0 Smu> 10: sipush 1000
13: invokestatic #5=<Method Smu.access$000 (Smu)void> 13: i2l
16: goto 20 14: invokestatic #22=<Method java.lang.Thread.sleep (long)void>
19: astore_1 17: aload_0
20: aload_0 18: getfield #12=<Field Smu$Foo.this$0 Smu>
21: getfield #4=<Field Smu$Foo.this$0 Smu> 21: invokespecial #25=<Method Smu.doFoo ()void>
24: invokevirtual #7=<Method Smu.isStarted ()boolean> 24: goto 28
27: ifne 3 27: astore_1
30: jsr 42 28: goto 0
33: goto 54 31: jsr 43
36: astore_2 34: goto 55
37: jsr 42 37: astore_2
40: aload_2 38: jsr 43
41: athrow 41: aload_2
42: astore_3 42: athrow
43: aload_0 43: astore_1
44: getfield #4=<Field Smu$Foo.this$0 Smu> 44: aload_0
47: aconst_null 45: getfield #12=<Field Smu$Foo.this$0 Smu>
48: invokestatic #8=<Method Smu.access$102 (Smu,Smu$Foo)Smu$Foo> 48: aconst_null
51: pop 49: invokestatic #29=<Method Smu.access$1 (Smu,Smu$Foo)Smu$Foo>
52: ret 3 52: pop
54: return 53: ret 1
55: return
IBMJava2-131/bin/javac is on the left, we are on the right. javac
calls Smu.access$100 with invokestatic, whereas we call Smu.doFoo with
invokespecial. Let's look at Smu.access$000:
Method name:"access$000" static Signature: 32=(Smu)void
Attribute "Code", length:29, max_stack:1, max_locals:1, code_length:5
0: aload_0
1: invokespecial #2=<Method Smu.doFoo ()void>
4: return
Attribute "LineNumberTable", length:6, count: 1
line: 1 at pc: 0
Attribute "Synthetic", length:0
So, Smu.access$000 is a thunk that javac generates in order to enable
inner classes to access methods in the enclosing class. AFAICS we
aren't doing that in this case.
This is illegal code on our part, because we're not allowed to use
invokepsecial on a private method. We should generate an access
method for Smu.doFoo and use it.
Andrew.