Add a new flag SVprv_PCS_IMPORTED (which is a pseudonym for SVf_SCREAM)
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index 14bfd2c..4038629 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -150,7 +150,7 @@ PP(pp_sassign)
                SV *const value = SvRV(cv);
 
                SvUPGRADE((SV *)gv, SVt_RV);
-               SvROK_on(gv);
+               SvPCS_IMPORTED_on(gv);
                SvRV_set(gv, value);
                SvREFCNT_inc_simple_void(value);
                SETs(right);
@@ -1304,6 +1304,7 @@ PP(pp_match)
     const I32 oldsave = PL_savestack_ix;
     I32 update_minmatch = 1;
     I32 had_zerolen = 0;
+    U32 gpos = 0;
 
     if (PL_op->op_flags & OPf_STACKED)
        TARG = POPs;
@@ -1350,18 +1351,23 @@ PP(pp_match)
        if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
            MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global);
            if (mg && mg->mg_len >= 0) {
-               if (!(rx->reganch & ROPT_GPOS_SEEN))
+               if (!(rx->extflags & RXf_GPOS_SEEN))
                    rx->endp[0] = rx->startp[0] = mg->mg_len;
-               else if (rx->reganch & ROPT_ANCH_GPOS) {
+               else if (rx->extflags & RXf_ANCH_GPOS) {
                    r_flags |= REXEC_IGNOREPOS;
                    rx->endp[0] = rx->startp[0] = mg->mg_len;
-               }
-               minmatch = (mg->mg_flags & MGf_MINMATCH);
+               } else if (rx->extflags & RXf_GPOS_FLOAT) 
+                   gpos = mg->mg_len;
+               else 
+                   rx->endp[0] = rx->startp[0] = mg->mg_len;
+               minmatch = (mg->mg_flags & MGf_MINMATCH) ? rx->gofs + 1 : 0;
                update_minmatch = 0;
            }
        }
     }
-    if ((!global && rx->nparens)
+    /* remove comment to get faster /g but possibly unsafe $1 vars after a
+       match. Test for the unsafe vars will fail as well*/
+    if (( /* !global &&  */ rx->nparens) 
            || SvTEMP(TARG) || PL_sawampersand || (pm->op_pmflags & PMf_EVAL))
        r_flags |= REXEC_COPY_STR;
     if (SvSCREAM(TARG))
@@ -1369,29 +1375,29 @@ PP(pp_match)
 
 play_it_again:
     if (global && rx->startp[0] != -1) {
-       t = s = rx->endp[0] + truebase;
-       if ((s + rx->minlen) > strend)
+       t = s = rx->endp[0] + truebase - rx->gofs;
+       if ((s + rx->minlen) > strend || s < truebase)
            goto nope;
        if (update_minmatch++)
            minmatch = had_zerolen;
     }
-    if (rx->reganch & RE_USE_INTUIT &&
-       DO_UTF8(TARG) == ((rx->reganch & ROPT_UTF8) != 0)) {
+    if (rx->extflags & RXf_USE_INTUIT &&
+       DO_UTF8(TARG) == ((rx->extflags & RXf_UTF8) != 0)) {
        /* FIXME - can PL_bostr be made const char *?  */
        PL_bostr = (char *)truebase;
        s = CALLREG_INTUIT_START(rx, TARG, (char *)s, (char *)strend, r_flags, NULL);
 
        if (!s)
            goto nope;
-       if ( (rx->reganch & ROPT_CHECK_ALL)
+       if ( (rx->extflags & RXf_CHECK_ALL)
             && !PL_sawampersand
-            && ((rx->reganch & ROPT_NOSCAN)
-                || !((rx->reganch & RE_INTUIT_TAIL)
+            && ((rx->extflags & RXf_NOSCAN)
+                || !((rx->extflags & RXf_INTUIT_TAIL)
                      && (r_flags & REXEC_SCREAM)))
             && !SvROK(TARG))   /* Cannot trust since INTUIT cannot guess ^ */
            goto yup;
     }
-    if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NULL, r_flags))
+    if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, INT2PTR(void*, gpos), r_flags))
     {
        PL_curpm = pm;
        if (dynpm->op_pmflags & PMf_ONCE)
@@ -1441,14 +1447,14 @@ play_it_again:
                }
                if (rx->startp[0] != -1) {
                    mg->mg_len = rx->endp[0];
-                   if (rx->startp[0] == rx->endp[0])
+                   if (rx->startp[0] + rx->gofs == (UV)rx->endp[0])
                        mg->mg_flags |= MGf_MINMATCH;
                    else
                        mg->mg_flags &= ~MGf_MINMATCH;
                }
            }
            had_zerolen = (rx->startp[0] != -1
-                          && rx->startp[0] == rx->endp[0]);
+                          && rx->startp[0] + rx->gofs == (UV)rx->endp[0]);
            PUTBACK;                    /* EVAL blocks may use stack */
            r_flags |= REXEC_IGNOREPOS | REXEC_NOT_FIRST;
            goto play_it_again;
@@ -1475,7 +1481,7 @@ play_it_again:
            }
            if (rx->startp[0] != -1) {
                mg->mg_len = rx->endp[0];
-               if (rx->startp[0] == rx->endp[0])
+               if (rx->startp[0] + rx->gofs == (UV)rx->endp[0])
                    mg->mg_flags |= MGf_MINMATCH;
                else
                    mg->mg_flags &= ~MGf_MINMATCH;
@@ -1644,6 +1650,8 @@ Perl_do_readline(pTHX)
   have_fp:
     if (gimme == G_SCALAR) {
        sv = TARG;
+       if (type == OP_RCATLINE && SvGMAGICAL(sv))
+           mg_get(sv);
        if (SvROK(sv)) {
            if (type == OP_RCATLINE)
                SvPV_force_nolen(sv);
@@ -2112,7 +2120,8 @@ PP(pp_subst)
        !is_cow &&
 #endif
        (SvREADONLY(TARG)
-       || ( (SvTYPE(TARG) == SVt_PVGV || SvTYPE(TARG) > SVt_PVLV)
+        || ( ((SvTYPE(TARG) == SVt_PVGV && isGV_with_GP(TARG))
+              || SvTYPE(TARG) > SVt_PVLV)
             && !(SvTYPE(TARG) == SVt_PVGV && SvFAKE(TARG)))))
        DIE(aTHX_ PL_no_modify);
     PUTBACK;
@@ -2149,17 +2158,17 @@ PP(pp_subst)
        r_flags |= REXEC_SCREAM;
 
     orig = m = s;
-    if (rx->reganch & RE_USE_INTUIT) {
+    if (rx->extflags & RXf_USE_INTUIT) {
        PL_bostr = orig;
        s = CALLREG_INTUIT_START(rx, TARG, s, strend, r_flags, NULL);
 
        if (!s)
            goto nope;
        /* How to do it in subst? */
-/*     if ( (rx->reganch & ROPT_CHECK_ALL)
+/*     if ( (rx->extflags & RXf_CHECK_ALL)
             && !PL_sawampersand
-            && ((rx->reganch & ROPT_NOSCAN)
-                || !((rx->reganch & RE_INTUIT_TAIL)
+            && ((rx->extflags & RXf_NOSCAN)
+                || !((rx->extflags & RXf_INTUIT_TAIL)
                      && (r_flags & REXEC_SCREAM))))
            goto yup;
 */
@@ -2197,7 +2206,7 @@ PP(pp_subst)
        && !is_cow
 #endif
        && (I32)clen <= rx->minlenret && (once || !(r_flags & REXEC_COPY_STR))
-       && !(rx->reganch & ROPT_LOOKBEHIND_SEEN)
+       && !(rx->extflags & RXf_LOOKBEHIND_SEEN)
        && (!doutf8 || SvUTF8(TARG))) {
        if (!CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL,
                         r_flags | REXEC_CHECKED))
@@ -2674,45 +2683,6 @@ PP(pp_leavesublv)
     return cx->blk_sub.retop;
 }
 
-
-STATIC CV *
-S_get_db_sub(pTHX_ SV **svp, CV *cv)
-{
-    dVAR;
-    SV * const dbsv = GvSVn(PL_DBsub);
-
-    save_item(dbsv);
-    if (!PERLDB_SUB_NN) {
-       GV * const gv = CvGV(cv);
-
-       if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
-            || strEQ(GvNAME(gv), "END")
-            || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
-                !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) ))) {
-           /* Use GV from the stack as a fallback. */
-           /* GV is potentially non-unique, or contain different CV. */
-           SV * const tmp = newRV((SV*)cv);
-           sv_setsv(dbsv, tmp);
-           SvREFCNT_dec(tmp);
-       }
-       else {
-           gv_efullname3(dbsv, gv, NULL);
-       }
-    }
-    else {
-       const int type = SvTYPE(dbsv);
-       if (type < SVt_PVIV && type != SVt_IV)
-           sv_upgrade(dbsv, SVt_PVIV);
-       (void)SvIOK_on(dbsv);
-       SvIV_set(dbsv, PTR2IV(cv));     /* Do it the quickest way  */
-    }
-
-    if (CvISXSUB(cv))
-       PL_curcopdb = PL_curcop;
-    cv = GvCV(PL_DBsub);
-    return cv;
-}
-
 PP(pp_entersub)
 {
     dVAR; dSP; dPOPss;
@@ -2820,7 +2790,11 @@ try_autoload:
         if (CvASSERTION(cv) && PL_DBassertion)
            sv_setiv(PL_DBassertion, 1);
        
-       cv = get_db_sub(&sv, cv);
+        Perl_get_db_sub(aTHX_ &sv, cv);
+        if (CvISXSUB(cv))
+            PL_curcopdb = PL_curcop;
+        cv = GvCV(PL_DBsub);
+
        if (!cv || (!CvXSUB(cv) && !CvSTART(cv)))
            DIE(aTHX_ "No DB::sub routine defined");
     }