Abolish wrapped in struct regexp - store the wrapped pattern pointer
Nicholas Clark [Sat, 5 Jan 2008 14:13:48 +0000 (14:13 +0000)]
in the SvPVX().

p4raw-id: //depot/perl@32841

ext/B/t/optree_constants.t
ext/Devel/Peek/t/Peek.t
regcomp.c
regexp.h

index c05138b..bf6384b 100644 (file)
@@ -59,7 +59,11 @@ my $want = { # expected types, how value renders in-line, todos (maybe)
     myaref     => [ $RV_class, '\\\\' ],
     myfl       => [ 'NV', myfl ],
     myint      => [ 'IV', myint ],
+    $] >= 5.011 ? (
+    myrex      => [ $RV_class, '\\\\"\\(?-xism:Foo\\)"' ],
+    ) : (
     myrex      => [ $RV_class, '\\\\' ],
+    ),
     myundef    => [ 'NULL', ],
     ) : (
     myaref     => [ 'PVIV', '' ],
index af9dc02..0047ee5 100644 (file)
@@ -284,10 +284,12 @@ do_test(15,
   RV = $ADDR
   SV = REGEXP\\($ADDR\\) at $ADDR
     REFCNT = 2
-    FLAGS = \\(\\)
+    FLAGS = \\(POK,pPOK\\)
     IV = 0
     NV = 0
-    PV = 0');
+    PV = $ADDR "\\(\\?-xism:tic\\)"\\\0
+    CUR = 12
+    LEN = \\d+');
 } else {
 do_test(15,
         qr(tic),
index 33ed6fc..b1a8cb0 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -4294,8 +4294,9 @@ redo_first_pass:
             + (sizeof(STD_PAT_MODS) - 1)
             + (sizeof("(?:)") - 1);
 
-        Newx(RX_WRAPPED(rx), RXp_WRAPLEN(r) + 1, char );
-        p = RX_WRAPPED(rx);
+       p = sv_grow(rx, RXp_WRAPLEN(r) + 1);
+       SvCUR_set(rx, RXp_WRAPLEN(r));
+       SvPOK_on(rx);
         *p++='('; *p++='?';
         if (has_p)
             *p++ = KEEPCOPY_PAT_MOD; /*'p'*/
@@ -9159,7 +9160,6 @@ Perl_pregfree2(pTHX_ REGEXP *rx)
         CALLREGFREE_PVT(rx); /* free the private data */
         if (r->paren_names)
             SvREFCNT_dec(r->paren_names);
-        Safefree(RX_WRAPPED(rx));
     }        
     if (r->substrs) {
         if (r->anchored_substr)
@@ -9206,7 +9206,13 @@ Perl_reg_temp_copy (pTHX_ REGEXP *rx) {
     register const I32 npar = r->nparens+1;
     (void)ReREFCNT_inc(rx);
     /* FIXME ORANGE (once we start actually using the regular SV fields.) */
+    /* We can take advantage of the existing "copied buffer" mechanism in SVs
+       by pointing directly at the buffer, but flagging that the allocated
+       space in the copy is zero. As we've just done a struct copy, it's now
+       a case of zero-ing that, rather than copying the current length.  */
+    SvPV_set(ret_x, RX_WRAPPED(rx));
     StructCopy(r, ret, regexp);
+    SvLEN_set(ret_x, 0);
     Newx(ret->offs, npar, regexp_paren_pair);
     Copy(r->offs, ret->offs, npar, regexp_paren_pair);
     if (r->substrs) {
@@ -9425,7 +9431,6 @@ Perl_re_dup_guts(pTHX_ const REGEXP *sstr, REGEXP *dstr, CLONE_PARAMS *param)
        }
     }
 
-    RXp_WRAPPED(ret)    = SAVEPVN(RXp_WRAPPED(ret), RXp_WRAPLEN(ret)+1);
     ret->paren_names    = hv_dup_inc(ret->paren_names, param);
 
     if (ret->pprivate)
index f76a8ea..fd2431a 100644 (file)
--- a/regexp.h
+++ b/regexp.h
@@ -100,8 +100,6 @@ typedef struct regexp {
         
         
         /* Information about the match that isn't often used */
-       /* wrapped can't be const char*, as it is returned by sv_2pv_flags */
-       char *wrapped;          /* wrapped version of the pattern */
        I32 wraplen;            /* length of wrapped */
        unsigned pre_prefix:4;  /* offset from wrapped to the start of precomp */
        unsigned seen_evals:28; /* number of eval groups in the pattern - for security checks */ 
@@ -366,9 +364,9 @@ and check for NULL.
 #define RXp_EXTFLAGS(rx)       ((rx)->extflags)
 
 /* For source compatibility. We used to store these explicitly.  */
-#define RX_PRECOMP(prog)       (((struct regexp *)SvANY(prog))->wrapped + ((struct regexp *)SvANY(prog))->pre_prefix)
+#define RX_PRECOMP(prog)       (RX_WRAPPED(prog) + ((struct regexp *)SvANY(prog))->pre_prefix)
 #define RX_PRELEN(prog)                RXp_PRELEN((struct regexp *)SvANY(prog))
-#define RX_WRAPPED(prog)       (((struct regexp *)SvANY(prog))->wrapped)
+#define RX_WRAPPED(prog)       SvPVX(prog)
 #define RX_WRAPLEN(prog)       RXp_WRAPLEN((struct regexp *)SvANY(prog))
 #define RX_CHECK_SUBSTR(prog)  (((struct regexp *)SvANY(prog))->check_substr)
 #define RX_EXTFLAGS(prog)      RXp_EXTFLAGS((struct regexp *)SvANY(prog))