problem in gij bytecode verifier

Sonja Krause-Harder skh@suse.de
Sun Feb 29 05:17:00 GMT 2004


Hi,
I've found a problem in gij's bytecode verifier. Consider the following
(legal) code:
public class Main {
 // I is an interface
 public static void a (I i) {}
 public static void main (String[] argv) {
 // A implements I ...
 I i = new A ();
 if (foo()) {
 // ... and so does B.
 i = new B ();
 }
 a (i);
 }
 public static boolean foo () {
 return true;
 }
}
resulting in the following bytecode:
Method name:"main" public static Signature: 9=(java.lang.String[])void
Attribute "Code", length:63, max_stack:2, max_locals:2, code_length:27
 0: new #11=<Class A>
 3: dup
 4: invokespecial #15=<Method A.<init> ()void>
 7: astore_1
 8: invokestatic #19=<Method Main.foo ()boolean>
 11: ifeq 22
 14: new #21=<Class B>
 17: dup
 18: invokespecial #22=<Method B.<init> ()void>
 21: astore_1
 22: aload_1
 23: invokestatic #24=<Method Main.a (I)void>
 26: return
This fails during verification with:
Exception in thread "main" java.lang.VerifyError: verification failed at PC 23 
in Main:main(([Ljava.lang.String;)V): incompatible type on stack
(...)
The error does not occur when A extends B or vice versa.
I suspect that during the state merge at PC 22, the information about the
interface implemented by A and B is lost, leading to an plain Object passed to a().
The following snippet from type->merge() in libjava/verify.cc led to this suspicion:
(...)
 // Ordinarily this terminates when we hit Object...
 while (k != NULL)
 {
 if (is_assignable_from_slow (k, oldk))
 break;
 k = k->getSuperclass ();
 changed = true;
 }
 // ... but K could have been an interface, in which
 // case we'll end up here. We just convert this
 // into Object.
 if (k == NULL)
 k = &java::lang::Object::class$;
(...)
but I'm neither sure that my analysis is correct, nor what an appropriate fix
would be.
Any hints would be very welcome. Complete testcase attached.
regards,
Sonja
-- 
Sonja Krause-Harder (skh@suse.de) SuSE Linux AG
-------------- next part --------------
A non-text attachment was scrubbed...
Name: interface_verify_error.tar.gz
Type: application/x-gunzip
Size: 585 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/java/attachments/20040229/b5056211/attachment.bin>


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /