Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^5: XS: EXTEND/mPUSHi

by ikegami (Patriarch)
on Sep 27, 2011 at 01:08 UTC ( [id://927989]=note: print w/replies, xml ) Need Help??


in reply to Re^4: XS: EXTEND/mPUSHi
in thread XS: EXTEND/mPUSHi

It doesn't appear to leak any memory

Indeed, there's no leak.

Perl's stack isn't refcounted, so that means you can't decrement the refcount of a scalar you place on the stack even if you don't keep a reference to it.

What you do is place the scalar on a list of variables whose refcount needs to be decremented when they are removed from the stack. Variables on this list are called mortals.

(This way of doing things is a source of many bugs, but that's the box you have to play in.)

The "m" in "mPUSHi" stands for mortal. The created scalar will be made mortal.

mPUSHi(4);
boils down to
*(++SP) = sv_2mortal(newSViv(4));

but that still leaves me with the question of whether I should be resetting the stack to account for the single input parameter

Check the first value being returned. It's always your argument (n).

or whether the EXTEND() takes care for that for me?

As documented EXTEND will make sure there is n spaces available. That's it. It doesn't remove anything already there.

In your case, you end up with at least n+1 spaces on the the stack total, one of which is used for the argument.

Weirdness like the completely unused & redundant PUTBACK; return; sequence generated by the Inline::C wrapper functions

It's actually added by the XS to C converter, xsubpp. Inline::C doesn't put there. In fact, Inline::C specifically doesn't want it, but doesn't have a way of telling xsubpp not to call it.

Inline::C requires that you call PUTBACK (explicitly or via XSRETURN) because it can't do it for you because it doesn't have access to your sub's SP to "put it back".

Real XS doesn't require that you call PUTBACK because xsubpp actually creates the sub, so it has access to the sub's SP.

PS — C doesn't require the use of return; when the return type is void.

Replies are listed 'Best First'.
Re^6: XS: EXTEND/mPUSHi
by BrowserUk (Patriarch) on Sep 27, 2011 at 01:44 UTC
    Inline::C requires that you call PUTBACK (explicitly or via XSRETURN) because it can't do it for you because it doesn't have access to your sub's SP to "put it back".

    Hm. The wrapper sub knows (or can find out) how many values were passed on the stack. For fixed-length argument lists (no ellipses), it could clean up the stack before calling the I::C sub. Indeed, it already seems to (attempt to) do that:

    XS(XS_main_rnd64); /* prototype to pass -Wmissing-prototypes */ XS(XS_main_rnd64) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items != 1) croak_xs_usage(cv, "n"); PERL_UNUSED_VAR(ax); /* -Wall */ SP -= items;

    Which is the source of my confusion regarding the need to do this (again) within the sub.

    It (the wrapper sub) could also take a mark on the stack prior to invoking the I:C sub: (which it also seems to do:

    temp = PL_markstack_ptr++;
    ),

    and then use that to determine how many (if any) values have been pushed onto the stack during the call, thereby removing the need for the I::C programmer to do this manually.

    For all the world it looks like the wrapper sub were originally intended to automate this part of the process, but then something changed. Maybe the author changed his mind or couldn't get it to work. Or some other programmer went in there to correct some bug and made changes that were incompatible with the original vision. (This all pre-dates syphilis' involvement.).

    The closer you start to look at this code, the more oddities and (possibly) missed opportunities you see.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      The wrapper sub knows (or can find out) how many values were passed on the stack. For fixed-length argument lists (no ellipses), it could clean up the stack before calling the I::C sub.

      I concur. I came to the same conclusion.

      and then use that to determine how many (if any) values have been pushed onto the stack during the call, thereby removing the need for the I::C programmer to do this manually.

      I'm guessing "do this" means "calling PUTBACK". If so, sweet. I hadn't looked that far.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://927989]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-19 08:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found