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.
In reply to Re^6: XS: EXTEND/mPUSHi
by BrowserUk
in thread XS: EXTEND/mPUSHi
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |