http://qs1969.pair.com?node_id=503126


in reply to Re: Inline::C - object accessor failure
in thread Inline::C - object accessor failure

Actually, that's XS.

In your first example, you're returning an SV* you looked up in the hash, so you don't own it. Inline::C works by generating an XS file and running xsubpp, and XS mortalizes any SV* that you return via its RETVAL mechanism. Thus, you've mortalized an SV* owned by the hash. Which is not at all pointed out by the Inline documentation (it should be in Inline::C-Cookbook), and the description in perlxs seems suspicious to me to (it claims that RETVAL is mortalized via the typemap file, but I'm looking at the typemap and I see no relevant mention of 'mortal' anywhere -- nor any mention of RETVAL.)

So I think this should work:

package InlineTest; use strict; use warnings; use Inline qw(NOCLEAN INFO); use Inline 'C' => <<'CEND'; SV* x (HV* self) { SV** xp = hv_fetch(self, "x", 1, 0); /* Increment the ref count because XS mortalizes any returned SV* */ return xp ? SvREFCNT_inc(*xp) : &PL_sv_undef; } CEND sub new { my $self = shift; return bless {@_}, $self; } package main; use strict; use warnings; my $t = InlineTest->new( x => 'foo' ); print $t->x, "\n";
And it doesn't seem to leak, either: replace the last two lines with
sub Whiner::DESTROY { print "Dying!\n" } my $t = InlineTest->new( x => bless [], 'Whiner' ); print $t->x, "\n"; undef $t; print "Done.\n";
and it prints "Dying!" before "Done."

In general, I would also recommend using <<'CEND' rather than <<CEND for blocks of Inline code, because if you want to insert a debugging printf("Got here!\n"), then you don't really want that \n to be translated to a newline.


I work for Reactrix Systems, and am willing to admit it.

Replies are listed 'Best First'.
Re^3: Inline::C - object accessor failure
by rg0now (Chaplain) on Oct 26, 2005 at 18:54 UTC
    ...XS mortalizes any SV* that you return via its RETVAL mechanism ... and the description in perlxs seems suspicious to me to (it claims that RETVAL is mortalized via the typemap file, but I'm looking at the typemap and I see no relevant mention of 'mortal' anywhere -- nor any mention of RETVAL.)
    Interestingly, RETVAL is mortalized by xsubpp itself (see the generate_output cruft in the xsubpp source) - so it is hardwired into XS... But it usually turns out to do what you want, except for the cases, when it does not.
Re^3: Inline::C - object accessor failure
by robin (Chaplain) on Oct 26, 2005 at 22:12 UTC

    Wow, thanks! I've been looking at the 5.8.1 version of perlxs, which doesn't mention the automatic mortalization of RETVAL at all. It looks like that section was added in 5.8.4.

    (Inline was written quite a while before this feature was documented, so maybe ingy didn't know about it and that's why the Inline::C documentation doesn't mention it?)

    You'd think that not knowing about this would have caused me problems by now. The odd thing is, I've just looked over all my XS code and I don't seem to have run afoul of it anywhere. I suppose it helps that I usually use PPCODE instead of CODE.