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/