X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Findirect.git;a=blobdiff_plain;f=indirect.xs;h=dbcaad15c77d6250114a613c3151a3318375d2ba;hp=ba9c503958a997ab3b043683cbd0b48b9af213f4;hb=85db13117ff9f1611f5f0364093799351673840f;hpb=b692a67bb2d094808f4ef331df53093a4019b34e diff --git a/indirect.xs b/indirect.xs index ba9c503..dbcaad1 100644 --- a/indirect.xs +++ b/indirect.xs @@ -200,6 +200,7 @@ typedef struct { #include "ptable.h" #define ptable_store(T, K, V) ptable_store(aTHX_ (T), (K), (V)) +#define ptable_delete(T, K) ptable_delete(aTHX_ (T), (K)) #define ptable_clear(T) ptable_clear(aTHX_ (T)) #define ptable_free(T) ptable_free(aTHX_ (T)) @@ -329,7 +330,6 @@ STATIC SV *indirect_tag(pTHX_ SV *value) { #define indirect_tag(V) indirect_tag(aTHX_ (V)) indirect_hint_t *h; SV *code = NULL; - dMY_CXT; if (SvROK(value)) { value = SvRV(value); @@ -350,10 +350,13 @@ STATIC SV *indirect_tag(pTHX_ SV *value) { #endif /* !I_HINT_STRUCT */ #if I_THREADSAFE - /* We only need for the key to be an unique tag for looking up the value later. - * Allocated memory provides convenient unique identifiers, so that's why we - * use the hint as the key itself. */ - ptable_hints_store(MY_CXT.tbl, h, h); + { + dMY_CXT; + /* We only need for the key to be an unique tag for looking up the value later + * Allocated memory provides convenient unique identifiers, so that's why we + * use the hint as the key itself. */ + ptable_hints_store(MY_CXT.tbl, h, h); + } #endif /* I_THREADSAFE */ return newSViv(PTR2IV(h)); @@ -362,14 +365,16 @@ STATIC SV *indirect_tag(pTHX_ SV *value) { STATIC SV *indirect_detag(pTHX_ const SV *hint) { #define indirect_detag(H) indirect_detag(aTHX_ (H)) indirect_hint_t *h; - dMY_CXT; if (!(hint && SvIOK(hint))) return NULL; h = INT2PTR(indirect_hint_t *, SvIVX(hint)); #if I_THREADSAFE - h = ptable_fetch(MY_CXT.tbl, h); + { + dMY_CXT; + h = ptable_fetch(MY_CXT.tbl, h); + } #endif /* I_THREADSAFE */ #if I_WORKAROUND_REQUIRE_PROPAGATION @@ -389,7 +394,10 @@ STATIC SV *indirect_hint(pTHX) { if (IN_PERL_RUNTIME) return NULL; -#if I_HAS_PERL(5, 9, 5) +#ifdef cop_hints_fetch_pvn + hint = cop_hints_fetch_pvn(PL_curcop, __PACKAGE__, __PACKAGE_LEN__, + indirect_hash, 0); +#elif I_HAS_PERL(5, 9, 5) hint = Perl_refcounted_he_fetch(aTHX_ PL_curcop->cop_hints_hash, NULL, __PACKAGE__, __PACKAGE_LEN__, @@ -397,13 +405,13 @@ STATIC SV *indirect_hint(pTHX) { indirect_hash); #else { - SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__, - indirect_hash); + SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__, 0); if (!val) return 0; hint = *val; } #endif + return indirect_detag(hint); } @@ -453,7 +461,7 @@ STATIC void indirect_map_delete(pTHX_ const OP *o) { #define indirect_map_delete(O) indirect_map_delete(aTHX_ (O)) dMY_CXT; - ptable_store(MY_CXT.map, o, NULL); + ptable_delete(MY_CXT.map, o); } /* --- Check functions ----------------------------------------------------- */ @@ -461,7 +469,7 @@ STATIC void indirect_map_delete(pTHX_ const OP *o) { STATIC int indirect_find(pTHX_ SV *sv, const char *s, STRLEN *pos) { #define indirect_find(N, S, P) indirect_find(aTHX_ (N), (S), (P)) STRLEN len; - const char *p = NULL, *r = SvPV_const(sv, len); + const char *p, *r = SvPV_const(sv, len); if (len >= 1 && *r == '$') { ++r; @@ -471,15 +479,18 @@ STATIC int indirect_find(pTHX_ SV *sv, const char *s, STRLEN *pos) { return 0; } - p = strstr(s, r); - while (p) { - p += len; - if (!isALNUM(*p)) + p = s; + while (1) { + p = strstr(p, r); + if (!p) + return 0; + if (!isALNUM(p[len])) break; - p = strstr(p + 1, r); + /* p points to a word that has r as prefix, skip the rest of the word */ + p += len + 1; + while (isALNUM(*p)) + ++p; } - if (!p) - return 0; *pos = p - SvPVX_const(PL_linestr); @@ -491,7 +502,7 @@ STATIC int indirect_find(pTHX_ SV *sv, const char *s, STRLEN *pos) { STATIC OP *(*indirect_old_ck_const)(pTHX_ OP *) = 0; STATIC OP *indirect_ck_const(pTHX_ OP *o) { - o = CALL_FPTR(indirect_old_ck_const)(aTHX_ o); + o = indirect_old_ck_const(aTHX_ o); if (indirect_hint()) { SV *sv = cSVOPo_sv; @@ -564,14 +575,14 @@ STATIC OP *indirect_ck_rv2sv(pTHX_ OP *o) { goto done; } - o = CALL_FPTR(indirect_old_ck_rv2sv)(aTHX_ o); + o = indirect_old_ck_rv2sv(aTHX_ o); indirect_map_store(o, pos, sv, CopLINE(&PL_compiling)); return o; } done: - o = CALL_FPTR(indirect_old_ck_rv2sv)(aTHX_ o); + o = indirect_old_ck_rv2sv(aTHX_ o); indirect_map_delete(o); return o; @@ -582,7 +593,7 @@ done: STATIC OP *(*indirect_old_ck_padany)(pTHX_ OP *) = 0; STATIC OP *indirect_ck_padany(pTHX_ OP *o) { - o = CALL_FPTR(indirect_old_ck_padany)(aTHX_ o); + o = indirect_old_ck_padany(aTHX_ o); if (indirect_hint()) { SV *sv; @@ -616,7 +627,7 @@ STATIC OP *indirect_ck_scope(pTHX_ OP *o) { case OP_SCOPE: old_ck = indirect_old_ck_scope; break; case OP_LINESEQ: old_ck = indirect_old_ck_lineseq; break; } - o = CALL_FPTR(old_ck)(aTHX_ o); + o = old_ck(aTHX_ o); if (indirect_hint()) { indirect_map_store(o, PL_oldbufptr - SvPVX_const(PL_linestr), @@ -647,24 +658,16 @@ STATIC OP *indirect_ck_method(pTHX_ OP *o) { line_t line; SV *sv; - if (oi) { - sv = sv_2mortal(newSVpvn(oi->buf, oi->len)); - pos = oi->pos; - /* Keep the old line so that we really point to the first line of the - * expression. */ - line = oi->line; - } else { - sv = cSVOPx_sv(op); - if (!SvPOK(sv) || (SvTYPE(sv) < SVt_PV)) - goto done; - sv = sv_mortalcopy(sv); + if (!oi) + goto done; - if (!indirect_find(sv, PL_oldbufptr, &pos)) - goto done; - line = CopLINE(&PL_compiling); - } + sv = sv_2mortal(newSVpvn(oi->buf, oi->len)); + pos = oi->pos; + /* Keep the old line so that we really point to the first line of the + * expression. */ + line = oi->line; - o = CALL_FPTR(indirect_old_ck_method)(aTHX_ o); + o = indirect_old_ck_method(aTHX_ o); /* o may now be a method_named */ indirect_map_store(o, pos, sv, line); @@ -673,7 +676,7 @@ STATIC OP *indirect_ck_method(pTHX_ OP *o) { } done: - o = CALL_FPTR(indirect_old_ck_method)(aTHX_ o); + o = indirect_old_ck_method(aTHX_ o); indirect_map_delete(o); return o; @@ -701,14 +704,14 @@ STATIC OP *indirect_ck_method_named(pTHX_ OP *o) { goto done; line = CopLINE(&PL_compiling); - o = CALL_FPTR(indirect_old_ck_method_named)(aTHX_ o); + o = indirect_old_ck_method_named(aTHX_ o); indirect_map_store(o, pos, sv, line); return o; } done: - o = CALL_FPTR(indirect_old_ck_method_named)(aTHX_ o); + o = indirect_old_ck_method_named(aTHX_ o); indirect_map_delete(o); return o; @@ -716,22 +719,12 @@ done: /* ... ck_entersub ......................................................... */ -STATIC int indirect_is_indirect(const indirect_op_info_t *moi, const indirect_op_info_t *ooi) { - if (moi->pos > ooi->pos) - return 0; - - if (moi->pos == ooi->pos) - return moi->len == ooi->len && !memcmp(moi->buf, ooi->buf, moi->len); - - return 1; -} - STATIC OP *(*indirect_old_ck_entersub)(pTHX_ OP *) = 0; STATIC OP *indirect_ck_entersub(pTHX_ OP *o) { SV *code = indirect_hint(); - o = CALL_FPTR(indirect_old_ck_entersub)(aTHX_ o); + o = indirect_old_ck_entersub(aTHX_ o); if (code) { const indirect_op_info_t *moi, *ooi; @@ -775,7 +768,10 @@ STATIC OP *indirect_ck_entersub(pTHX_ OP *o) { if (!ooi) goto done; - if (indirect_is_indirect(moi, ooi)) { + /* When positions are identical, the method and the object must have the + * same name. But it also means that it is an indirect call, as "foo->foo" + * results in different positions. */ + if (moi->pos <= ooi->pos) { SV *file; dSP; @@ -812,8 +808,6 @@ done: STATIC U32 indirect_initialized = 0; STATIC void indirect_teardown(pTHX_ void *root) { - dMY_CXT; - if (!indirect_initialized) return; @@ -822,10 +816,13 @@ STATIC void indirect_teardown(pTHX_ void *root) { return; #endif - ptable_free(MY_CXT.map); + { + dMY_CXT; + ptable_free(MY_CXT.map); #if I_THREADSAFE - ptable_hints_free(MY_CXT.tbl); + ptable_hints_free(MY_CXT.tbl); #endif + } PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_old_ck_const); indirect_old_ck_const = 0;