On Sun, Sep 07, 2003 at 09:02:11AM -0700 Jan Dubois wrote: > On Sun, 07 Sep 2003 09:49:32 +0200, Tassilo von Parseval > <[EMAIL PROTECTED]> wrote:
> >this is the strangest thing I've ever encountered so far with XS. To me > >it looks like a very obscure bug in perl, but hopefully it's not. The > >Perl examples actually use autobox, but the very same behaviour shows up > >when using a pure functional interface: > > > >I have a very basic C function that triggers a Perl callback: > > > > SV * call_Pslice (const char *func) { > > SV *res; > > > > dSP; > > ENTER; > > SAVETMPS; > > PUTBACK; > > > > (void)call_pv(func, G_SCALAR); > > SPAGAIN; > > > > res = newSVsv(POPs); > > > > PUTBACK; > > FREETMPS; > > LEAVE; > > > > return sv_2mortal(res); > > } > > You are missing a PUSHMARK(xxx) call in here. The call_pv() will pop your > callers frame from the stack, and you caller doesn't seem to adjust for > it. Grrr, yes! PUSHMARK(SP) before the call fixes it. I guess since I didn't explicitely pushed the arguments for the Perl-callback onto the stack (and instead just left the old arguments there to pass them on), I forgot to adjust the markstack accordingly. Thanks for spotting it, this solves my most serious problem! > Two more unrelated notes: > > 1) You call sv_2mortal() on your result without checking if the result has > the SvREADONLY bit set. If the sub can return undef, you may be modifying > the refcount of an immortal, which doesn't matter in most cases as it > starts with a refcount of 2**31, but is still bad style (IMO). The sub may return nothing actually...I omitted to handle this case. Second thanks. > 2) Calling call_xxx() without G_EVAL often doesn't work correctly when > your Perl sub can die(). Maybe it is just cargo cult, but I've been > bitten by this one too many times and now always specify G_EVAL and check > SvTRUE(ERRSV) myself to handle exceptions myself. That fortunately can't happen since the Perl-callback it calls is supplied by me...it does a substitution and either returns the matched string (matched by left side of s///) or nothing. But I have two other places where code from the user is triggered. However, when I look at print "foobar"->each_byte(sub { warn chr(shift), "\n"; die }); __END__ f Died at - line 1 This seems to do the right thing. perlcall.pod says on that: [ example ] 1. We want to be able to catch the die so we have used the G_EVAL flag. Not specifying this flag would mean that the program would terminate immediately at the die statement in the subroutine Sub- tract. I'll do a few tests and see whether not using G_EVAL can produce inconsistent results. I guess that if (SvTRUE(ERRSV)) croak(Nullch); would then fix them. Thanks for warning me! Tassilo -- $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({ pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#; $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval