On Mon, Mar 15, 2010 at 07:07:41AM -0400, Sisyphus via RT wrote:
Show quoted text> 2) I gather that there's currently never any problem for the "truly
> void" functions - that the problem can only arise when dXSARGS are
> invoked. Is that right ?
No, a void function could have used call_sv and ended up reallocating
the mark stack somewhere. Anything that hands control back to the perl
interpreter is 'unsafe' here.
Show quoted text> 3) In the "truly void" case, instead of assigning the original value
> back to PL_markstack_ptr, the above code just does a "PL_markstack_ptr--
> ;". Are there situations when that's *not* the right thing to do ? If
> we really need to assign the old value back again, I guess we could
> store it in a second temp value - ie do:
> temp2 = PL_markstack_ptr++;
> and then, later:
> PL_markstack_ptr = temp2;
Other way around; assigning back the old value is the thing which is
wrong (since in the reallocation case, the old value points to freed
memory). You have to assume that all stack pointers from before the
$function() call are invalidated, and fetch new ones.
Using PL_markstack_ptr-- should be safe - I think.
However, this is all making a lot of fragile assumptions about how
perl handles the mark stack. It occurs to me that it would be sensible
to write:
<record mark stack height>
PUSHMARK(SP);
$function($arg_name_list);
if ( <mark stack height is unchanged> ) {
POPMARK;
...
That's obviously correct, and more robust against changes to perl's
internals.
Show quoted text> 4) The "INT2PTR()" stuff is just to shut up an "assignment makes
> pointer from integer without a cast" and a "comparison between pointer
> and integer" warning. Is that the right approach to getting rid of
> those warnings ? (It seems to have done the trick.)
Wrong way around. The difference between two pointers is just an
integer, so you wanted this:
PTRV temp;
PPCODE:
temp = PL_markstack_ptr - PL_markstack;
(And the corresponding expression later)
This also fixes #5. PTRV is whatever Configure decided was an unsigned
integer the same size as a pointer, hence must be big enough.
Ironically, in the couple of places where perl does this, it just uses
an I32 - but the mark stack is unlikely to ever grow that large, it's
roughly the same as the call stack height.
Show quoted text> 1) Does that fix the particular problem for you ?
(I'll get back to you on this when I've had time to run some tests)