X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Findirect.git;a=blobdiff_plain;f=indirect.xs;h=578c15447e5a3dfe1f815eeaed161731a67312f7;hp=df9bca8d979753c50637b079c8b639cab73f51c8;hb=690b145b767297bcf2561580e1ebda2115b42f5f;hpb=90ac1453cad3b894c5e1d7962afe502d03112bb9 diff --git a/indirect.xs b/indirect.xs index df9bca8..578c154 100644 --- a/indirect.xs +++ b/indirect.xs @@ -142,7 +142,7 @@ typedef struct { SV *code; - IV cxreq; + IV require_tag; } indirect_hint_t; #define I_HINT_STRUCT 1 @@ -256,11 +256,12 @@ STATIC void indirect_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { #if I_HINT_STRUCT - h2 = PerlMemShared_malloc(sizeof *h2); - h2->code = indirect_clone(h1->code, ud->owner); + h2 = PerlMemShared_malloc(sizeof *h2); + h2->code = indirect_clone(h1->code, ud->owner); SvREFCNT_inc(h2->code); #if I_WORKAROUND_REQUIRE_PROPAGATION - h2->cxreq = h1->cxreq; + h2->require_tag = PTR2IV(indirect_clone(INT2PTR(SV *, h1->require_tag), + ud->owner)); #endif #else /* I_HINT_STRUCT */ @@ -273,22 +274,13 @@ STATIC void indirect_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { ptable_hints_store(ud->tbl, ent->key, h2); } -STATIC void indirect_thread_cleanup(pTHX_ void *); +#include "reap.h" STATIC void indirect_thread_cleanup(pTHX_ void *ud) { - int *level = ud; + dMY_CXT; - if (*level) { - *level = 0; - LEAVE; - SAVEDESTRUCTOR_X(indirect_thread_cleanup, level); - ENTER; - } else { - dMY_CXT; - PerlMemShared_free(level); - ptable_free(MY_CXT.map); - ptable_hints_free(MY_CXT.tbl); - } + ptable_free(MY_CXT.map); + ptable_hints_free(MY_CXT.tbl); } #endif /* I_THREADSAFE */ @@ -296,20 +288,46 @@ STATIC void indirect_thread_cleanup(pTHX_ void *ud) { #if I_WORKAROUND_REQUIRE_PROPAGATION STATIC IV indirect_require_tag(pTHX) { #define indirect_require_tag() indirect_require_tag(aTHX) - const PERL_SI *si; - - for (si = PL_curstackinfo; si; si = si->si_prev) { - I32 cxix; - - for (cxix = si->si_cxix; cxix >= 0; --cxix) { - const PERL_CONTEXT *cx = si->si_cxstack + cxix; - - if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_REQUIRE) - return PTR2IV(cx); + const CV *cv, *outside; + + cv = PL_compcv; + + if (!cv) { + /* If for some reason the pragma is operational at run-time, try to discover + * the current cv in use. */ + const PERL_SI *si; + + for (si = PL_curstackinfo; si; si = si->si_prev) { + I32 cxix; + + for (cxix = si->si_cxix; cxix >= 0; --cxix) { + const PERL_CONTEXT *cx = si->si_cxstack + cxix; + + switch (CxTYPE(cx)) { + case CXt_SUB: + case CXt_FORMAT: + /* The propagation workaround is only needed up to 5.10.0 and at that + * time format and sub contexts were still identical. And even later the + * cv members offsets should have been kept the same. */ + cv = cx->blk_sub.cv; + goto get_enclosing_cv; + case CXt_EVAL: + cv = cx->blk_eval.cv; + goto get_enclosing_cv; + default: + break; + } + } } + + cv = PL_main_cv; } - return PTR2IV(NULL); +get_enclosing_cv: + for (outside = CvOUTSIDE(cv); outside; outside = CvOUTSIDE(cv)) + cv = outside; + + return PTR2IV(cv); } #endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ @@ -329,9 +347,9 @@ STATIC SV *indirect_tag(pTHX_ SV *value) { #if I_HINT_STRUCT h = PerlMemShared_malloc(sizeof *h); - h->code = code; + h->code = code; # if I_WORKAROUND_REQUIRE_PROPAGATION - h->cxreq = indirect_require_tag(); + h->require_tag = indirect_require_tag(); # endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ #else /* I_HINT_STRUCT */ h = code; @@ -361,7 +379,7 @@ STATIC SV *indirect_detag(pTHX_ const SV *hint) { #endif /* I_THREADSAFE */ #if I_WORKAROUND_REQUIRE_PROPAGATION - if (indirect_require_tag() != h->cxreq) + if (indirect_require_tag() != h->require_tag) return NULL; #endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ @@ -444,7 +462,6 @@ STATIC void indirect_map_store(pTHX_ const OP *o, const char *src, SV *sv, line_ STATIC const indirect_op_info_t *indirect_map_fetch(pTHX_ const OP *o) { #define indirect_map_fetch(O) indirect_map_fetch(aTHX_ (O)) - const indirect_op_info_t *val; dMY_CXT; if (MY_CXT.linestr != SvPVX_const(PL_linestr)) @@ -800,13 +817,15 @@ STATIC void indirect_setup(pTHX) { if (indirect_initialized) return; - MY_CXT_INIT; + { + MY_CXT_INIT; #if I_THREADSAFE - MY_CXT.tbl = ptable_new(); - MY_CXT.owner = aTHX; + MY_CXT.tbl = ptable_new(); + MY_CXT.owner = aTHX; #endif - MY_CXT.map = ptable_new(); - MY_CXT.linestr = NULL; + MY_CXT.map = ptable_new(); + MY_CXT.linestr = NULL; + } indirect_old_ck_const = PL_check[OP_CONST]; PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_ck_const); @@ -863,8 +882,7 @@ CLONE(...) PROTOTYPE: DISABLE PREINIT: ptable *t; - int *level; -CODE: +PPCODE: { my_cxt_t ud; dMY_CXT; @@ -879,13 +897,8 @@ CODE: MY_CXT.tbl = t; MY_CXT.owner = aTHX; } - { - level = PerlMemShared_malloc(sizeof *level); - *level = 1; - LEAVE; - SAVEDESTRUCTOR_X(indirect_thread_cleanup, level); - ENTER; - } + reap(3, indirect_thread_cleanup, NULL); + XSRETURN(0); #endif