[perl #37648] segfault with PERLIO_DEBUG
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index b150ac9..0f13d5a 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -100,7 +100,8 @@ PP(pp_and)
     if (!SvTRUE(TOPs))
        RETURN;
     else {
-       --SP;
+        if (PL_op->op_type == OP_AND)
+           --SP;
        RETURNOP(cLOGOP->op_other);
     }
 }
@@ -169,8 +170,7 @@ PP(pp_concat)
     }
     else { /* TARG == left */
         STRLEN llen;
-       if (SvGMAGICAL(left))
-           mg_get(left);               /* or mg_get(left) may happen here */
+       SvGETMAGIC(left);               /* or mg_get(left) may happen here */
        if (!SvOK(TARG))
            sv_setpvn(left, "", 0);
        (void)SvPV_nomg_const(left, llen);    /* Needed to set UTF8 flag */
@@ -320,44 +320,63 @@ PP(pp_or)
     if (SvTRUE(TOPs))
        RETURN;
     else {
-       --SP;
+       if (PL_op->op_type == OP_OR)
+            --SP;
        RETURNOP(cLOGOP->op_other);
     }
 }
 
-PP(pp_dor)
+PP(pp_defined)
 {
-    /* Most of this is lifted straight from pp_defined */
     dSP;
-    register SV* const sv = TOPs;
+    register SV* sv = NULL;
+    bool defined = FALSE;
+    const int op_type = PL_op->op_type;
+
+    if(op_type == OP_DOR || op_type == OP_DORASSIGN) {
+        sv = TOPs;
+        if (!sv || !SvANY(sv)) {
+           if (op_type == OP_DOR)
+               --SP;
+            RETURNOP(cLOGOP->op_other);
+        }
+    } else if (op_type == OP_DEFINED) {
+        sv = POPs;
+        if (!sv || !SvANY(sv))
+            RETPUSHNO;
+    } else
+        DIE(aTHX_ "panic:  Invalid op (%s) in pp_defined()", OP_NAME(PL_op));
 
-    if (!sv || !SvANY(sv)) {
-       --SP;
-       RETURNOP(cLOGOP->op_other);
-    }
-    
     switch (SvTYPE(sv)) {
     case SVt_PVAV:
        if (AvMAX(sv) >= 0 || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
-           RETURN;
+           defined = TRUE;
        break;
     case SVt_PVHV:
        if (HvARRAY(sv) || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
-           RETURN;
+           defined = TRUE;
        break;
     case SVt_PVCV:
        if (CvROOT(sv) || CvXSUB(sv))
-           RETURN;
+           defined = TRUE;
        break;
     default:
-       if (SvGMAGICAL(sv))
-           mg_get(sv);
+       SvGETMAGIC(sv);
        if (SvOK(sv))
-           RETURN;
+           defined = TRUE;
     }
     
-    --SP;
-    RETURNOP(cLOGOP->op_other);
+    if(op_type == OP_DOR || op_type == OP_DORASSIGN) {
+        if(defined) 
+            RETURN; 
+        if(op_type == OP_DOR)
+            --SP;
+        RETURNOP(cLOGOP->op_other);
+    }
+    /* assuming OP_DEFINED */
+    if(defined) 
+        RETPUSHYES;
+    RETPUSHNO;
 }
 
 PP(pp_add)
@@ -555,7 +574,7 @@ PP(pp_pushre)
      * We ass_u_me that LvTARGOFF() comes first, and that two STRLENs
      * will be enough to hold an OP*.
      */
-    SV* sv = sv_newmortal();
+    SV* const sv = sv_newmortal();
     sv_upgrade(sv, SVt_PVLV);
     LvTYPE(sv) = '/';
     Copy(&PL_op, &LvTARGOFF(sv), 1, OP*);
@@ -660,12 +679,12 @@ PP(pp_print)
        }
     }
     SP = ORIGMARK;
-    PUSHs(&PL_sv_yes);
+    XPUSHs(&PL_sv_yes);
     RETURN;
 
   just_say_no:
     SP = ORIGMARK;
-    PUSHs(&PL_sv_undef);
+    XPUSHs(&PL_sv_undef);
     RETURN;
 }
 
