X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Upper.xs;h=6ff176d68d913973734a80e8bde1d18b85eec2eb;hb=915ea103e7467eb15f3e5a37c4d4329a2803ea3a;hp=2d7efd3fd16fd51d27a108c0313e7e37f90fe46a;hpb=48b50a3930f2b3b3f7a56616e903909787f1439d;p=perl%2Fmodules%2FScope-Upper.git diff --git a/Upper.xs b/Upper.xs index 2d7efd3..6ff176d 100644 --- a/Upper.xs +++ b/Upper.xs @@ -17,10 +17,7 @@ /* --- Compatibility ------------------------------------------------------- */ /* perl 5.23.8 onwards has a revamped context system */ -#if XSH_HAS_PERL(5, 23, 8) -# define SU_HAS_NEW_CXT -#endif - +#define SU_HAS_NEW_CXT XSH_HAS_PERL(5, 23, 8) #ifndef dVAR # define dVAR dNOOP @@ -356,10 +353,10 @@ typedef struct { CV *callback; CV *renamed; -#ifdef SU_HAS_NEW_CXT - U8 *cxtypes; /* array of saved context types */ - I32 gap; /* how many contexts have temporarily CXt_NULLed out */ - AV* argarray; /* the PL_curpad[0] of the uplevel sub */ +#if SU_HAS_NEW_CXT + U8 *cxtypes; /* array of saved context types */ + I32 gap; /* how many contexts have temporarily CXt_NULLed out*/ + AV* argarray; /* the PL_curpad[0] of the uplevel sub */ #else I32 target_depth; CV *target; @@ -378,7 +375,7 @@ typedef struct { #endif } su_uplevel_ud; -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT /* used to flag a context stack entry whose type has been temporarily * set to CXt_NULL. It relies on perl not using this value for real * CXt_NULL entries. @@ -398,7 +395,7 @@ static su_uplevel_ud *su_uplevel_ud_new(pTHX) { sud->tmp_uid_storage.used = 0; sud->tmp_uid_storage.alloc = 0; - #ifndef SU_HAS_NEW_CXT +#if !SU_HAS_NEW_CXT Newx(si, 1, PERL_SI); si->si_stack = newAV(); AvREAL_off(si->si_stack); @@ -414,7 +411,7 @@ static su_uplevel_ud *su_uplevel_ud_new(pTHX) { static void su_uplevel_ud_delete(pTHX_ su_uplevel_ud *sud) { #define su_uplevel_ud_delete(S) su_uplevel_ud_delete(aTHX_ (S)) -#ifndef SU_HAS_NEW_CXT +#if !SU_HAS_NEW_CXT PERL_SI *si = sud->si; Safefree(si->si_cxstack); @@ -532,7 +529,6 @@ static void xsh_user_clone(pTHX_ const xsh_user_cxt_t *old_cxt, xsh_user_cxt_t * # define SU_SAVE_HELEM_OR_HDELETE_SIZE SU_SAVE_HELEM_SIZE #endif - #ifndef SvCANEXISTDELETE # define SvCANEXISTDELETE(sv) \ (!SvRMAGICAL(sv) \ @@ -713,19 +709,18 @@ static void su_save_gvcv(pTHX_ GV *gv) { /* --- Actions ------------------------------------------------------------- */ typedef struct { - I32 orig_ix; /* original savestack_ix */ - I32 offset; /* how much we bumped this savestack index */ + I32 orig_ix; /* original savestack_ix */ + I32 offset; /* how much we bumped this savestack index */ } su_ud_origin_elem; typedef struct { - U8 type; - U8 private; + U8 type; + U8 private; /* spare */ - I32 depth; + I32 depth; su_ud_origin_elem *origin; } su_ud_common; - #define SU_UD_TYPE(U) (((su_ud_common *) (U))->type) #define SU_UD_PRIVATE(U) (((su_ud_common *) (U))->private) #define SU_UD_DEPTH(U) (((su_ud_common *) (U))->depth) @@ -905,24 +900,26 @@ static void su_localize(pTHX_ void *ud_) { if (SvTYPE(sv) >= SVt_PVGV) { gv = (GV *) sv; } else { - /* new perl context implementation frees savestack *before* restoring * PL_curcop. Temporarily restore it prematurely to make gv_fetch* * looks up unqualified var names in the caller's package */ -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT COP *old_cop = PL_curcop; - PL_curcop = CX_CUR()->blk_oldcop; + PL_curcop = CX_CUR()->blk_oldcop; #endif #ifdef gv_fetchsv gv = gv_fetchsv(sv, GV_ADDMULTI, t); #else - STRLEN len; - const char *name = SvPV_const(sv, len); - gv = gv_fetchpvn_flags(name, len, GV_ADDMULTI, t); + { + STRLEN len; + const char *name = SvPV_const(sv, len); + gv = gv_fetchpvn_flags(name, len, GV_ADDMULTI, t); + } #endif -#ifdef SU_HAS_NEW_CXT - CX_CUR()->blk_oldcop = PL_curcop; + +#if SU_HAS_NEW_CXT + CX_CUR()->blk_oldcop = old_cop; #endif } @@ -1072,8 +1069,6 @@ static const int su_cxt_enter_count[] = { # endif }; - - /* push at least 'size' slots worth of padding onto the savestack */ static void su_ss_push_padding(pTHX_ void *ud, I32 size) { @@ -1087,11 +1082,8 @@ static void su_ss_push_padding(pTHX_ void *ud, I32 size) { save_alloc((size - SU_SAVE_ALLOC_SIZE)*sizeof(*PL_savestack), 0); } - static void su_pop(pTHX_ void *ud); - - /* push an su_pop destructor onto the savestack with suitable padding. * first indicates that this is the first push of a destructor */ @@ -1110,7 +1102,6 @@ static void su_ss_push_destructor(pTHX_ void *ud, I32 depth, bool first) { PL_savestack_ix <= origin[depth+1].orig_ix + origin[depth+1].offset); } - /* this is called during each leave_scope() via SAVEDESTRUCTOR_X */ static void su_pop(pTHX_ void *ud) { @@ -1171,7 +1162,6 @@ static void su_pop(pTHX_ void *ud) { XSH_D(su_debug_log("%p: end pop: ss_ix=%d\n", ud, PL_savestack_ix)); } - /* --- Initialize the stack and the action userdata ------------------------ */ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { @@ -1184,7 +1174,7 @@ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { XSH_D(su_debug_log("%p: ### su_init(cxix=%d, size=%d)\n", ud, cxix, size)); depth = PL_scopestack_ix - cxstack[cxix].blk_oldscopesp; -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT depth += (cxstack_ix - cxix); /* each context frame holds 1 scope */ #endif XSH_D(su_debug_log( @@ -1229,14 +1219,14 @@ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { * * The passed cxix argument represents the scope we wish to inject into; * we have to adjust all the savestack frame boundaries above (but not - * including) that context. + * including) that context. */ Newx(origin, depth, su_ud_origin_elem); cur_cx_ix = cxix; cur_scope_ix = cxstack[cxix].blk_oldscopesp; -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT XSH_D(su_debug_log("%p: cx=%-2d %-11s\n", ud, cur_cx_ix, SU_CXNAME(cxstack+cur_cx_ix))); cur_cx_ix++; @@ -1246,7 +1236,7 @@ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { I32 *ixp; I32 offset; -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT if ( cur_cx_ix <= cxstack_ix && cur_scope_ix == cxstack[cur_cx_ix].blk_oldscopesp @@ -1304,7 +1294,7 @@ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { origin[i].orig_ix = *ixp; *ixp += offset; -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT XSH_D({ if (ixp == &PL_scopestack[cur_scope_ix-1]) su_debug_log( @@ -1332,7 +1322,6 @@ static void su_init(pTHX_ void *ud, I32 cxix, I32 size) { su_ss_push_destructor(aTHX_ ud, depth-1, 1); } - /* --- Unwind stack -------------------------------------------------------- */ static void su_unwind(pTHX_ void *ud_) { @@ -1652,7 +1641,7 @@ static int su_uplevel_goto_static(const OP *o) { return 0; } -#if !defined(SU_HAS_NEW_CXT) && SU_UPLEVEL_HIJACKS_RUNOPS +#if !SU_HAS_NEW_CXT && SU_UPLEVEL_HIJACKS_RUNOPS static int su_uplevel_goto_runops(pTHX) { #define su_uplevel_goto_runops() su_uplevel_goto_runops(aTHX) @@ -1714,7 +1703,7 @@ done: #define su_at_underscore(C) PadARRAY(PadlistARRAY(CvPADLIST(C))[CvDEPTH(C)])[0] -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT static void su_uplevel_restore_new(pTHX_ void *sus_) { su_uplevel_ud *sud = sus_; @@ -1985,9 +1974,7 @@ static CV *su_cv_clone(pTHX_ CV *proto, GV *gv) { return cv; } - - -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT /* this one-shot runops "loop" is designed to be called just before * execution of the first op following an uplevel()'s entersub. It gets a @@ -2029,8 +2016,6 @@ static int su_uplevel_runops_hook_entersub(pTHX) { return 0; } - - static I32 su_uplevel_new(pTHX_ CV *callback, I32 cxix, I32 args) { su_uplevel_ud *sud; U8 *saved_cxtypes; @@ -2060,7 +2045,6 @@ static I32 su_uplevel_new(pTHX_ CV *callback, I32 cxix, I32 args) { sud->gap = cxstack_ix - cxix + 1; sud->argarray = NULL; - Newx(saved_cxtypes, sud->gap, U8); sud->cxtypes = saved_cxtypes; @@ -2082,7 +2066,6 @@ static I32 su_uplevel_new(pTHX_ CV *callback, I32 cxix, I32 args) { sud->renamed = su_cv_clone(callback, CvGV(base_cv)); sud->old_runops = PL_runops; - if (!CvISXSUB(sud->renamed) && CxHASARGS(&cxstack[cxix])) { sud->argarray = (AV*)su_at_underscore(base_cv); assert(PL_runops != su_uplevel_runops_hook_entersub); @@ -2448,8 +2431,7 @@ static I32 su_context_skip_db(pTHX_ I32 cxix) { return cxix; } - -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT /* convert a physical context stack index into the logical equivalent: * one that ignores all the context frames hidden by uplevel(). @@ -2499,7 +2481,6 @@ static I32 su_context_logical2real(pTHX_ I32 cxix) { # define su_context_logical2real(C) (C) #endif - static I32 su_context_normalize_up(pTHX_ I32 cxix) { #define su_context_normalize_up(C) su_context_normalize_up(aTHX_ (C)) PERL_CONTEXT *cx; @@ -3262,7 +3243,7 @@ PPCODE: args = items - 2; } /* su_uplevel() takes care of extending the stack if needed. */ -#ifdef SU_HAS_NEW_CXT +#if SU_HAS_NEW_CXT ret = su_uplevel_new(aTHX_ (CV *) code, cxix, args); #else ret = su_uplevel_old(aTHX_ (CV *) code, cxix, args);