Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister


by ikegami (Pope)
on Sep 26, 2011 at 17:37 UTC ( #927908=note: print w/replies, xml ) Need Help??

in reply to XS: EXTEND/mPUSHi

  • You need to use XSRETURN to specify how many items you placed on the stack. Basically, dSP; creates a local stack pointer and mPUSHi modifies this local pointer, so you need to copy this value back to the real stack pointer.

    Instead of figuring out what argument to use for XSRETURN, you can use PUTBACK. Unlike XSRETURN, it doesn't perform a return, so you need to follow it up with return if you use it in the middle of a function.

    XS would normally do this for you, but Inline::C forces you to do it (by using return; /* assume stack size is correct */).

    This was the purpose of Inline_Stack_Done.

  • The scalars passed to the sub are still on the stack, so you need to remove them unless you want to return them.

    In Perl ops, this would be done by popping them as they are read, but one doesn't tend to read them when using Inline. SP = MARK; will pop all of them.

    This was the purpose of Inline_Stack_Reset.

  • If rnd(100) should return 100 numbers, you need to use a post-decrement for your loop counter.

void rnd( int n ) { static __int64 y = 2463534242; dXSARGS; int i; POPs; EXTEND( SP, n ); for (i = n; i--; ) { y ^= y << 13; y ^= y >> 17; y ^= y << 5; mPUSHi( (IV)y ); } XSRETURN(n); }
void rnd( int n ) { static __int64 y = 2463534242; dSP; dMARK; SP = MARK; // Remove args from stack. EXTEND( SP, n ); while (n--) { y ^= y << 13; y ^= y >> 17; y ^= y << 5; mPUSHi( (IV)y ); } PUTBACK; // Publish changes to stack. }

Replies are listed 'Best First'.
by BrowserUk (Pope) on Sep 26, 2011 at 18:03 UTC

    Thanks for the very nice explanation. I was concerned about using PUTBACK myself as I thought t would be duplicating the one in the wrapper sub. On closer inspection I've realised that the one in the wrapper sub will never be reached:

    /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ ### Her +e #line 128 "monkeys.c" PUTBACK; return; } }

    Which make me wonder why it (and the second return), are there in the first place?

    I'm also lost to understand the derivation of the name "PUTBACK". It certainly isn't intuitive (to me) as a term that means 'remember how many items were added to the stack'.

    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.
      I agree. It's probably short for "put sp (aka SP) back into PL_stack_sp" (as it does PL_stack_sp = sp), but it's not a very useful name.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://927908]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (7)
As of 2018-06-20 14:24 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (116 votes). Check out past polls.