applied suggested fix for xhv_array sizing, with portability tweaks
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index b81ec56..8e3bf70 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -250,9 +250,13 @@ PP(pp_aelemfast)
 {
     djSP;
     AV *av = GvAV((GV*)cSVOP->op_sv);
-    SV** svp = av_fetch(av, op->op_private, op->op_flags & OPf_MOD);
+    U32 lval = op->op_flags & OPf_MOD;
+    SV** svp = av_fetch(av, op->op_private, lval);
+    SV *sv = (svp ? *svp : &sv_undef);
     EXTEND(SP, 1);
-    PUSHs(svp ? *svp : &sv_undef);
+    if (!lval && SvGMAGICAL(sv))       /* see note in pp_helem() */
+       sv = sv_mortalcopy(sv);
+    PUSHs(sv);
     RETURN;
 }
 
@@ -673,7 +677,7 @@ PP(pp_aassign)
        default:
            if (SvTHINKFIRST(sv)) {
                if (SvREADONLY(sv) && curcop != &compiling) {
-                   if (sv != &sv_undef && sv != &sv_yes && sv != &sv_no)
+                   if (!SvIMMORTAL(sv))
                        DIE(no_modify);
                    if (relem <= lastrelem)
                        relem++;
@@ -872,7 +876,7 @@ play_it_again:
            }
            else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min,
                                     (unsigned char*)strend, 
-                                    rx->check_substr)))
+                                    rx->check_substr, 0)))
                goto nope;
            else if ((rx->reganch & ROPT_CHECK_ALL) && !sawampersand)
                goto yup;
@@ -913,7 +917,9 @@ play_it_again:
     /*NOTREACHED*/
 
   gotcha:
-    RX_MATCH_TAINTED_SET(rx, rxtainted);
+    if (rxtainted)
+       RX_MATCH_TAINTED_on(rx);
+    TAINT_IF(RX_MATCH_TAINTED(rx));
     if (gimme == G_ARRAY) {
        I32 iters, i, len;
 
@@ -966,7 +972,9 @@ play_it_again:
     }
 
 yup:                                   /* Confirmed by check_substr */
-    RX_MATCH_TAINTED_SET(rx, rxtainted);
+    if (rxtainted)
+       RX_MATCH_TAINTED_on(rx);
+    TAINT_IF(RX_MATCH_TAINTED(rx));
     ++BmUSEFUL(rx->check_substr);
     curpm = pm;
     if (pm->op_pmflags & PMf_ONCE)
@@ -1311,6 +1319,7 @@ PP(pp_helem)
     HV *hv = (HV*)POPs;
     U32 lval = op->op_flags & OPf_MOD;
     U32 defer = op->op_private & OPpLVAL_DEFER;
+    SV *sv;
 
     if (SvTYPE(hv) == SVt_PVHV) {
        he = hv_fetch_ent(hv, keysv, lval && !defer, 0);
@@ -1347,7 +1356,16 @@ PP(pp_helem)
        else if (op->op_private & OPpDEREF)
            vivify_ref(*svp, op->op_private & OPpDEREF);
     }
-    PUSHs(svp ? *svp : &sv_undef);
+    sv = (svp ? *svp : &sv_undef);
+    /* This makes C<local $tied{foo} = $tied{foo}> possible.
+     * Pushing the magical RHS on to the stack is useless, since
+     * that magic is soon destined to be misled by the local(),
+     * and thus the later pp_sassign() will fail to mg_get() the
+     * old value.  This should also cure problems with delayed
+     * mg_get()s.  GSAR 98-07-03 */
+    if (!lval && SvGMAGICAL(sv))
+       sv = sv_mortalcopy(sv);
+    PUSHs(sv);
     RETURN;
 }
 
@@ -1562,7 +1580,7 @@ PP(pp_subst)
            }
            else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min, 
                                     (unsigned char*)strend,
-                                    rx->check_substr)))
+                                    rx->check_substr, 0)))
                goto nope;
            if (s && rx->check_offset_max < s - m) {
                ++BmUSEFUL(rx->check_substr);
@@ -2320,6 +2338,7 @@ PP(pp_aelem)
     AV* av = (AV*)POPs;
     U32 lval = op->op_flags & OPf_MOD;
     U32 defer = (op->op_private & OPpLVAL_DEFER) && (elem > AvFILL(av));
+    SV *sv;
 
     if (elem > 0)
        elem -= curcop->cop_arybase;
@@ -2346,7 +2365,10 @@ PP(pp_aelem)
        else if (op->op_private & OPpDEREF)
            vivify_ref(*svp, op->op_private & OPpDEREF);
     }
-    PUSHs(svp ? *svp : &sv_undef);
+    sv = (svp ? *svp : &sv_undef);
+    if (!lval && SvGMAGICAL(sv))       /* see note in pp_helem() */
+       sv = sv_mortalcopy(sv);
+    PUSHs(sv);
     RETURN;
 }