syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I had always assumed that if, in XS, we wanted to return items from the stack to perl, we had to do an XSRETURN(x) where x is the number of items we want to return.

Apparently that's not so. The below Inline::C script doesn't explicitly return anything, yet the 3 values that are pushed onto the stack are returned:
use warnings; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; void foo() { dXSARGS; sp = mark; XPUSHs(sv_2mortal(newSVuv(111))); XPUSHs(sv_2mortal(newSVuv(87))); XPUSHs(sv_2mortal(newSVuv(42))); PUTBACK; } EOC @bar = foo(); print "@bar\n"; # prints 111 87 42
There's also a demo in the Inline::C-Cookbook that returns values in the same way without an explicit XSRETURN(x).

If no explicit XSRETURN(x) is made, and the function is void, is it simply the case that everything that has been pushed onto the stack is returned ? Is this behaviour reliable ?

Cheers,
Rob

Replies are listed 'Best First'.
Re: [XS] Correct way to return the stack
by jand (Friar) on Sep 07, 2008 at 19:16 UTC
    XSRETURN(n) is just setting the stack pointer and returns, so if you already set up the correct stack pointer with XPUSHs() then there is indeed no need to call XSRETURN(n). XSRETURN(n) is usefull if you return fewer values than you had input parameters and just set your return values by direct assignment to ST(i). Or even if you called EXTEND(SP, n), and then assigned to ST(i), which is slightly more efficient than a long series of XPUSHs() calls.
Re: [XS] Correct way to return the stack (source)
by tye (Sage) on Sep 07, 2008 at 19:18 UTC

    XSRETURN(off); does (slightly more than) PL_stack_sp = PL_stack_base + ax + (off - 1);. PUTBACK; does PL_stack_sp = sp;. Yep, I think that behavior is reliable. Those are just two different ways of saying how many items from the top of the stack should be considered return values.

    - tye        

      Thanks jand, tye.
      That gives me a much clearer picture of what's really going on.

      Cheers,
      Rob