cosimo has asked for the wisdom of the Perl Monks concerning the following question:
This code is partly taken from JSON::XS. I'm trying to write an XS function that takes an array or hashref in sv and, with some custom rules, serializes the content into a result scalar as one big string with everything.GV *to_string = gv_fetchmethod (SvSTASH (sv), "toString"); if (to_string) { dSP; SV *res_sv; /* result scalar */ ENTER; SAVETMPS; /* Declare function arguments */ PUSHMARK (SP); XPUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), SvSTASH (sv))); PUTBACK; /* Call in scalar context (G_SCALAR) */ call_sv ((SV *)GvCV (to_string), G_SCALAR); SPAGAIN; /* Fetch returned SV from the stack */ res_sv = POPs; PUTBACK; /* Append returned SvPVX to our SV */ append_sv(res_sv, result); FREETMPS; LEAVE; }
When an hashref is really a blessed object, I want its toString() method to be called to dump the hashref content to my result SV. Calling the object's toString() method is the task for the code I shown you.
I think the problem lies here: what happens when, eventually, an object's toString() method code, for whatever reason, happens to contain a call to my XS function? (that could, in turn, call other toString() methods for other kind of objects...).
Does this break my stack manipulation? I think so, because I see segfaults and other bad things when toString() completes and the the code tries to return the resulting SV to the caller.
I feel I'm missing something about the stack manipulation in this case, but I really don't know how to proceed. Thank you for any help you can provide.
UPDATE: 2008-05-25 14:53 CETI believe I have solved the problem. It was a real bitch of a hellish problem, trust me. Seems I've been bitten by old XS conventions about returning values to Perl code.
As it turned out, the problem was not in the snippet I showed you, but rather in this one, that called the function above, and incorrectly returned the resulting scalar to the caller. Real names changed to protect the innocents :)
void func (SV *scalar) PPCODE: SV *result = newSV(INIT_SIZE); sv_setpv(result, ""); SvPOK_only(result); serialize(result, scalar); XPUSHs(result);
The fixed and working version follows:
SV* func (SV *scalar) CODE: SV *result = newSV(INIT_SIZE); sv_setpv(result, ""); SvPOK_only(result); serialize(result, scalar); RETVAL = result; OUTPUT: RETVAL
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Problem on perl callbacks from XS
by almut (Canon) on May 24, 2008 at 23:22 UTC | |
by cosimo (Hermit) on May 25, 2008 at 08:45 UTC | |
|
Re: Problem on perl callbacks from XS
by syphilis (Archbishop) on May 25, 2008 at 00:09 UTC | |
|
Re: Problem on perl callbacks from XS
by tachyon-II (Chaplain) on May 25, 2008 at 06:46 UTC | |
by cosimo (Hermit) on May 25, 2008 at 09:04 UTC | |
by tachyon-II (Chaplain) on May 25, 2008 at 15:35 UTC |