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

Reply via email to