@@ -1161,9 +1180,9 @@ PP(pp_aassign)
 PP(pp_qr)
 {
     dSP;
-    register PMOP *pm = cPMOP;
-    SV *rv = sv_newmortal();
-    SV *sv = newSVrv(rv, "Regexp");
+    register PMOP * const pm = cPMOP;
+    SV * const rv = sv_newmortal();
+    SV * const sv = newSVrv(rv, "Regexp");
     if (pm->op_pmdynflags & PMdf_TAINTED)
         SvTAINTED_on(rv);
     sv_magic(sv,(SV*)ReREFCNT_inc(PM_GETRE(pm)), PERL_MAGIC_qr,0,0);
@@ -1175,8 +1194,8 @@ PP(pp_match)
     dSP; dTARG;
     register PMOP *pm = cPMOP;
     PMOP *dynpm = pm;
-    const register char *t;
-    const register char *s;
+    register const char *t;
+    register const char *s;
     const char *strend;
     I32 global;
     I32 r_flags = REXEC_CHECKED;
@@ -1611,8 +1630,8 @@ Perl_do_readline(pTHX)
             const STRLEN len = SvCUR(sv) - offset;
             const U8 *f;
             
-            if (!Perl_is_utf8_string_loc(aTHX_ s, len, &f)
-               && ckWARN(WARN_UTF8))
+            if (ckWARN(WARN_UTF8) &&
+                   !is_utf8_string_loc(s, len, &f))
                  /* Emulate :encoding(utf8) warning in the same case. */
                  Perl_warner(aTHX_ packWARN(WARN_UTF8),
                              "utf8 \"\\x%02X\" does not map to Unicode",
@@ -2284,7 +2303,7 @@ PP(pp_grepwhile)
     /* All done yet? */
     if (PL_stack_base + *PL_markstack_ptr > SP) {
        I32 items;
-       I32 gimme = GIMME_V;
+       const I32 gimme = GIMME_V;
 
        LEAVE;                                  /* exit outer scope */
        (void)POPMARK;                          /* pop src */
@@ -2293,7 +2312,7 @@ PP(pp_grepwhile)
        SP = PL_stack_base + POPMARK;           /* pop original mark */
        if (gimme == G_SCALAR) {
            if (PL_op->op_private & OPpGREP_LEX) {
-               SV* sv = sv_newmortal();
+               SV* const sv = sv_newmortal();
                sv_setiv(sv, items);
                PUSHs(sv);
            }
@@ -2333,6 +2352,9 @@ PP(pp_leavesub)
     register PERL_CONTEXT *cx;
     SV *sv;
 
+    if (CxMULTICALL(&cxstack[cxstack_ix]))
+       return 0;
+
     POPBLOCK(cx,newpm);
     cxstack_ix++; /* temporarily protect top context */
 
@@ -2393,6 +2415,9 @@ PP(pp_leavesublv)
     register PERL_CONTEXT *cx;
     SV *sv;
 
+    if (CxMULTICALL(&cxstack[cxstack_ix]))
+       return 0;
+
     POPBLOCK(cx,newpm);
     cxstack_ix++; /* temporarily protect top context */
 
@@ -2441,7 +2466,10 @@ PP(pp_leavesublv)
            MARK = newsp + 1;
            EXTEND_MORTAL(1);
            if (MARK == SP) {
-               if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) {
+               /* Temporaries are bad unless they happen to be elements
+                * of a tied hash or array */
+               if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY) &&
+                   !(SvRMAGICAL(TOPs) && mg_find(TOPs, PERL_MAGIC_tiedelem))) {
                    LEAVE;
                    cxstack_ix--;
                    POPSUB(cx,sv);
@@ -2556,7 +2584,7 @@ S_get_db_sub(pTHX_ SV **svp, CV *cv)
                    && (gv = (GV*)*svp) ))) {
            /* Use GV from the stack as a fallback. */
            /* GV is potentially non-unique, or contain different CV. */
-           SV *tmp = newRV((SV*)cv);
+           SV * const tmp = newRV((SV*)cv);
            sv_setsv(dbsv, tmp);
            SvREFCNT_dec(tmp);
        }
@@ -2627,7 +2655,7 @@ PP(pp_entersub)
        }
   got_rv:
        {
-           SV **sp = &sv;              /* Used in tryAMAGICunDEREF macro. */
+           SV * const * sp = &sv;              /* Used in tryAMAGICunDEREF macro. */
            tryAMAGICunDEREF(to_cv);
        }       
        cv = (CV*)SvRV(sv);
@@ -2843,7 +2871,7 @@ Perl_sub_crush_depth(pTHX_ CV *cv)
     if (CvANON(cv))
        Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on anonymous subroutine");
     else {
-       SV* tmpstr = sv_newmortal();
+       SV* const tmpstr = sv_newmortal();
        gv_efullname3(tmpstr, CvGV(cv), Nullch);
        Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on subroutine \"%"SVf"\"",
                tmpstr);
@@ -2911,8 +2939,7 @@ PP(pp_aelem)
 void
 Perl_vivify_ref(pTHX_ SV *sv, U32 to_what)
 {
-    if (SvGMAGICAL(sv))
-       mg_get(sv);
+    SvGETMAGIC(sv);
     if (!SvOK(sv)) {
        if (SvREADONLY(sv))
            Perl_croak(aTHX_ PL_no_modify);
@@ -2982,8 +3009,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
     if (!sv)
        Perl_croak(aTHX_ "Can't call method \"%s\" on an undefined value", name);
 
-    if (SvGMAGICAL(sv))
-       mg_get(sv);
+    SvGETMAGIC(sv);
     if (SvROK(sv))
        ob = (SV*)SvRV(sv);
     else {