Can XPUSHs be used in C callbacks?
[email protected] ("Jochen Stenzel")
| Newsgroups | perl.xs |
|---|---|
| Message-ID | <[email protected]> |
Hello,
I am new to XS and started with an existing project. From what I read and
understood in tutorials and perlapi so far, XPUSHs is a short way to put
an SV on the stack and to make sure there is enough place for it - an
alternative to use EXTEND and to assign the value directly to a stack
position.
So, when I found code like the following in a C function called as a
callback by another C function which is invoked by an xsub:
dSP;
EXTEND (sp, result_nr);
sp[sp_pos] = sv_2mortal (sv);
I thought it could be shortened to
dSP;
XPUSHs (sv_2mortal (sv));
but was wrong.
In the original code, sp is passed through to the callback and
initialized as PL_stack_base + ax in the xsub. result_nr is set to 0 in
the xsub, passed through to the callback and incremented with each callback
invocation, being 1, 2, 3, ... in subsequent calls. Likewise, sp_pos is
starting with a value of 0 and incremented each time. The idea is to place
results on the stack subsequently, like so:
1st call:
dSP;
EXTEND (sp, 1);
sp[0] = ...;
2nd call:
dSP;
EXTEND (sp, 2);
sp[1] = ...;
3rd call:
dSP;
EXTEND (sp, 3);
sp[2] = ...;
and so on.
When I replaced the original code fragment by
dSP;
XPUSHs (sv_2mortal (sv));
in order to have stack extension and result positioning handled behind
the scenes, calls to the xsub failed with the error message:
"Bizarre copy of ARRAY in aassign [...]"
Now, it is no problem to live with the original code, but I'd like to
understand what I did wrong. Can XPUSHs be used in a callback, and will
it handle stack extension and result positioning as I expected? If XPUSHs
use is possible in general, what did I wrong so that the shorter code did
not work?
Thank you for any advice in advance!
Jochen Stenzel