Beautifully done, Animator. Your rewrite establishes that what I'd hoped to
do is possible. It's clearer IMHO as well. :)
My crucial error was misunderstanding the return value of sv_setref_pv.
I'd thought it returned the object rather than the reference. Once
artist->perlobj is assigned the correct value, everything falls into
place, as you show. Now I can go implement this algo. Brilliant!
you return the SV. Because of some XS magic (I think) a new SV
is created with the contents of the perlref SV,
Here's how things progress behind the scenes as control leaves
new_artist and we enter
XS_main_new_artist, the glue function generated by Inline::C/xsubpp:
XS(XS_main_new_artist)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: main::new_artist(name)");
PERL_UNUSED_VAR(cv); /* -W */
{
char * name = (char *)SvPV_nolen(ST(0));
SV * RETVAL;
RETVAL = new_artist(name);
ST(0) = RETVAL;
sv_2mortal(ST(0));
}
XSRETURN(1);
}
-
The return value from new_artist is copied to RETVAL, which is copied in turn to ST(0), the top of the perl stack.
- ST(0) is "mortalized" by calling sv_2mortal( ST(0) ). That's
essentially a delayed decrement of its refcount. It won't be freed right away
as would be the case if you'd called SvREFCNT_dec -- instead, the
cleanup will occur a bit later, after we've had the chance to do something
with it.
- XSRETURN(1) is invoked, indicating that a single value is being returned via the stack, and control leaves XS land, heading back into world of stock Perl OPs.
- The Perl assignment operator = pops the top item off the stack and triggers a call to SvSetMagicSV, and the
value of the popped SV is copied into the lexical variable $artist. Now the SV that we created back in new_artist can be freed. (Note that since the Perl interpreter can often
tell when an SV is about to be freed, it will probably "steal" the contents
and avoid doing unneeded memory allocation and copying).
Now, consider that in my original program, the mortalized SV on the stack is the same SV that's housed in the Artist struct. I don't fully understand how reference counts affect things in such cases, but that was definitely not what I intended. It does not surprise me that undesirable consequences arose.
Thanks for your help,
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.