develooper Front page | perl.perl5.porters | Postings from August 2012

calling an xsub from an xsub without perl

Thread Next
From:
bulk 88
Date:
August 25, 2012 10:20
Subject:
calling an xsub from an xsub without perl
Message ID:
COL115-W12A48EE034EAF85DCDDBD8DFBC0@phx.gbl

I've been wondering if there is a more efficient or faster way to call an XSUB from an XSUB without going through call_sv/call_pv and pp_entersub. 

So I tried this
_____________________________________________________

MODULE = Local::XS   PACKAGE = Local::XS

void
DESTROY(self)
    SV * self
PREINIT:
    SV * retsv;
PPCODE:
    PUSHMARK(SP);
    PUSHs(self);
    PUSHs(&PL_sv_yes);
    PUTBACK;
     /*the cv is wrong with this hack*/
    XS_Local__XS__Delete(aTHX_ cv);
    /*call_pv("Local::XS::Delete", 0);*/
    retsv = POPs;
    if(!sv_true(retsv)){
        croak("%s: Delete() failed", "Local::XS::DESTROY");
    }
______________________________________________________

and it works with no superficial errors or panics/Bizares, etc. The only global changes global changes the parent/all XSUBs make is removing an "element" from the markstack and pushing back the C auto SP if it is a PPCODE (CODE leave's C auto SP at the end of the XSUB's params, suitable for POPs'ing incoming args in an XSUB, in a PPCODE, if you do a SPAGAIN and C auto SP is at the end of the @_ params again). By re-adding a new mark to the markstack the Perl stack isn't corrupted for the Perl opcode caller. I know the CV * is wrong, I'm not sure what the side effect of that will be in the child XSUB other than a broken croak_xs_usage, that can be fixed with a get_cv. I haven't tried to work out how to calculate the number of items returned by the child (it can't be that hard, its the delta between some mark and SP +/-1 probably).

So my question is? How wrong is this? How much would this be using perl private api/subject to breakage? Should some formal macros be added to the perl public API and ppport.h that will make calling an XSUB from an XSUB "safe" forever with all the cavets/bugs mentioned?

Is GIMME_V broken for the child with this hack? Is it worth fixing or just delare context will always be the last caller who went through entersub's context?

Here is a GIMME_V expanded from some Perl, (10/12/14/16 I don't remember, it changed over the last 2-3 years to be something slightly shorter as of today I remember).
_____________________________________________________
     static U32 my_gimme_v (register PerlInterpreter * my_perl)
{
    return ((((my_perl->Iop))->op_flags & 3) == 1 ? 1 : (((my_perl->Iop))->op_flags & 3) ==
            2 ? 2 : (((my_perl->Iop))->op_flags & 3) == 3 ? 3 : Perl_block_gimme (my_perl));
}
_____________________________________________________
call_* does change PL_op of course.

Method resolution/inheritance is broken also of course.

Maybe (I can't do this) call_* can have a shortcut path to directly call the C XSUB if the SV is a CV, and is an XSUB, and *psuedocode* (flags & CONTEXT_BITS == PL_op->flags & CONTEXT_BITS) ?

Or with that much machine code and checks, you might as well do the pp_entersub?

 		 	   		  
Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About