Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^9: XS: EXTEND/mPUSHi

by syphilis (Canon)
on Sep 29, 2011 at 08:41 UTC ( #928494=note: print w/ replies, xml ) Need Help??


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

But if some of that seems unnecessary, then ... :)

Ike obviously recognised the duplication to which you alluded ... but not me, alas.
Could you elaborate ?

Update: Also, ikegami mentioned making Inline_Stack_Reset a no-op. That just means amending Inline.h to do something like:

#define Inline_Stack_Reset {}
Right ?

Cheers,
Rob


Comment on Re^9: XS: EXTEND/mPUSHi
Download Code
Re^10: XS: EXTEND/mPUSHi
by BrowserUk (Pope) on Sep 29, 2011 at 10:46 UTC

    The the XS wrappers generated by I::C:

    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; ### <<<<<<< Has no effect { int n = (int)SvIV(ST(0)); #line 64 "monkeys.xs" I32* temp; #line 135 "monkeys.c" #line 66 "monkeys.xs" temp = PL_markstack_ptr++; rnd64(n);

    Prior to calling the C-func, the stack is adjusted to account for the number of input parameters passed:

    SP -= items;

    But this never has any affect because SP is a local copy of the real stack pointer. In order to 'remove' the passed parameters from the stack (inside the C-func) you have to call Inline_Stack_Reset; which translates to sp = mark;

    Then after you've pushed your return parameters onto the stack, you have to remember to call Inline_Stack_Done; which translates to PUTBACK;, which translates to PL_stack_sp = sp;. Which updates the real stack pointer from tha local copy to account for the net effect of removing the input parameters and adding the output parameters.

    But the generated XS wrapper already has code to take care of this, except it has been disabled by having been preceded with a(nother) return:

    return; /* assume stack size is correct */ #line 146 "monkeys.c" PUTBACK; ### << Never reached return; } }

    What we discussed above is that if PUTBACK was called after SP -= items: and before the C-sub is invoked, there would be no need to call Inline_Stack_Reset; within the C-sub, because that stack would have already been adjusted to account for the input parameters. And the Stack access (ST(0); xPUSHy() & Inline_Stack_Push() etc.) macros would still operate correctly.

    And then, if the first return statement was removed from the wrapper sub, so that the currently unreached PUTBACK; was reached, then the real stack would again be updated this time reflecting whatever output parameters had been push onto the stack (if any), thereby removing the need for the Inline_Stack_done; macro.

    In summary: The theory went that if the wrapper sub were generated as (discarding the extraneous stuff for clarity) :

    XS(XS_main_xxxxx) { dXSARGS; if (items != 1) croak_xs_usage(cv, "n"); SP -= items; { int n = (int)SvIV(ST(0)); I32* temp = PL_markstack_ptr++; PUTBACK; xxxxx(n); if (PL_markstack_ptr != temp) { PL_markstack_ptr = temp; XSRETURN_EMPTY; } PUTBACK; return; } }

    Then Inline_Stack_Reset; & Inline_Stack_Done; become redundant for new code, and could be made noops for backward compatibility.

    The fly in this ointment is that there are the XS macros POPx, which would no longer operate correctly if mixed into I::C.

    I wouldn't consider this a loss as there are alternative and better ways of accessing the input stack, but I've no doubt that some of those p5p for who backward compatibility is sacrosanct would be up in arms.

    Bottom line: Your 'do nothing' was probably the right call. Sorry for having suggested otherwise.


    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.
      Heh - I must've looked at the C code a hundred times over the years, and never noticed the unreached
      PUTBACK; return;
      ... though, as I write this, I'm suddenly struck with a contradictory sense of "deja vu".

      That unreached code *is* confusing and/or annoying, and it would be nice to make that piece of xsubbp-generated code reachable (as you suggest) - which means amending C.pm in a way that makes me feel a bit uneasy.

      Your 'do nothing' was probably the right call

      Maybe ... I *have* been right before, y'know !! ... by accident, of course ( ... which would also be the case in this instance :-)

      I'll chew this over for a while, as time permits. I've already checked that ikegami's suggested changes re the "no-op" and the "PUTBACK" insertions don't break the test suite. (However, they still leave us with that unreached "return" ... not that he suggested they would do otherwise.)

      Thanks BrowserUk, ikegami.

      Cheers,
      Rob

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (13)
As of 2014-11-27 13:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (184 votes), past polls