This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #119043] Exempt shared hash key consts from ro
[perl5.git] / pp_ctl.c
index ec63801..ff3d661 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -214,7 +214,6 @@ PP(pp_substcont)
     }
 
     rxres_restore(&cx->sb_rxres, rx);
-    RX_MATCH_UTF8_set(rx, DO_UTF8(cx->sb_targ));
 
     if (cx->sb_iters++) {
        const I32 saviters = cx->sb_iters;
@@ -227,14 +226,10 @@ PP(pp_substcont)
        if (SvTAINTED(TOPs))
            cx->sb_rxtainted |= SUBST_TAINT_REPL;
        sv_catsv_nomg(dstr, POPs);
-       /* XXX: adjust for positive offsets of \G for instance s/(.)\G//g with positive pos() */
-       s -= RX_GOFS(rx);
-
-       /* Are we done */
        if (CxONCE(cx) || s < orig ||
-               !CALLREGEXEC(rx, s, cx->sb_strend, orig,
-                            (s == m) + RX_GOFS(rx), cx->sb_targ, NULL,
-                                (REXEC_IGNOREPOS|REXEC_NOT_FIRST)))
+                !CALLREGEXEC(rx, s, cx->sb_strend, orig,
+                            (s == m), cx->sb_targ, NULL,
+                    (REXEC_IGNOREPOS|REXEC_NOT_FIRST|REXEC_FAIL_ON_UNDERFLOW)))
        {
            SV *targ = cx->sb_targ;
 
@@ -326,14 +321,8 @@ PP(pp_substcont)
        SV * const sv
            = (pm->op_pmflags & PMf_NONDESTRUCT) ? cx->sb_dstr : cx->sb_targ;
        MAGIC *mg;
-       SvUPGRADE(sv, SVt_PVMG);
-       if (!(mg = mg_find(sv, PERL_MAGIC_regex_global))) {
-#ifdef PERL_OLD_COPY_ON_WRITE
-           if (SvIsCOW(sv))
-               sv_force_normal_flags(sv, 0);
-#endif
-           mg = sv_magicext(sv, NULL, PERL_MAGIC_regex_global, &PL_vtbl_mglob,
-                            NULL, 0);
+       if (!(mg = mg_find_mglob(sv))) {
+           mg = sv_magicext_mglob(sv);
        }
        mg->mg_len = m - orig;
     }
@@ -1000,6 +989,10 @@ PP(pp_grepstart)
     SAVEVPTR(PL_curpm);
 
     src = PL_stack_base[*PL_markstack_ptr];
+    if (SvPADTMP(src) && !IS_PADGV(src)) {
+       src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src);
+       PL_tmps_floor++;
+    }
     SvTEMP_off(src);
     if (PL_op->op_private & OPpGREP_LEX)
        PAD_SVl(PL_op->op_targ) = src;
@@ -1148,6 +1141,7 @@ PP(pp_mapwhile)
 
        /* set $_ to the new source item */
        src = PL_stack_base[PL_markstack_ptr[-1]];
+       if (SvPADTMP(src) && !IS_PADGV(src)) src = sv_mortalcopy(src);
        SvTEMP_off(src);
        if (PL_op->op_private & OPpGREP_LEX)
            PAD_SVl(PL_op->op_targ) = src;
@@ -2724,7 +2718,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac
     PERL_ARGS_ASSERT_DOFINDLABEL;
 
     if (ops >= oplimit)
