Nicholas Clark <[EMAIL PROTECTED]> writes:
>On Fri, Jan 17, 2003 at 12:40:49PM +0000, Nick Ing-Simmons wrote:
>> The other main thing you need to keep in mind is that EXTEND (or the 
>> implied one in XPUSHs) can re-allocate stack and so it may move wholesale 
>> in memory. I think the XS macro ST(n) dodges this issue by working in offsets
>> from _the_ global variable which holds bottom-of-stack. But dSP / PUTBACK 
>> and PUSH are working with a "cached" local copy of top-of-stack pointer.
>
>In both 5.005_03 5.9 the two definitions look like this:
>
>#define PUSHs(s)        (*++sp = (s))
>#define XPUSHs(s)       STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END
>
>and EXTEND is defined to update the cached local copy sp:
>
>#define EXTEND(p,n)     STMT_START { if (PL_stack_max - p < (n)) {     \
>                            sp = stack_grow(sp,p, (int) (n));          \
>                        } } STMT_END
>
>so I think that there isn't actually a problem. But, obviously, I could be
>wrong, as XS isn't really something I know that much about.

The problem I was alluding to needs the definition of 'sp' as well:

pp.h:#define dSP                register SV **sp = PL_stack_sp

Here 'PL_stack_sp' is _the_ global variable and 'sp' is a local copy

So if you have a function:

func(...)
{
 dSP;       /* Declares sp and inits from PL_stack_sp */
 XPUSH(...)
 PUTBACK;   /* copy sp to PL_stack_sp */
}

And then have XS code call it 

CODE:
   ...
   func();
   SPAGAIN; /* if you use sp anywhwere after this point */
   ...
   XS_RETURN(n); /* Is immune as uses global PL_stack_base */

There are thus really two ways of working with the stack:

A. dSP/XPUSH/EXTEND/PUTBACK/SPAGAIN 
   originaly developed for perl ops 

B. items/ST(N)/XSRETURN(N) 
   intended for XS CODE: blocks.

They can be mixed but a little care is needed.

 


>
>Nicholas Clark
-- 
Nick Ing-Simmons
http://www.ni-s.u-net.com/

Reply via email to