Jeroen Frijters wrote:
Eric Blake wrote:

I think you two are talking about two different things. I think Robert
means that it is legal to use invokeinterface on an Object method
through an interface type. So this is legal:

invokeinterface java/lang/Runnable/toString()Ljava/lang/String;

No, it is the same issue. The compiler must always allow you to invoke a public method from Object from a qualifying type of an interface (since in JLS 9, interfaces implicitly have all public methods from Object), but the compiler's responsibility according to JLS 13.1 is to flatten that to a call on Object if and only if the qualifying type does not redeclare (or inherit a redeclaration) of the method. Corallary - since no interface can redeclare a final method, a compiler should never produce invokeinterface SomeInterface.getClass or any of the other final methods in Object; so this issue only affects equals, hashCode, and toString.


class Foo
{
void m(Runnable r, java.util.Collection c)
{
r.toString(); // compiler must flatten to invokevirtual Object.toString: Runnable does not redeclare toString
c.equals(r); // compiler must emit invokeinterface Collection.equals: since Collection redeclares equals
}
}


However, there are buggy compilers out there that emit invokeinterface Runnable.toString(), even though Runnable does not redeclare toString; and a robust JVM implementation will be prepared to deal with this situation.

This is a binary compatibility issue - in other words, it is possible to expose javac 1.4's bug by using inconsistent .class files to show whether a class was compiled with a call invokevirtual Object.toString or invokeinterface SomeInterface.toString (and the jacks compiler test suite does this).



Regards, Jeroen


-- Someday, I might put a cute statement here.

Eric Blake             [EMAIL PROTECTED]


_______________________________________________ Classpath mailing list [EMAIL PROTECTED] http://lists.gnu.org/mailman/listinfo/classpath

Reply via email to