Greets,

Right now, if a final class inherits a method, we make the final class's
method invocation an alias for the implementing function -- avoiding vtable
dispatch.  I have come to believe that this is incorrect.

Consider a parcel com.example.stuff which publishes classes Foo and FooJr.
Foo implements Say_Hello().

    public class Foo inherits Clownfish::Obj {
        ...

        public void
        Say_Hello(Foo *self);
    }

    public class FooJr inherits Foo {
        ...
    }


Now, consider another parcel com.example.morestuff which publishes the final
class MyFinalFoo.

    public final class MyFinalFoo inherits FooJr {
        ...
    }

We'll get the following method definition for Say_Hello():

    #define MORESTUFF_MyFinalFoo_Say_Hello(self) \
        STUFF_Foo_Say_Hello(self)

What happens if a newer com.example.stuff is loaded with a FooJr which
implements Say_Hello()?  Invocations on MyFinalFoo will invoke the wrong
function: the old one in Foo rather than the new one in FooJr.

I believe that we can only avoid vtable dispatch for methods which are known
to be final because they are explicitly declared as final or because they are
contained within a final class.

(I figured this out because we have an invocation of Hash_Is_A() in
IndexReader.c, and there was a symbol export problem with CFISH_Obj_Is_A_IMP
when I declared that Hash was final.)

Marvin Humphrey

Reply via email to