Storable 2.06 (was Re: Bug in ext/Storable/t/integer.t)
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index 7a440ae..0359935 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -836,7 +836,7 @@ PP(pp_mapwhile)
        }
        /* copy the new items down to the destination list */
        dst = PL_stack_base + (PL_markstack_ptr[-2] += items) - 1;
-       while (items--)
+       while (items-- > 0)
            *dst-- = SvTEMP(TOPs) ? POPs : sv_mortalcopy(POPs);
     }
     LEAVE;                                     /* exit inner scope */
@@ -1378,7 +1378,40 @@ PP(pp_orassign)
     else
        RETURNOP(cLOGOP->op_other);
 }
-       
+
+PP(pp_dorassign)
+{
+    dSP;
+    register SV* sv;
+
+    sv = TOPs;
+    if (!sv || !SvANY(sv)) {
+       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;
+       break;
+    case SVt_PVHV:
+       if (HvARRAY(sv) || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
+           RETURN;
+       break;
+    case SVt_PVCV:
+       if (CvROOT(sv) || CvXSUB(sv))
+           RETURN;
+       break;
+    default:
+       if (SvGMAGICAL(sv))
+           mg_get(sv);
+       if (SvOK(sv))
+           RETURN;
+    }
+
+    RETURNOP(cLOGOP->op_other);
+}
+
 PP(pp_caller)
 {
     dSP;
@@ -1450,11 +1483,18 @@ PP(pp_caller)
     if (!MAXARG)
        RETURN;
     if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
+       GV *cvgv = CvGV(ccstack[cxix].blk_sub.cv);
        /* So is ccstack[dbcxix]. */
-       sv = NEWSV(49, 0);
-       gv_efullname3(sv, CvGV(ccstack[cxix].blk_sub.cv), Nullch);
-       PUSHs(sv_2mortal(sv));
-       PUSHs(sv_2mortal(newSViv((I32)cx->blk_sub.hasargs)));
+       if (isGV(cvgv)) {
+           sv = NEWSV(49, 0);
+           gv_efullname3(sv, cvgv, Nullch);
+           PUSHs(sv_2mortal(sv));
+           PUSHs(sv_2mortal(newSViv((I32)cx->blk_sub.hasargs)));
+       }
+       else {
+           PUSHs(sv_2mortal(newSVpvn("(unknown)",9)));
+           PUSHs(sv_2mortal(newSViv((I32)cx->blk_sub.hasargs)));
+       }
     }
     else {
        PUSHs(sv_2mortal(newSVpvn("(eval)",6)));
@@ -1547,6 +1587,8 @@ PP(pp_lineseq)
     return NORMAL;
 }
 
+/* like pp_nextstate, but used instead when the debugger is active */
+
 PP(pp_dbstate)
 {
     PL_curcop = (COP*)PL_op;
@@ -1586,8 +1628,7 @@ PP(pp_dbstate)
        PUSHSUB(cx);
        CvDEPTH(cv)++;
        (void)SvREFCNT_inc(cv);
-       SAVEVPTR(PL_curpad);
-       PL_curpad = AvARRAY((AV*)*av_fetch(CvPADLIST(cv),1,FALSE));
+       PAD_SET_CUR(CvPADLIST(cv),1);
        RETURNOP(CvSTART(cv));
     }
     else
@@ -1623,7 +1664,7 @@ PP(pp_enteriter)
 #endif /* USE_5005THREADS */
     if (PL_op->op_targ) {
 #ifndef USE_ITHREADS
-       svp = &PL_curpad[PL_op->op_targ];               /* "my" variable */
+       svp = &PAD_SVl(PL_op->op_targ);         /* "my" variable */
        SAVESPTR(*svp);
 #else
        SAVEPADSV(PL_op->op_targ);
@@ -2105,13 +2146,13 @@ PP(pp_goto)
                    av = newAV();
                    av_extend(av, items-1);
                    AvFLAGS(av) = AVf_REIFY;
-                   PL_curpad[0] = (SV*)(cx->blk_sub.argarray = av);
+                   PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av);
                }
            }
            else if (CvXSUB(cv)) {      /* put GvAV(defgv) back onto stack */
                AV* av;
 #ifdef USE_5005THREADS
-               av = (AV*)PL_curpad[0];
+               av = (AV*)PAD_SVl(0);
 #else
                av = GvAV(PL_defgv);
 #endif
@@ -2162,7 +2203,6 @@ PP(pp_goto)
            }
            else {
                AV* padlist = CvPADLIST(cv);
-               SV** svp = AvARRAY(padlist);
                if (CxTYPE(cx) == CXt_EVAL) {
                    PL_in_eval = cx->blk_eval.old_in_eval;
                    PL_eval_root = cx->blk_eval.old_eval_root;
@@ -2171,60 +2211,18 @@ PP(pp_goto)
                }
                cx->blk_sub.cv = cv;
                cx->blk_sub.olddepth = (U16)CvDEPTH(cv);
+
                CvDEPTH(cv)++;
                if (CvDEPTH(cv) < 2)
                    (void)SvREFCNT_inc(cv);
-               else {  /* save temporaries on recursion? */
+               else {
                    if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
                        sub_crush_depth(cv);
-                   if (CvDEPTH(cv) > AvFILLp(padlist)) {
-                       AV *newpad = newAV();
-                       SV **oldpad = AvARRAY(svp[CvDEPTH(cv)-1]);
-                       I32 ix = AvFILLp((AV*)svp[1]);
-                       I32 names_fill = AvFILLp((AV*)svp[0]);
-                       svp = AvARRAY(svp[0]);
-                       for ( ;ix > 0; ix--) {
-                           if (names_fill >= ix && svp[ix] != &PL_sv_undef) {
-                               char *name = SvPVX(svp[ix]);
-                               if ((SvFLAGS(svp[ix]) & SVf_FAKE)
-                                   || *name == '&')
-                               {
-                                   /* outer lexical or anon code */
-                                   av_store(newpad, ix,
-                                       SvREFCNT_inc(oldpad[ix]) );
-                               }
-                               else {          /* our own lexical */
-                                   if (*name == '@')
-                                       av_store(newpad, ix, sv = (SV*)newAV());
-                                   else if (*name == '%')
-                                       av_store(newpad, ix, sv = (SV*)newHV());
-                                   else
-                                       av_store(newpad, ix, sv = NEWSV(0,0));
-                                   SvPADMY_on(sv);
-                               }
-                           }
-                           else if (IS_PADGV(oldpad[ix]) || IS_PADCONST(oldpad[ix])) {
-                               av_store(newpad, ix, sv = SvREFCNT_inc(oldpad[ix]));
-                           }
-                           else {
-                               av_store(newpad, ix, sv = NEWSV(0,0));
-                               SvPADTMP_on(sv);
-                           }
-                       }
-                       if (cx->blk_sub.hasargs) {
-                           AV* av = newAV();
-                           av_extend(av, 0);
-                           av_store(newpad, 0, (SV*)av);
-                           AvFLAGS(av) = AVf_REIFY;
-                       }
-                       av_store(padlist, CvDEPTH(cv), (SV*)newpad);
-                       AvFILLp(padlist) = CvDEPTH(cv);
-                       svp = AvARRAY(padlist);
-                   }
+                   pad_push(padlist, CvDEPTH(cv), cx->blk_sub.hasargs);
                }
 #ifdef USE_5005THREADS
                if (!cx->blk_sub.hasargs) {
-                   AV* av = (AV*)PL_curpad[0];
+                   AV* av = (AV*)PAD_SVl(0);
                
                    items = AvFILLp(av) + 1;
                    if (items) {
@@ -2235,21 +2233,20 @@ PP(pp_goto)
                        PUTBACK ;               
                    }
                }
-#endif /* USE_5005THREADS */           
-               SAVEVPTR(PL_curpad);
-               PL_curpad = AvARRAY((AV*)svp[CvDEPTH(cv)]);
+#endif /* USE_5005THREADS */
+               PAD_SET_CUR(padlist, CvDEPTH(cv));
 #ifndef USE_5005THREADS
                if (cx->blk_sub.hasargs)
 #endif /* USE_5005THREADS */
                {
-                   AV* av = (AV*)PL_curpad[0];
+                   AV* av = (AV*)PAD_SVl(0);
                    SV** ary;
 
 #ifndef USE_5005THREADS
                    cx->blk_sub.savearray = GvAV(PL_defgv);
                    GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
 #endif /* USE_5005THREADS */
-                   cx->blk_sub.oldcurpad = PL_curpad;
+                   CX_CURPAD_SAVE(cx->blk_sub);
                    cx->blk_sub.argarray = av;
                    ++mark;
 
@@ -2670,7 +2667,6 @@ S_doeval(pTHX_ int gimme, OP** startop)
     dSP;
     OP *saveop = PL_op;
     CV *caller;
-    AV* comppadlist;
     I32 i;
 
     PL_in_eval = ((saveop && saveop->op_type == OP_REQUIRE)
@@ -2679,16 +2675,6 @@ S_doeval(pTHX_ int gimme, OP** startop)
 
     PUSHMARK(SP);
 
-    /* set up a scratch pad */
-
-    SAVEI32(PL_padix);
-    SAVEVPTR(PL_curpad);
-    SAVESPTR(PL_comppad);
-    SAVESPTR(PL_comppad_name);
-    SAVEI32(PL_comppad_name_fill);
-    SAVEI32(PL_min_intro_pending);
-    SAVEI32(PL_max_intro_pending);
-
     caller = PL_compcv;
     for (i = cxstack_ix - 1; i >= 0; i--) {
        PERL_CONTEXT *cx = &cxstack[i];
@@ -2713,24 +2699,9 @@ S_doeval(pTHX_ int gimme, OP** startop)
     MUTEX_INIT(CvMUTEXP(PL_compcv));
 #endif /* USE_5005THREADS */
 
-    PL_comppad = newAV();
-    av_push(PL_comppad, Nullsv);
-    PL_curpad = AvARRAY(PL_comppad);
-    PL_comppad_name = newAV();
-    PL_comppad_name_fill = 0;
-    PL_min_intro_pending = 0;
-    PL_padix = 0;
-#ifdef USE_5005THREADS
-    av_store(PL_comppad_name, 0, newSVpvn("@_", 2));
-    PL_curpad[0] = (SV*)newAV();
-    SvPADMY_on(PL_curpad[0]);  /* XXX Needed? */
-#endif /* USE_5005THREADS */
+    /* set up a scratch pad */
 
-    comppadlist = newAV();
-    AvREAL_off(comppadlist);
-    av_store(comppadlist, 0, (SV*)PL_comppad_name);
-    av_store(comppadlist, 1, (SV*)PL_comppad);
-    CvPADLIST(PL_compcv) = comppadlist;
+    CvPADLIST(PL_compcv) = pad_new(padnew_SAVE);
 
     if (!saveop ||
        (saveop->op_type != OP_REQUIRE && saveop->op_type != OP_DOFILE))
@@ -2945,11 +2916,11 @@ PP(pp_require)
 
                /* help out with the "use 5.6" confusion */
                if (sver == 0 && (rev > 5 || (rev == 5 && ver >= 100))) {
-                   DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required--"
-                       "this is only v%d.%d.%d, stopped"
-                       " (did you mean v%"UVuf".%03"UVuf"?)",
-                       rev, ver, sver, PERL_REVISION, PERL_VERSION,
-                       PERL_SUBVERSION, rev, ver/100);
+                   DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required"
+                       " (did you mean v%"UVuf".%03"UVuf"?)--"
+                       "this is only v%d.%d.%d, stopped",
+                       rev, ver, sver, rev, ver/100,
+                       PERL_REVISION, PERL_VERSION, PERL_SUBVERSION);
                }
                else {
                    DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required--"
@@ -2976,6 +2947,17 @@ PP(pp_require)
        tryname = name;
        tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE);
     }
+#ifdef MACOS_TRADITIONAL
+    if (!tryrsfp) {
+       char newname[256];
+
+       MacPerl_CanonDir(name, newname, 1);
+       if (path_is_absolute(newname)) {
+           tryname = newname;
+           tryrsfp = doopen_pmc(newname,PERL_SCRIPT_MODE);
+       }
+    }
+#endif
     if (!tryrsfp) {
        AV *ar = GvAVn(PL_incgv);
        I32 i;
@@ -3109,8 +3091,11 @@ PP(pp_require)
                  ) {
                    char *dir = SvPVx(dirsv, n_a);
 #ifdef MACOS_TRADITIONAL
-                   char buf[256];
-                   Perl_sv_setpvf(aTHX_ namesv, "%s%s", MacPerl_CanonDir(dir, buf), name+(name[0] == ':'));
+                   char buf1[256];
+                   char buf2[256];
+
+                   MacPerl_CanonDir(name, buf2, 1);
+                   Perl_sv_setpvf(aTHX_ namesv, "%s%s", MacPerl_CanonDir(dir, buf1, 0), buf2+(buf2[0] == ':'));
 #else
 #ifdef VMS
                    char *unixdir;
@@ -3124,14 +3109,6 @@ PP(pp_require)
 #endif
                    TAINT_PROPER("require");
                    tryname = SvPVX(namesv);
-#ifdef MACOS_TRADITIONAL
-                   {
-                       /* Convert slashes in the name part, but not the directory part, to colons */
-                       char * colon;
-                       for (colon = tryname+strlen(dir); colon = strchr(colon, '/'); )
-                           *colon++ = ':';
-                   }
-#endif
                    tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
                    if (tryrsfp) {
                        if (tryname[0] == '.' && tryname[1] == '/')
@@ -3175,7 +3152,7 @@ PP(pp_require)
        RETPUSHUNDEF;
     }
     else
-       SETERRNO(0, SS$_NORMAL);
+       SETERRNO(0, SS_NORMAL);
 
     /* Assume success here to prevent recursive requirement. */
     len = strlen(name);
@@ -3263,7 +3240,7 @@ PP(pp_entereval)
     STRLEN len;
     OP *ret;
 
-    if (!SvPV(sv,len) || !len)
+    if (!SvPV(sv,len))
        RETPUSHUNDEF;
     TAINT_PROPER("eval");
 
@@ -3743,7 +3720,7 @@ S_path_is_absolute(pTHX_ char *name)
 {
     if (PERL_FILE_IS_ABSOLUTE(name)
 #ifdef MACOS_TRADITIONAL
-       || (*name == ':' && name[1] != ':' && strchr(name+2, ':')))
+       || (*name == ':'))
 #else
        || (*name == '.' && (name[1] == '/' ||
                             (name[1] == '.' && name[2] == '/'))))