On Thu, Feb 23, 2017 at 9:57 AM, Nick Wellnhofer <[email protected]> wrote:
> CFCPerlClass_method_bindings in CFCPerlClass.c currently generates XSubs for
> overridden methods. The comment states:
>
> /* Create the binding, add it to the array.
> *
> * Also create an XSub binding for each override. Each of these
> * directly calls the implementing function, rather than invokes the
> * method on the object using vtable method dispatch. Doing things
> * this way allows SUPER:: invocations from Perl-space to work
> * properly.
> */
>
> While this is true, I fail to see a practical use case. IMO, the only place
> where calling a supermethod makes sense is in the method implementation of a
> subclass.
Calling the supermethod from the method implementation of a subclass is
exactly the intended use case.
There's a test in t/binding/019-obj.t to guarantee that it works.
package SonOfTestObj;
use base qw( TestObj );
{
sub to_string {
my $self = shift;
return "STRING: " . $self->SUPER::to_string;
}
}
...
$object = SonOfTestObj->new;
like( $object->to_string, qr/STRING:.*?SonOfTestObj/,
"overridden XS bindings can be called via SUPER" );
If I make a change like the following in the XS binding, switching from a
hard-coded function to a vtable method invocation...
- method = CFISH_METHOD_PTR(CFISH_OBJ, CFISH_Obj_To_String);
- retval = method(arg_self);
+ retval = CFISH_Obj_To_String(arg_self);
... the test will segfault after Perl tells us "Deep recursion on subroutine
"SonOfTestObj::to_string" at t/binding/019-obj.t line 32."
That happens because the method pointer stored in the vtable is a callback
which calls the XSUB which calls the callback which calls the XSUB which calls
the callback...
PS: While researching this post and preparing an example using SUPER::DESTROY,
I discovered that the implementation for DESTROY is a little wacky right
now. When a Perl subclass implements DESTROY, the method pointer for
Destroy in the subclass vtable doesn't get overridden (possibly because
"destroy" doesn't match "DESTROY" after
https://github.com/apache/lucy-clownfish/commit/64cf00e28a2 ) but stuff
still works because under the Perl bindings cfish_dec_refcount calls
SvREFCNT_dec if there's a cached host object.
Marvin Humphrey