On Sep 10, 2014, at 19:22 , Marvin Humphrey <[email protected]> wrote:

> Each interface gets:
> 
> *   A unique integer id.
> *   A stub interface table filled with stub methods.
> 
> Each Class gets:
> 
> *   An array of interfaces, initialized to the stub interface tables for each
>    interface.
> 
> Interface method dispatch would look something like this:
> 
>    static inline void
>    Futzer_Futz(Futzer *self) {
>        Interface *interface = self->klass->itables[Futzer_INTERFACE_ID];
>        char *ptr = (char*)interface + Futzer_Futz_OFFSET;
>        Futzer_Futz_t method = (Futzer_Futz_t)ptr;
>        method(self);
>    }
> 
> If we add many interfaces dynamically, we'll have to reallocate, at a cost
> proportional to O(M*N) for M classes and N interfaces.  Thread safety when
> modifying Class data will be tricky but ought to be manageable.

Ah, you mean an array of itable pointers for every class. This would mean a 
per-class overhead of 8 KB for 1,000 interfaces. This is a bit much but having 
an itable array has the benefit that we don’t need a heap allocation for 
interface instances. Method dispatch is also fast with only one additional 
memory access for the itables member.

But I don’t understand why we need the stub interfaces. Although we could 
simply cast an Obj to any interface type, we should still have a function that 
checks whether an object satifies the interface before calling any interface 
methods. Otherwise, we’ll get an exception on an attempt to call an unsupported 
method. This can happen much later and looks dangerous to me.

Why don’t we simply initialize the itable array with NULLs and have a function 
like

    Futzer*
    Futzer_from_obj(Obj* obj) {
        if (!obj->klass->itables[Futzer_INTERFACE_ID]) {
            // Build the interface table and store it in itables array.
            // Throw if the class doesn’t satisfy the interface.
        }
        return (Futzer*)obj;
    }

This can be used to cast an object to an interface type and make sure that the 
object’s class is compatible and the itables entry is populated.

Nick

Reply via email to