-       Perl_croak(aTHX_ too_deep);
+       Perl_croak(aTHX_ "%s", too_deep);
     if (o->op_type == OP_LEAVE ||
        o->op_type == OP_SCOPE ||
        o->op_type == OP_LEAVELOOP ||
@@ -2733,7 +2727,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac
     {
        *ops++ = cUNOPo->op_first;
        if (ops >= oplimit)
-           Perl_croak(aTHX_ too_deep);
+           Perl_croak(aTHX_ "%s", too_deep);
     }
     *ops = 0;
     if (o->op_flags & OPf_KIDS) {
@@ -2993,7 +2987,7 @@ PP(pp_goto)
         label_flags = (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0;
         label_len   = strlen(label);
     }
-    if (!(do_dump || label_len)) DIE(aTHX_ must_have_label);
+    if (!(do_dump || label_len)) DIE(aTHX_ "%s", must_have_label);
 
     PERL_ASYNC_CHECK();
 
@@ -3071,9 +3065,8 @@ PP(pp_goto)
            PL_lastgotoprobe = gotoprobe;
        }
        if (!retop)
-           DIE(aTHX_ "Can't find label %"SVf,
-                            SVfARG(newSVpvn_flags(label, label_len,
-                                        SVs_TEMP | label_flags)));
+           DIE(aTHX_ "Can't find label %"UTF8f, 
+                      UTF8fARG(label_flags, label_len, label));
 
        /* if we're leaving an eval, check before we pop any frames
            that we're not going to punt, otherwise the error
@@ -3403,7 +3396,9 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
 
     if (CopSTASH_ne(PL_curcop, PL_curstash)) {
        SAVEGENERICSV(PL_curstash);
-       PL_curstash = (HV *)SvREFCNT_inc_simple(CopSTASH(PL_curcop));
+       PL_curstash = (HV *)CopSTASH(PL_curcop);
+       if (SvTYPE(PL_curstash) != SVt_PVHV) PL_curstash = NULL;
+       else SvREFCNT_inc_simple_void(PL_curstash);
     }
     /* XXX:ajgo do we really need to alloc an AV for begin/checkunit */
     SAVESPTR(PL_beginav);
@@ -3625,6 +3620,32 @@ S_doopen_pm(pTHX_ SV *name)
 #  define doopen_pm(name) check_type_and_open(name)
 #endif /* !PERL_DISABLE_PMC */
 
+/* require doesn't search for absolute names, or when the name is
+   explicity relative the current directory */
+PERL_STATIC_INLINE bool
+S_path_is_searchable(const char *name)
+{
+    PERL_ARGS_ASSERT_PATH_IS_SEARCHABLE;
+
+    if (PERL_FILE_IS_ABSOLUTE(name)
+#ifdef WIN32
+       || (*name == '.' && ((name[1] == '/' ||
+                            (name[1] == '.' && name[2] == '/'))
+                        || (name[1] == '\\' ||
+                            ( name[1] == '.' && name[2] == '\\')))
+           )
+#else
+       || (*name == '.' && (name[1] == '/' ||
+                            (name[1] == '.' && name[2] == '/')))
+#endif
+        )
+    {
+       return FALSE;
+    }
+    else
+       return TRUE;
+}
+
 PP(pp_require)
 {
     dVAR; dSP;
@@ -3652,6 +3673,7 @@ PP(pp_require)
     SV *encoding;
     OP *op;
     int saved_errno;
+    bool path_searchable;
 
     sv = POPs;
     if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
@@ -3716,6 +3738,7 @@ PP(pp_require)
        DIE(aTHX_ "Null filename used");
     TAINT_PROPER("require");
 
+    path_searchable = path_is_searchable(name);
 
 #ifdef VMS
     /* The key in the %ENV hash is in the syntax of file passed as the argument
@@ -3755,12 +3778,12 @@ PP(pp_require)
 
     /* prepare to compile file */
 
-    if (path_is_absolute(name)) {
+    if (!path_searchable) {
        /* At this point, name is SvPVX(sv)  */
        tryname = name;
        tryrsfp = doopen_pm(sv);
     }
-    if (!tryrsfp && !(errno == EACCES && path_is_absolute(name))) {
+    if (!tryrsfp && !(errno == EACCES && !path_searchable)) {
        AV * const ar = GvAVn(PL_incgv);
        I32 i;
 #ifdef VMS
@@ -3813,7 +3836,6 @@ PP(pp_require)
                        if (SvROK(arg) && (SvTYPE(SvRV(arg)) <= SVt_PVLV)
                            && !isGV_with_GP(SvRV(arg))) {
                            filter_cache = SvRV(arg);
-                           SvREFCNT_inc_simple_void_NN(filter_cache);
 
                            if (i < count) {
                                arg = SP[i++];
@@ -3876,10 +3898,7 @@ PP(pp_require)
                    }
 
                    filter_has_file = 0;
-                   if (filter_cache) {
-                       SvREFCNT_dec(filter_cache);
-                       filter_cache = NULL;
-                   }
+                   filter_cache = NULL;
                    if (filter_state) {
                        SvREFCNT_dec(filter_state);
                        filter_state = NULL;
@@ -3890,8 +3909,7 @@ PP(pp_require)
                    }
                }
                else {
-                 if (!path_is_absolute(name)
-                 ) {
+                 if (path_searchable) {
                    const char *dir;
                    STRLEN dirlen;
 
@@ -4046,7 +4064,10 @@ PP(pp_require)
           than hanging another SV from it. In turn, filter_add() optionally
           takes the SV to use as the filter (or creates a new SV if passed
           NULL), so simply pass in whatever value filter_cache has.  */
-       SV * const datasv = filter_add(S_run_user_filter, filter_cache);
+       SV * const fc = filter_cache ? newSV(0) : NULL;
+       SV *datasv;
+       if (fc) sv_copypv(fc, filter_cache);
+       datasv = filter_add(S_run_user_filter, fc);
        IoLINES(datasv) = filter_has_file;
        IoTOP_GV(datasv) = MUTABLE_GV(filter_state);
        IoBOTTOM_GV(datasv) = MUTABLE_GV(filter_sub);
@@ -5510,32 +5531,6 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
     return status;
 }
 
-/* perhaps someone can come up with a better name for
-   this?  it is not really "absolute", per se ... */
-static bool
-S_path_is_absolute(const char *name)
-{
-    PERL_ARGS_ASSERT_PATH_IS_ABSOLUTE;
-
-    if (PERL_FILE_IS_ABSOLUTE(name)
-#ifdef WIN32
-       || (*name == '.' && ((name[1] == '/' ||
-                            (name[1] == '.' && name[2] == '/'))
-                        || (name[1] == '\\' ||
-                            ( name[1] == '.' && name[2] == '\\')))
-           )
-#else
-       || (*name == '.' && (name[1] == '/' ||
-                            (name[1] == '.' && name[2] == '/')))
-#endif
-        )
-    {
-       return TRUE;
-    }
-    else
-       return FALSE;
-}
-
 /*
  * Local variables:
  * c-indentation-style: bsd