By swapping the order of pushes onto the save stack for
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index ded27c9..63cef31 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -4489,6 +4489,8 @@ Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 nam
     case PERL_MAGIC_qr:
        vtable = &PL_vtbl_regexp;
        break;
+    case PERL_MAGIC_hints:
+       /* As this vtable is all NULL, we can reuse it.  */
     case PERL_MAGIC_sig:
        vtable = &PL_vtbl_sig;
        break;
@@ -4528,6 +4530,9 @@ Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 nam
     case PERL_MAGIC_backref:
        vtable = &PL_vtbl_backref;
        break;
+    case PERL_MAGIC_hintselem:
+       vtable = &PL_vtbl_hintselem;
+       break;
     case PERL_MAGIC_ext:
        /* Reserved for use by extensions not perl internals.           */
        /* Useful for attaching extension internal data to perl vars.   */
@@ -7683,9 +7688,11 @@ Perl_newSVrv(pTHX_ SV *rv, const char *classname)
        sv_clear(rv);
        SvFLAGS(rv) = 0;
        SvREFCNT(rv) = refcnt;
-    }
 
-    if (SvTYPE(rv) < SVt_RV)
+       sv_upgrade(rv, SVt_RV);
+    } else if (SvROK(rv)) {
+       SvREFCNT_dec(SvRV(rv));
+    } else if (SvTYPE(rv) < SVt_RV)
        sv_upgrade(rv, SVt_RV);
     else if (SvTYPE(rv) > SVt_RV) {
        SvPV_free(rv);
@@ -10375,12 +10382,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            gv = (GV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = gv_dup_inc(gv, param);
            break;
-       case SAVEt_GENERIC_PVREF:               /* generic char* */
-           c = (char*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = pv_dup(c);
-           ptr = POPPTR(ss,ix);
-           TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
-           break;
        case SAVEt_SHARED_PVREF:                /* char* in shared space */
            c = (char*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = savesharedpv(c);
@@ -10421,6 +10422,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
        case SAVEt_I32:                         /* I32 reference */
        case SAVEt_I16:                         /* I16 reference */
        case SAVEt_I8:                          /* I8 reference */
+       case SAVEt_COP_ARYBASE:                 /* call CopARYBASE_set */
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            i = POPINT(ss,ix);
@@ -10444,6 +10446,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            break;
+       case SAVEt_GENERIC_PVREF:               /* generic char* */
        case SAVEt_PPTR:                        /* char* reference */
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
@@ -10573,6 +10576,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
        case SAVEt_HINTS:
            i = POPINT(ss,ix);
            TOPINT(nss,ix) = i;
+           ptr = POPPTR(ss,ix);
+           TOPPTR(nss,ix) = Perl_refcounted_he_dup(aTHX_ ptr, param);
+           if (i & HINT_LOCALIZE_HH) {
+               hv = (HV*)POPPTR(ss,ix);
+               TOPPTR(nss,ix) = hv_dup_inc(hv, param);
+           }
            break;
        case SAVEt_COMPPAD:
            av = (AV*)POPPTR(ss,ix);
@@ -10600,8 +10609,80 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            sv = (SV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = sv_dup(sv, param);
            break;
+       case SAVEt_RE_STATE:
+           {
+               const struct re_save_state *const old_state
+                   = (struct re_save_state *)
+                   (ss + ix - SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
+               struct re_save_state *const new_state
+                   = (struct re_save_state *)
+                   (nss + ix - SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
+
+               Copy(old_state, new_state, 1, struct re_save_state);
+               ix -= SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
+
+               new_state->re_state_bostr
+                   = pv_dup(old_state->re_state_bostr);
+               new_state->re_state_reginput
+                   = pv_dup(old_state->re_state_reginput);
+               new_state->re_state_regbol
+                   = pv_dup(old_state->re_state_regbol);
+               new_state->re_state_regeol
+                   = pv_dup(old_state->re_state_regeol);
+               new_state->re_state_regstartp
+                   = any_dup(old_state->re_state_regstartp, proto_perl);
+               new_state->re_state_regendp
+                   = any_dup(old_state->re_state_regendp, proto_perl);
+               new_state->re_state_reglastparen
+                   = any_dup(old_state->re_state_reglastparen, proto_perl);
+               new_state->re_state_reglastcloseparen
+                   = any_dup(old_state->re_state_reglastcloseparen,
+                             proto_perl);
+               new_state->re_state_regtill
+                   = pv_dup(old_state->re_state_regtill);
+               /* XXX This just has to be broken. The old save_re_context
+                  code did SAVEGENERICPV(PL_reg_start_tmp);
+                  PL_reg_start_tmp is char **.
+                  Look above to what the dup code does for
+                  SAVEt_GENERIC_PVREF
+                  It can never have worked.
+                  So this is merely a faithful copy of the exiting bug:  */
+               new_state->re_state_reg_start_tmp
+                   = (char **) pv_dup((char *)
+                                     old_state->re_state_reg_start_tmp);
+               /* I assume that it only ever "worked" because no-one called
+                  (pseudo)fork while the regexp engine had re-entered itself.
+               */
+               new_state->re_state_reg_call_cc
+                   = any_dup(old_state->re_state_reg_call_cc, proto_perl);
+               new_state->re_state_reg_re
+                   = any_dup(old_state->re_state_reg_re, proto_perl);
+               new_state->re_state_reg_ganch
+                   = pv_dup(old_state->re_state_reg_ganch);
+               new_state->re_state_reg_sv
+                   = sv_dup(old_state->re_state_reg_sv, param);
+#ifdef PERL_OLD_COPY_ON_WRITE
+               new_state->re_state_nrs
+                   = sv_dup(old_state->re_state_nrs, param);
+#endif
+               new_state->re_state_reg_magic
+                   = any_dup(old_state->re_state_reg_magic, proto_perl);
+               new_state->re_state_reg_oldcurpm
+                   = any_dup(old_state->re_state_reg_oldcurpm, proto_perl);
+               new_state->re_state_reg_curpm
+                   = any_dup(old_state->re_state_reg_curpm, proto_perl);
+               new_state->re_state_reg_oldsaved
+                   = pv_dup(old_state->re_state_reg_oldsaved);
+               new_state->re_state_reg_poscache
+                   = pv_dup(old_state->re_state_reg_poscache);
+#ifdef DEBUGGING
+               new_state->re_state_reg_starttry
+                   = pv_dup(old_state->re_state_reg_starttry);
+#endif
+               break;
+           }
        default:
-           Perl_croak(aTHX_ "panic: ss_dup inconsistency");
+           Perl_croak(aTHX_ "panic: ss_dup inconsistency (%"IVdf")", (IV) i);
        }
     }
 
@@ -10857,6 +10938,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
        PL_compiling.cop_warnings = sv_dup_inc(PL_compiling.cop_warnings, param);
     if (!specialCopIO(PL_compiling.cop_io))
        PL_compiling.cop_io = sv_dup_inc(PL_compiling.cop_io, param);
+    PL_compiling.cop_hints
+       = Perl_refcounted_he_dup(aTHX_ PL_compiling.cop_hints, param);
     PL_curcop          = (COP*)any_dup(proto_perl->Tcurcop, proto_perl);
 
     /* pseudo environmental stuff */
@@ -11417,46 +11500,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_watchok         = NULL;
 
     PL_regdummy                = proto_perl->Tregdummy;
-    PL_regprecomp      = NULL;
-    PL_regnpar         = 0;
-    PL_regsize         = 0;
     PL_colorset                = 0;            /* reinits PL_colors[] */
     /*PL_colors[6]     = {0,0,0,0,0,0};*/
-    PL_reginput                = NULL;
-    PL_regbol          = NULL;
-    PL_regeol          = NULL;
-    PL_regstartp       = (I32*)NULL;
-    PL_regendp         = (I32*)NULL;
-    PL_reglastparen    = (U32*)NULL;
-    PL_reglastcloseparen       = (U32*)NULL;
-    PL_regtill         = NULL;
-    PL_reg_start_tmp   = (char**)NULL;
-    PL_reg_start_tmpl  = 0;
-    PL_regdata         = (struct reg_data*)NULL;
-    PL_bostr           = NULL;
-    PL_reg_flags       = 0;
-    PL_reg_eval_set    = 0;
-    PL_regnarrate      = 0;
-    PL_regprogram      = (regnode*)NULL;
-    PL_regindent       = 0;
-    PL_reg_call_cc     = (struct re_cc_state*)NULL;
-    PL_reg_re          = (regexp*)NULL;
-    PL_reg_ganch       = NULL;
-    PL_reg_sv          = NULL;
-    PL_reg_match_utf8  = FALSE;
-    PL_reg_magic       = (MAGIC*)NULL;
-    PL_reg_oldpos      = 0;
-    PL_reg_oldcurpm    = (PMOP*)NULL;
-    PL_reg_curpm       = (PMOP*)NULL;
-    PL_reg_oldsaved    = NULL;
-    PL_reg_oldsavedlen = 0;
-#ifdef PERL_OLD_COPY_ON_WRITE
-    PL_nrs             = NULL;
-#endif
-    PL_reg_maxiter     = 0;
-    PL_reg_leftiter    = 0;
-    PL_reg_poscache    = NULL;
-    PL_reg_poscache_size= 0;
 
     /* RE engine - function pointers */
     PL_regcompp                = proto_perl->Tregcompp;
@@ -11464,9 +11509,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_regint_start    = proto_perl->Tregint_start;
     PL_regint_string   = proto_perl->Tregint_string;
     PL_regfree         = proto_perl->Tregfree;
-
+    Zero(&PL_reg_state, 1, struct re_save_state);
     PL_reginterp_cnt   = 0;
-    PL_reg_starttry    = 0;
+    PL_regmatch_slab   = NULL;
 
     /* Pluggable optimizer */
     PL_peepp           = proto_perl->Tpeepp;