On 26/06/2015 04:06, Marvin Humphrey wrote:
Consider a method with an interface type argument

     Obj*
     Fetch(Hash *hash, Hashable *key);

That should be `Hashable key` rather than `Hashable *key` -- right?

Right.

Does this approach make sense?

     https://github.com/rectang/lucy-clownfish/commits/iface_exp1

Obviously some of that code would be autogenerated by CFC.

I think it would work for Perl, Python, Ruby, etc -- languages which
resolve method names on each invocation.

The question is how to deal with wrapped Clownfish objects that are passed as interface type arguments. For example, the `key_sv` passed to Stringify_And_Fetch might be a Clownfish::Obj. In this case, it should work to wrap it a second time as HostStringable. But this would make interface method calls a lot slower. Calling Stringify on such a doubly wrapped object would go through S_call_stringify, call_method, and the generated XS wrapper, instead of invoking Stringify directly.

So if a Clownfish::Obj is passed as interface type argument, we should check whether it implements the interface and create an interface object with the itable of the Obj's class, not the host object itable. Something like:

    Stringable_t
    sv_to_stringable(SV *sv) {
        Obj *obj;
        ITable *itable;

        if (sv_derived_from(sv, "Clownfish::Obj")) {
            IV iv_ptr = SvIV(SvRV(sv));
            obj = INT2PTR(cfish_Obj*, iv_ptr);
            itable = Obj_lookup_itable(obj, STRINGABLE);
            if (itable == NULL) {
                THROW(ERR, "%o doesn't implement Stringable",
                      Obj_get_class_name(obj));
            }
            INCREF(obj);
        }
        else {
            // Pure Perl object.
            obj = HostStringable_new(sv);
            itable = XSBind_hoststringable_itable();
        }

        Stringable_t stringable = { obj, itable };
        return stringable;
    }

*   Allocate the wrapper object on the stack, similar to our approach with
     stack-allocated String.

This only works if we made the host objects "clone on incref" like stack 
Strings.

Nick

Reply via email to