From: Vincent Pit Date: Thu, 19 Aug 2010 15:05:48 +0000 (+0200) Subject: Store the offset from the source buffer beginning in the op info object X-Git-Tag: v0.23~10 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Findirect.git;a=commitdiff_plain;h=b692a67bb2d094808f4ef331df53093a4019b34e Store the offset from the source buffer beginning in the op info object This fixes potential errors where some indirect constructs are wrongly reported (or failed to be) when the source buffer is grown between the method and the object name. Also, from now on, an op info object is never stored when the correct position could not have been found in the source buffer. This is really how it should have behaved from the beginning. --- diff --git a/indirect.xs b/indirect.xs index 8a4a192..ba9c503 100644 --- a/indirect.xs +++ b/indirect.xs @@ -62,6 +62,9 @@ #define I_HAS_PERL(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S)))))) #if I_HAS_PERL(5, 10, 0) || defined(PL_parser) +# ifndef PL_linestr +# define PL_linestr PL_parser->linestr +# endif # ifndef PL_bufptr # define PL_bufptr PL_parser->bufptr # endif @@ -69,6 +72,9 @@ # define PL_oldbufptr PL_parser->oldbufptr # endif #else +# ifndef PL_linestr +# define PL_linestr PL_Ilinestr +# endif # ifndef PL_bufptr # define PL_bufptr PL_Ibufptr # endif @@ -176,10 +182,11 @@ typedef SV indirect_hint_t; * thread cleanup. */ typedef struct { - const char *pos; - char *buf; - STRLEN len, size; - line_t line; + STRLEN pos; + STRLEN size; + STRLEN len; + char *buf; + line_t line; } indirect_op_info_t; #define PTABLE_NAME ptable @@ -402,8 +409,8 @@ STATIC SV *indirect_hint(pTHX) { /* ... op -> source position ............................................... */ -STATIC void indirect_map_store(pTHX_ const OP *o, const char *src, SV *sv, line_t line) { -#define indirect_map_store(O, S, N, L) indirect_map_store(aTHX_ (O), (S), (N), (L)) +STATIC void indirect_map_store(pTHX_ const OP *o, STRLEN pos, SV *sv, line_t line) { +#define indirect_map_store(O, P, N, L) indirect_map_store(aTHX_ (O), (P), (N), (L)) indirect_op_info_t *oi; const char *s; STRLEN len; @@ -431,7 +438,7 @@ STATIC void indirect_map_store(pTHX_ const OP *o, const char *src, SV *sv, line_ Copy(s, oi->buf, len, char); oi->len = len; - oi->pos = src; + oi->pos = pos; oi->line = line; } @@ -451,8 +458,8 @@ STATIC void indirect_map_delete(pTHX_ const OP *o) { /* --- Check functions ----------------------------------------------------- */ -STATIC const char *indirect_find(pTHX_ SV *sv, const char *s) { -#define indirect_find(N, S) indirect_find(aTHX_ (N), (S)) +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); @@ -461,7 +468,7 @@ STATIC const char *indirect_find(pTHX_ SV *sv, const char *s) { --len; s = strchr(s, '$'); if (!s) - return NULL; + return 0; } p = strstr(s, r); @@ -471,8 +478,12 @@ STATIC const char *indirect_find(pTHX_ SV *sv, const char *s) { break; p = strstr(p + 1, r); } + if (!p) + return 0; - return p; + *pos = p - SvPVX_const(PL_linestr); + + return 1; } /* ... ck_const ............................................................ */ @@ -484,10 +495,14 @@ STATIC OP *indirect_ck_const(pTHX_ OP *o) { if (indirect_hint()) { SV *sv = cSVOPo_sv; + if (SvPOK(sv) && (SvTYPE(sv) >= SVt_PV)) { - const char *s = indirect_find(sv, PL_oldbufptr); - indirect_map_store(o, s, sv, CopLINE(&PL_compiling)); - return o; + STRLEN pos; + + if (indirect_find(sv, PL_oldbufptr, &pos)) { + indirect_map_store(o, pos, sv, CopLINE(&PL_compiling)); + return o; + } } } @@ -503,8 +518,8 @@ STATIC OP *indirect_ck_rv2sv(pTHX_ OP *o) { if (indirect_hint()) { OP *op = cUNOPo->op_first; SV *sv; - const char *name = NULL, *s; - STRLEN len; + const char *name = NULL; + STRLEN pos, len; OPCODE type = (OPCODE) op->op_type; switch (type) { @@ -527,8 +542,8 @@ STATIC OP *indirect_ck_rv2sv(pTHX_ OP *o) { sv = sv_2mortal(newSVpvn("$", 1)); sv_catpvn_nomg(sv, name, len); - s = indirect_find(sv, PL_oldbufptr); - if (!s) { /* If it failed, retry without the current stash */ + if (!indirect_find(sv, PL_oldbufptr, &pos)) { + /* If it failed, retry without the current stash */ const char *stash = HvNAME_get(PL_curstash); STRLEN stashlen = HvNAMELEN_get(PL_curstash); @@ -545,13 +560,13 @@ STATIC OP *indirect_ck_rv2sv(pTHX_ OP *o) { sv_setpvn(sv, "$", 1); stashlen += 2; sv_catpvn_nomg(sv, name + stashlen, len - stashlen); - s = indirect_find(sv, PL_oldbufptr); - if (!s) + if (!indirect_find(sv, PL_oldbufptr, &pos)) goto done; } o = CALL_FPTR(indirect_old_ck_rv2sv)(aTHX_ o); - indirect_map_store(o, s, sv, CopLINE(&PL_compiling)); + + indirect_map_store(o, pos, sv, CopLINE(&PL_compiling)); return o; } @@ -579,7 +594,8 @@ STATIC OP *indirect_ck_padany(pTHX_ OP *o) { while (s < t && isSPACE(*t)) --t; sv = sv_2mortal(newSVpvn("$", 1)); sv_catpvn_nomg(sv, s, t - s + 1); - indirect_map_store(o, s, sv, CopLINE(&PL_compiling)); + indirect_map_store(o, s - SvPVX_const(PL_linestr), + sv, CopLINE(&PL_compiling)); return o; } } @@ -603,7 +619,8 @@ STATIC OP *indirect_ck_scope(pTHX_ OP *o) { o = CALL_FPTR(old_ck)(aTHX_ o); if (indirect_hint()) { - indirect_map_store(o, PL_oldbufptr, NULL, CopLINE(&PL_compiling)); + indirect_map_store(o, PL_oldbufptr - SvPVX_const(PL_linestr), + NULL, CopLINE(&PL_compiling)); return o; } @@ -626,12 +643,13 @@ STATIC OP *indirect_ck_method(pTHX_ OP *o) { * don't trip up on $obj->$meth. */ if (op && op->op_type == OP_CONST) { const indirect_op_info_t *oi = indirect_map_fetch(op); - const char *s = NULL; + STRLEN pos; line_t line; SV *sv; - if (oi && (s = oi->pos)) { + 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; @@ -639,15 +657,17 @@ STATIC OP *indirect_ck_method(pTHX_ OP *o) { sv = cSVOPx_sv(op); if (!SvPOK(sv) || (SvTYPE(sv) < SVt_PV)) goto done; - sv = sv_mortalcopy(sv); - s = indirect_find(sv, PL_oldbufptr); + sv = sv_mortalcopy(sv); + + if (!indirect_find(sv, PL_oldbufptr, &pos)) + goto done; line = CopLINE(&PL_compiling); } o = CALL_FPTR(indirect_old_ck_method)(aTHX_ o); /* o may now be a method_named */ - indirect_map_store(o, s, sv, line); + indirect_map_store(o, pos, sv, line); return o; } } @@ -668,22 +688,22 @@ STATIC OP *(*indirect_old_ck_method_named)(pTHX_ OP *) = 0; STATIC OP *indirect_ck_method_named(pTHX_ OP *o) { if (indirect_hint()) { - const char *s; + STRLEN pos; line_t line; SV *sv; - sv = cSVOPo_sv; + sv = cSVOPo_sv; if (!SvPOK(sv) || (SvTYPE(sv) < SVt_PV)) goto done; - sv = sv_mortalcopy(sv); - s = indirect_find(sv, PL_oldbufptr); - if (!s) + sv = sv_mortalcopy(sv); + + if (!indirect_find(sv, PL_oldbufptr, &pos)) goto done; line = CopLINE(&PL_compiling); o = CALL_FPTR(indirect_old_ck_method_named)(aTHX_ o); - indirect_map_store(o, s, sv, line); + indirect_map_store(o, pos, sv, line); return o; } @@ -748,11 +768,11 @@ STATIC OP *indirect_ck_entersub(pTHX_ OP *o) { goto done; moi = indirect_map_fetch(mop); - if (!(moi && moi->pos)) + if (!moi) goto done; ooi = indirect_map_fetch(oop); - if (!(ooi && ooi->pos)) + if (!ooi) goto done; if (indirect_is_indirect(moi, ooi)) {