This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Eliminate SVrepl_EVAL and SvEVALED()
authorDavid Mitchell <davem@iabyn.com>
Thu, 10 Nov 2016 21:38:30 +0000 (21:38 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 12 Nov 2016 16:15:09 +0000 (16:15 +0000)
This flag is only used to indicate that the SV holding the text of the
replacement part of a s/// has seen at least one /e.

Instead, set the IVX field in the SV to a true value.
(We already set the NVX field on that SV to indicate a multi-src-line
substitution).

This is to reduce the number of odd special cases for the SVpbm_VALID flag.

dump.c
ext/Devel-Peek/t/Peek.t
sv.h
toke.c

diff --git a/dump.c b/dump.c
index be89333..5b59500 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1509,15 +1509,13 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        }
        /* FALLTHROUGH */
     default:
-    evaled_or_uv:
-       if (SvEVALED(sv))       sv_catpv(d, "EVALED,");
+    do_uv:
        if (SvIsUV(sv) && !(flags & SVf_ROK))   sv_catpv(d, "IsUV,");
        break;
     case SVt_PVMG:
        if (SvTAIL(sv))         sv_catpv(d, "TAIL,");
        if (SvVALID(sv))        sv_catpv(d, "VALID,");
-       /* FALLTHROUGH */
-       goto evaled_or_uv;
+       goto do_uv;
     case SVt_PVAV:
        break;
     }
index d5d3f5c..52f75bf 100644 (file)
@@ -1045,14 +1045,10 @@ unless ($Config{useithreads}) {
 
     eval 'index "", perl';
 
-    # FIXME - really this shouldn't say EVALED. It's a false posistive on
-    # 0x40000000 being used for several things, not a flag for "I'm in a string
-    # eval"
-
     do_test('string constant now an FBM', perl,
 'SV = PVMG\\($ADDR\\) at $ADDR
   REFCNT = 5
-  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
+  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID\\)
   PV = $ADDR "rule"\\\0
   CUR = 4
   LEN = \d+
@@ -1072,7 +1068,7 @@ unless ($Config{useithreads}) {
     do_test('string constant still an FBM', perl,
 'SV = PVMG\\($ADDR\\) at $ADDR
   REFCNT = 5
-  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
+  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID\\)
   PV = $ADDR "rule"\\\0
   CUR = 4
   LEN = \d+
@@ -1112,7 +1108,7 @@ unless ($Config{useithreads}) {
 
     my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
   REFCNT = 6
-  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID,EVALED\\)
+  FLAGS = \\($PADMY,SMG,POK,(?:IsCOW,)?READONLY,(?:IsCOW,)?pPOK,VALID\\)
   PV = $ADDR "foam"\\\0
   CUR = 4
   LEN = \d+
diff --git a/sv.h b/sv.h
index 01277af..c33a9a4 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -456,8 +456,6 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 /* This is only set true on a PVGV when it's playing "PVBM", but is tested for
    on any regular scalar (anything <= PVLV) */
 #define SVpbm_VALID    0x40000000
-/* Only used in toke.c on an SV stored in PL_lex_repl */
-#define SVrepl_EVAL    0x40000000  /* Replacement part of s///e */
 
 /* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV  */
 #define SVf_IVisUV     0x80000000  /* use XPVUV instead of XPVIV */
@@ -492,6 +490,7 @@ union _xivu {
     IV     xivu_iv;            /* integer value */
     UV     xivu_uv;
     HEK *   xivu_namehek;      /* xpvlv, xpvgv: GvNAME */
+    bool    xivu_eval_seen;     /* used internally by S_scan_subst() */
 };
 
 union _xmgu {
@@ -1120,10 +1119,6 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 #  define SvCOMPILED_off(sv)
 #endif
 
-#define SvEVALED(sv)           (SvFLAGS(sv) & SVrepl_EVAL)
-#define SvEVALED_on(sv)                (SvFLAGS(sv) |= SVrepl_EVAL)
-#define SvEVALED_off(sv)       (SvFLAGS(sv) &= ~SVrepl_EVAL)
-
 #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define SvVALID(sv)          ({ const SV *const _svvalid = (const SV*)(sv); \
                                   if (SvFLAGS(_svvalid) & SVpbm_VALID && !SvSCREAM(_svvalid)) \
diff --git a/toke.c b/toke.c
index 2bc9fb2..061b4d3 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -88,6 +88,11 @@ Individual members of C<PL_parser> have their own documentation.
 #  define PL_nexttype          (PL_parser->nexttype)
 #  define PL_nextval           (PL_parser->nextval)
 
+
+#define SvEVALED(sv) \
+    (SvTYPE(sv) >= SVt_PVNV \
+    && ((XPVIV*)SvANY(sv))->xiv_u.xivu_eval_seen)
+
 static const char* const ident_too_long = "Identifier too long";
 
 #  define NEXTVAL_NEXTTOKE PL_nextval[PL_nexttoke]
@@ -9370,6 +9375,7 @@ S_scan_subst(pTHX_ char *start)
     PMOP *pm;
     I32 first_start;
     line_t first_line;
+    line_t linediff = 0;
     I32 es = 0;
     char charset = '\0';    /* character set modifier */
     unsigned int x_mod_count = 0;
@@ -9433,15 +9439,24 @@ S_scan_subst(pTHX_ char *start)
        sv_catpvs(repl, "{");
        sv_catsv(repl, PL_parser->lex_sub_repl);
        sv_catpvs(repl, "}");
-       SvEVALED_on(repl);
+       ((XPVIV*)SvANY(PL_parser->lex_sub_repl))->xiv_u.xivu_eval_seen = 1;
        SvREFCNT_dec(PL_parser->lex_sub_repl);
        PL_parser->lex_sub_repl = repl;
+        es = 1;
     }
-    if (CopLINE(PL_curcop) != first_line) {
-       sv_upgrade(PL_parser->lex_sub_repl, SVt_PVNV);
-       ((XPVNV*)SvANY(PL_parser->lex_sub_repl))->xnv_u.xnv_lines =
-           CopLINE(PL_curcop) - first_line;
+
+
+    linediff = CopLINE(PL_curcop) - first_line;
+    if (linediff)
        CopLINE_set(PL_curcop, first_line);
+
+    if (linediff || es) {
+        /* the IVX field indicates that the replacement string is a s///e;
+         * the NVX field indicates how many src code lines the replacement
+         * spreads over */
+        sv_upgrade(PL_parser->lex_sub_repl, SVt_PVNV);
+        ((XPVNV*)SvANY(PL_parser->lex_sub_repl))->xnv_u.xnv_lines = 0;
+        ((XPVIV*)SvANY(PL_parser->lex_sub_repl))->xiv_u.xivu_eval_seen = es;
     }
 
     PL_lex_op = (OP*)pm;