This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Minor updates of the charnames documentation.
[perl5.git] / pp_ctl.c
index c60f7dc..55ec3c3 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1,6 +1,7 @@
 /*    pp_ctl.c
  *
- *    Copyright (c) 1991-2002, Larry Wall
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ *    2000, 2001, 2002, 2003, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -21,7 +22,7 @@
 #include "perl.h"
 
 #ifndef WORD_ALIGN
-#define WORD_ALIGN sizeof(U16)
+#define WORD_ALIGN sizeof(U32)
 #endif
 
 #define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o))
@@ -73,7 +74,7 @@ PP(pp_regcomp)
     tmpstr = POPs;
 
     /* prevent recompiling under /o and ithreads. */
-#if defined(USE_ITHREADS) || defined(USE_5005THREADS)
+#if defined(USE_ITHREADS)
     if (pm->op_pmflags & PMf_KEEP && PM_GETRE(pm))
         RETURN;
 #endif
@@ -93,11 +94,11 @@ PP(pp_regcomp)
 
        /* Check against the last compiled regexp. */
        if (!PM_GETRE(pm) || !PM_GETRE(pm)->precomp ||
-           PM_GETRE(pm)->prelen != len ||
+           PM_GETRE(pm)->prelen != (I32)len ||
            memNE(PM_GETRE(pm)->precomp, t, len))
        {
            if (PM_GETRE(pm)) {
-               ReREFCNT_dec(PM_GETRE(pm));
+               ReREFCNT_dec(PM_GETRE(pm));
                PM_SETRE(pm, Null(REGEXP*));    /* crucial if regcomp aborts */
            }
            if (PL_op->op_flags & OPf_SPECIAL)
@@ -138,7 +139,7 @@ PP(pp_regcomp)
     /* XXX runtime compiled output needs to move to the pad */
     if (pm->op_pmflags & PMf_KEEP) {
        pm->op_private &= ~OPpRUNTIME;  /* no point compiling again */
-#if !defined(USE_ITHREADS) && !defined(USE_5005THREADS)
+#if !defined(USE_ITHREADS)
        /* XXX can't change the optree at runtime either */
        cLOGOP->op_first->op_next = PL_op->op_next;
 #endif
@@ -156,8 +157,19 @@ PP(pp_substcont)
     register char *m = cx->sb_m;
     char *orig = cx->sb_orig;
     register REGEXP *rx = cx->sb_rx;
+    SV *nsv = Nullsv;
+
+    { 
+      REGEXP *old = PM_GETRE(pm);
+      if(old != rx) {
+       if(old) 
+         ReREFCNT_dec(old);
+       PM_SETRE(pm,rx);
+      }
+    }
 
     rxres_restore(&cx->sb_rxres, rx);
+    RX_MATCH_UTF8_set(rx, SvUTF8(cx->sb_targ));
 
     if (cx->sb_iters++) {
        I32 saviters = cx->sb_iters;
@@ -177,11 +189,22 @@ PP(pp_substcont)
        {
            SV *targ = cx->sb_targ;
 
-           sv_catpvn(dstr, s, cx->sb_strend - s);
+           if (DO_UTF8(dstr) && !SvUTF8(targ))
+               sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
+           else
+               sv_catpvn(dstr, s, cx->sb_strend - s);
            cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
 
-           (void)SvOOK_off(targ);
-           Safefree(SvPVX(targ));
+#ifdef PERL_COPY_ON_WRITE
+           if (SvIsCOW(targ)) {
+               sv_force_normal_flags(targ, SV_COW_DROP_PV);
+           } else
+#endif
+           {
+               (void)SvOOK_off(targ);
+               if (SvLEN(targ))
+                   Safefree(SvPVX(targ));
+           }
            SvPVX(targ) = SvPVX(dstr);
            SvCUR_set(targ, SvCUR(dstr));
            SvLEN_set(targ, SvLEN(dstr));
@@ -191,7 +214,7 @@ PP(pp_substcont)
            sv_free(dstr);
 
            TAINT_IF(cx->sb_rxtainted & 1);
-           PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1)));
+           PUSHs(sv_2mortal(newSViv(saviters - 1)));
 
            (void)SvPOK_only_UTF8(targ);
            TAINT_IF(cx->sb_rxtainted);
@@ -199,6 +222,7 @@ PP(pp_substcont)
            SvTAINT(targ);
 
            LEAVE_SCOPE(cx->sb_oldsave);
+           ReREFCNT_dec(rx);
            POPSUBST(cx);
            RETURNOP(pm->op_next);
        }
@@ -212,8 +236,12 @@ PP(pp_substcont)
        cx->sb_strend = s + (cx->sb_strend - m);
     }
     cx->sb_m = m = rx->startp[0] + orig;
-    if (m > s)
-       sv_catpvn(dstr, s, m-s);
+    if (m > s) {
+       if (DO_UTF8(dstr) && !SvUTF8(cx->sb_targ)) 
+           sv_catpvn_utf8_upgrade(dstr, s, m - s, nsv);
+       else
+           sv_catpvn(dstr, s, m-s);
+    }
     cx->sb_s = rx->endp[0] + orig;
     { /* Update the pos() information. */
        SV *sv = cx->sb_targ;
@@ -230,6 +258,7 @@ PP(pp_substcont)
            sv_pos_b2u(sv, &i);
        mg->mg_len = i;
     }
+    ReREFCNT_inc(rx);
     cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
     rxres_save(&cx->sb_rxres, rx);
     RETURNOP(pm->op_pmreplstart);
@@ -242,7 +271,11 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx)
     U32 i;
 
     if (!p || p[1] < rx->nparens) {
+#ifdef PERL_COPY_ON_WRITE
+       i = 7 + rx->nparens * 2;
+#else
        i = 6 + rx->nparens * 2;
+#endif
        if (!p)
            New(501, p, i, UV);
        else
@@ -253,6 +286,11 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx)
     *p++ = PTR2UV(RX_MATCH_COPIED(rx) ? rx->subbeg : Nullch);
     RX_MATCH_COPIED_off(rx);
 
+#ifdef PERL_COPY_ON_WRITE
+    *p++ = PTR2UV(rx->saved_copy);
+    rx->saved_copy = Nullsv;
+#endif
+
     *p++ = rx->nparens;
 
     *p++ = PTR2UV(rx->subbeg);
@@ -269,11 +307,17 @@ Perl_rxres_restore(pTHX_ void **rsp, REGEXP *rx)
     UV *p = (UV*)*rsp;
     U32 i;
 
-    if (RX_MATCH_COPIED(rx))
-       Safefree(rx->subbeg);
+    RX_MATCH_COPY_FREE(rx);
     RX_MATCH_COPIED_set(rx, *p);
     *p++ = 0;
 
+#ifdef PERL_COPY_ON_WRITE
+    if (rx->saved_copy)
+       SvREFCNT_dec (rx->saved_copy);
+    rx->saved_copy = INT2PTR(SV*,*p);
+    *p++ = 0;
+#endif
+
     rx->nparens = *p++;
 
     rx->subbeg = INT2PTR(char*,*p++);
@@ -291,6 +335,11 @@ Perl_rxres_free(pTHX_ void **rsp)
 
     if (p) {
        Safefree(INT2PTR(char*,*p));
+#ifdef PERL_COPY_ON_WRITE
+       if (p[1]) {
+           SvREFCNT_dec (INT2PTR(SV*,p[1]));
+       }
+#endif
        Safefree(p);
        *rsp = Null(void*);
     }
@@ -300,7 +349,7 @@ PP(pp_formline)
 {
     dSP; dMARK; dORIGMARK;
     register SV *tmpForm = *++MARK;
-    register U16 *fpc;
+    register U32 *fpc;
     register char *t;
     register char *f;
     register char *s;
@@ -318,7 +367,9 @@ PP(pp_formline)
     bool gotsome = FALSE;
     STRLEN len;
     STRLEN fudge = SvCUR(tmpForm) * (IN_BYTES ? 1 : 3) + 1;
-    bool item_is_utf = FALSE;
+    bool item_is_utf8 = FALSE;
+    bool targ_is_utf8 = FALSE;
+    SV * nsv = Nullsv;
 
     if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) {
        if (SvREADONLY(tmpForm)) {
@@ -329,15 +380,16 @@ PP(pp_formline)
        else
            doparseform(tmpForm);
     }
-
     SvPV_force(PL_formtarget, len);
+    if (DO_UTF8(PL_formtarget))
+       targ_is_utf8 = TRUE;
     t = SvGROW(PL_formtarget, len + fudge + 1);  /* XXX SvCUR bad */
     t += len;
     f = SvPV(tmpForm, len);
     /* need to jump to the next word */
     s = f + len + WORD_ALIGN - SvCUR(tmpForm) % WORD_ALIGN;
 
-    fpc = (U16*)s;
+    fpc = (U32*)s;
 
     for (;;) {
        DEBUG_f( {
@@ -377,6 +429,21 @@ PP(pp_formline)
 
        case FF_LITERAL:
            arg = *fpc++;
+           if (targ_is_utf8 && !SvUTF8(tmpForm)) {
+               SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+               *t = '\0';
+               sv_catpvn_utf8_upgrade(PL_formtarget, f, arg, nsv);
+               t = SvEND(PL_formtarget);
+               break;
+           }
+           if (!targ_is_utf8 && DO_UTF8(tmpForm)) {
+               SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+               *t = '\0';
+               sv_utf8_upgrade(PL_formtarget);
+               SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
+               t = SvEND(PL_formtarget);
+               targ_is_utf8 = TRUE;
+           }
            while (arg--)
                *t++ = *f++;
            break;
@@ -395,7 +462,7 @@ PP(pp_formline)
            else {
                sv = &PL_sv_no;
                if (ckWARN(WARN_SYNTAX))
-                   Perl_warner(aTHX_ WARN_SYNTAX, "Not enough format arguments");
+                   Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Not enough format arguments");
            }
            break;
 
@@ -404,7 +471,7 @@ PP(pp_formline)
            itemsize = len;
            if (DO_UTF8(sv)) {
                itemsize = sv_len_utf8(sv);
-               if (itemsize != len) {
+               if (itemsize != (I32)len) {
                    I32 itembytes;
                    if (itemsize > fieldsize) {
                        itemsize = fieldsize;
@@ -421,13 +488,13 @@ PP(pp_formline)
                            break;
                        s++;
                    }
-                   item_is_utf = TRUE;
+                   item_is_utf8 = TRUE;
                    itemsize = s - item;
                    sv_pos_b2u(sv, &itemsize);
                    break;
                }
            }
-           item_is_utf = FALSE;
+           item_is_utf8 = FALSE;
            if (itemsize > fieldsize)
                itemsize = fieldsize;
            send = chophere = s + itemsize;
@@ -446,7 +513,7 @@ PP(pp_formline)
            itemsize = len;
            if (DO_UTF8(sv)) {
                itemsize = sv_len_utf8(sv);
-               if (itemsize != len) {
+               if (itemsize != (I32)len) {
                    I32 itembytes;
                    if (itemsize <= fieldsize) {
                        send = chophere = s + itemsize;
@@ -482,11 +549,11 @@ PP(pp_formline)
                        itemsize = chophere - item;
                        sv_pos_b2u(sv, &itemsize);
                    }
-                   item_is_utf = TRUE;
+                   item_is_utf8 = TRUE;
                    break;
                }
            }
-           item_is_utf = FALSE;
+           item_is_utf8 = FALSE;
            if (itemsize <= fieldsize) {
                send = chophere = s + itemsize;
                while (s < send) {
@@ -542,7 +609,15 @@ PP(pp_formline)
        case FF_ITEM:
            arg = itemsize;
            s = item;
-           if (item_is_utf) {
+           if (item_is_utf8) {
+               if (!targ_is_utf8) {
+                   SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+                   *t = '\0';
+                   sv_utf8_upgrade(PL_formtarget);
+                   SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
+                   t = SvEND(PL_formtarget);
+                   targ_is_utf8 = TRUE;
+               }
                while (arg--) {
                    if (UTF8_IS_CONTINUED(*s)) {
                        STRLEN skip = UTF8SKIP(s);
@@ -568,6 +643,21 @@ PP(pp_formline)
                }
                break;
            }
+           if (targ_is_utf8 && !item_is_utf8) {
+               SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+               *t = '\0';
+               sv_catpvn_utf8_upgrade(PL_formtarget, s, arg, nsv);
+               for (; t < SvEND(PL_formtarget); t++) {
+#ifdef EBCDIC
+                   int ch = *t++ = *s++;
+                   if (iscntrl(ch))
+#else
+                   if (!(*t & ~31))
+#endif
+                       *t = ' ';
+               }
+               break;
+           }
            while (arg--) {
 #ifdef EBCDIC
                int ch = *t++ = *s++;
@@ -591,22 +681,32 @@ PP(pp_formline)
        case FF_LINEGLOB:
            item = s = SvPV(sv, len);
            itemsize = len;
-           item_is_utf = FALSE;                /* XXX is this correct? */
+           if ((item_is_utf8 = DO_UTF8(sv)))
+               itemsize = sv_len_utf8(sv);         
            if (itemsize) {
+               bool chopped = FALSE;
                gotsome = TRUE;
-               send = s + itemsize;
+               send = s + len;
                while (s < send) {
                    if (*s++ == '\n') {
-                       if (s == send)
+                       if (s == send) {
                            itemsize--;
+                           chopped = TRUE;
+                       }
                        else
                            lines++;
                    }
                }
                SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
-               sv_catpvn(PL_formtarget, item, itemsize);
+               if (targ_is_utf8)
+                   SvUTF8_on(PL_formtarget);
+               sv_catsv(PL_formtarget, sv);
+               if (chopped)
+                   SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) - 1);
                SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
                t = SvPVX(PL_formtarget) + SvCUR(PL_formtarget);
+               if (item_is_utf8)
+                   targ_is_utf8 = TRUE;
            }
            break;
 
@@ -702,6 +802,8 @@ PP(pp_formline)
                        if (strnEQ(linemark, linemark - arg, arg))
                            DIE(aTHX_ "Runaway format");
                    }
+                   if (targ_is_utf8)
+                       SvUTF8_on(PL_formtarget);
                    FmLINES(PL_formtarget) = lines;
                    SP = ORIGMARK;
                    RETURNOP(cLISTOP->op_first);
@@ -741,6 +843,8 @@ PP(pp_formline)
        case FF_END:
            *t = '\0';
            SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+           if (targ_is_utf8)
+               SvUTF8_on(PL_formtarget);
            FmLINES(PL_formtarget) += lines;
            SP = ORIGMARK;
            RETPUSHYES;
@@ -835,7 +939,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 */
@@ -895,13 +999,16 @@ PP(pp_flip)
     else {
        dTOPss;
        SV *targ = PAD_SV(PL_op->op_targ);
-       int flip;
+       int flip = 0;
 
        if (PL_op->op_private & OPpFLIP_LINENUM) {
-           struct io *gp_io;
-           flip = PL_last_in_gv
-               && (gp_io = GvIO(PL_last_in_gv))
-               && SvIV(sv) == (IV)IoLINES(gp_io);
+           if (GvIO(PL_last_in_gv)) {
+               flip = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv));
+           }
+           else {
+               GV *gv = gv_fetchpv(".", TRUE, SVt_PV);
+               if (gv && GvSV(gv)) flip = SvIV(sv) == SvIV(GvSV(gv));
+           }
        } else {
            flip = SvTRUE(sv);
        }
@@ -939,10 +1046,14 @@ PP(pp_flop)
        if (SvGMAGICAL(right))
            mg_get(right);
 
+       /* This code tries to decide if "$left .. $right" should use the
+          magical string increment, or if the range is numeric (we make
+          an exception for .."0" [#18165]). AMS 20021031. */
+
        if (SvNIOKp(left) || !SvPOKp(left) ||
            SvNIOKp(right) || !SvPOKp(right) ||
            (looks_like_number(left) && *SvPVX(left) != '0' &&
-            looks_like_number(right) && *SvPVX(right) != '0'))
+            looks_like_number(right)))
        {
            if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
                DIE(aTHX_ "Range iterator outside integer range");
@@ -979,11 +1090,23 @@ PP(pp_flop)
     else {
        dTOPss;
        SV *targ = PAD_SV(cUNOP->op_first->op_targ);
+       int flop = 0;
        sv_inc(targ);
-       if ((PL_op->op_private & OPpFLIP_LINENUM)
-         ? (GvIO(PL_last_in_gv)
-            && SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv)))
-         : SvTRUE(sv) ) {
+
+       if (PL_op->op_private & OPpFLIP_LINENUM) {
+           if (GvIO(PL_last_in_gv)) {
+               flop = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv));
+           }
+           else {
+               GV *gv = gv_fetchpv(".", TRUE, SVt_PV);
+               if (gv && GvSV(gv)) flop = SvIV(sv) == SvIV(GvSV(gv));
+           }
+       }
+       else {
+           flop = SvTRUE(sv);
+       }
+
+       if (flop) {
            sv_setiv(PAD_SV(((UNOP*)cUNOP->op_first)->op_first->op_targ), 0);
            sv_catpv(targ, "E0");
        }
@@ -995,6 +1118,16 @@ PP(pp_flop)
 
 /* Control. */
 
+static char *context_name[] = {
+    "pseudo-block",
+    "subroutine",
+    "eval",
+    "loop",
+    "substitution",
+    "block",
+    "format"
+};
+
 STATIC I32
 S_dopoptolabel(pTHX_ char *label)
 {
@@ -1005,30 +1138,16 @@ S_dopoptolabel(pTHX_ char *label)
        cx = &cxstack[i];
        switch (CxTYPE(cx)) {
        case CXt_SUBST:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_SUB:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_FORMAT:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_EVAL:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_NULL:
            if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s",
-                       OP_NAME(PL_op));
-           return -1;
+               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+                       context_name[CxTYPE(cx)], OP_NAME(PL_op));
+           if (CxTYPE(cx) == CXt_NULL)
+               return -1;
+           break;
        case CXt_LOOP:
            if (!cx->blk_loop.label ||
              strNE(label, cx->blk_loop.label) ) {
@@ -1140,30 +1259,16 @@ S_dopoptoloop(pTHX_ I32 startingblock)
        cx = &cxstack[i];
        switch (CxTYPE(cx)) {
        case CXt_SUBST:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_SUB:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_FORMAT:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_EVAL:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_NULL:
            if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s",
-                       OP_NAME(PL_op));
-           return -1;
+               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+                       context_name[CxTYPE(cx)], OP_NAME(PL_op));
+           if ((CxTYPE(cx)) == CXt_NULL)
+               return -1;
+           break;
        case CXt_LOOP:
            DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i));
            return i;
@@ -1224,8 +1329,6 @@ OP *
 Perl_die_where(pTHX_ char *message, STRLEN msglen)
 {
     STRLEN n_a;
-    IO *io;
-    MAGIC *mg;
 
     if (PL_in_eval) {
        I32 cxix;
@@ -1252,7 +1355,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
                    sv_catpvn(err, message, msglen);
                    if (ckWARN(WARN_MISC)) {
                        STRLEN start = SvCUR(err)-msglen-sizeof(prefix)+1;
-                       Perl_warner(aTHX_ WARN_MISC, SvPVX(err)+start);
+                       Perl_warner(aTHX_ packWARN(WARN_MISC), SvPVX(err)+start);
                    }
                }
            }
@@ -1260,8 +1363,6 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
                sv_setpvn(ERRSV, message, msglen);
            }
        }
-       else
-           message = SvPVx(ERRSV, msglen);
 
        while ((cxix = dopoptoeval(cxstack_ix)) < 0
               && PL_curstackinfo->si_prev)
@@ -1278,6 +1379,8 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
 
            POPBLOCK(cx,PL_curpm);
            if (CxTYPE(cx) != CXt_EVAL) {
+               if (!message)
+                   message = SvPVx(ERRSV, msglen);
                PerlIO_write(Perl_error_log, "panic: die ", 11);
                PerlIO_write(Perl_error_log, message, msglen);
                my_exit(1);
@@ -1307,30 +1410,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
     if (!message)
        message = SvPVx(ERRSV, msglen);
 
-    /* if STDERR is tied, print to it instead */
-    if (PL_stderrgv && (io = GvIOp(PL_stderrgv))
-       && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) {
-       dSP; ENTER;
-       PUSHMARK(SP);
-       XPUSHs(SvTIED_obj((SV*)io, mg));
-       XPUSHs(sv_2mortal(newSVpvn(message, msglen)));
-       PUTBACK;
-       call_method("PRINT", G_SCALAR);
-       LEAVE;
-    }
-    else {
-#ifdef USE_SFIO
-       /* SFIO can really mess with your errno */
-       int e = errno;
-#endif
-       PerlIO *serr = Perl_error_log;
-
-       PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen);
-       (void)PerlIO_flush(serr);
-#ifdef USE_SFIO
-       errno = e;
-#endif
-    }
+    write_to_stderr(message, msglen);
     my_failure_exit();
     /* NOTREACHED */
     return 0;
@@ -1362,7 +1442,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;
@@ -1434,11 +1547,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)));
@@ -1502,8 +1622,18 @@ PP(pp_caller)
                (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
             mask = newSVpvn(WARN_NONEstring, WARNsize) ;
         else if (old_warnings == pWARN_ALL ||
-                 (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON))
-            mask = newSVpvn(WARN_ALLstring, WARNsize) ;
+                 (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) {
+           /* Get the bit mask for $warnings::Bits{all}, because
+            * it could have been extended by warnings::register */
+           SV **bits_all;
+           HV *bits = get_hv("warnings::Bits", FALSE);
+           if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) {
+               mask = newSVsv(*bits_all);
+           }
+           else {
+               mask = newSVpvn(WARN_ALLstring, WARNsize) ;
+           }
+       }
         else
             mask = newSVsv(old_warnings);
         PUSHs(sv_2mortal(mask));
@@ -1531,6 +1661,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;
@@ -1538,13 +1670,14 @@ PP(pp_dbstate)
     PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
     FREETMPS;
 
-    if (PL_op->op_private || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
+    if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */
+           || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
     {
        dSP;
        register CV *cv;
        register PERL_CONTEXT *cx;
        I32 gimme = G_ARRAY;
-       I32 hasargs;
+       U8 hasargs;
        GV *gv;
 
        gv = PL_DBgv;
@@ -1567,11 +1700,10 @@ PP(pp_dbstate)
 
        push_return(PL_op->op_next);
        PUSHBLOCK(cx, CXt_SUB, SP);
-       PUSHSUB(cx);
+       PUSHSUB_DB(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
@@ -1597,17 +1729,9 @@ PP(pp_enteriter)
     ENTER;
     SAVETMPS;
 
-#ifdef USE_5005THREADS
-    if (PL_op->op_flags & OPf_SPECIAL) {
-       svp = &THREADSV(PL_op->op_targ);        /* per-thread variable */
-       SAVEGENERICSV(*svp);
-       *svp = NEWSV(0,0);
-    }
-    else
-#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);
@@ -1637,11 +1761,11 @@ PP(pp_enteriter)
        cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
        if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
            dPOPss;
+           /* See comment in pp_flop() */
            if (SvNIOKp(sv) || !SvPOKp(sv) ||
                SvNIOKp(cx->blk_loop.iterary) || !SvPOKp(cx->blk_loop.iterary) ||
                (looks_like_number(sv) && *SvPVX(sv) != '0' &&
-                looks_like_number((SV*)cx->blk_loop.iterary) &&
-                *SvPVX(cx->blk_loop.iterary) != '0'))
+                looks_like_number((SV*)cx->blk_loop.iterary)))
            {
                 if (SvNV(sv) < IV_MIN ||
                     SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
@@ -1767,7 +1891,7 @@ PP(pp_return)
            /* Unassume the success we assumed earlier. */
            SV *nsv = cx->blk_eval.old_namesv;
            (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
-           DIE(aTHX_ "%s did not return a true value", SvPVX(nsv));
+           DIE(aTHX_ "%"SVf" did not return a true value", nsv);
        }
        break;
     case CXt_FORMAT:
@@ -1812,6 +1936,7 @@ PP(pp_return)
     }
     PL_stack_sp = newsp;
 
+    LEAVE;
     /* Stack values are safe: */
     if (popsub2) {
        POPSUB(cx,sv);  /* release CV and @_ ... */
@@ -1820,7 +1945,6 @@ PP(pp_return)
        sv = Nullsv;
     PL_curpm = newpm;  /* ... and pop $1 et al */
 
-    LEAVE;
     LEAVESUB(sv);
     if (clear_errsv)
        sv_setpv(ERRSV,"");
@@ -1896,6 +2020,7 @@ PP(pp_last)
     SP = newsp;
     PUTBACK;
 
+    LEAVE;
     /* Stack values are safe: */
     switch (pop2) {
     case CXt_LOOP:
@@ -1908,7 +2033,6 @@ PP(pp_last)
     }
     PL_curpm = newpm;  /* ... and pop $1 et al */
 
-    LEAVE;
     LEAVESUB(sv);
     return nextop;
 }
@@ -1978,6 +2102,7 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit)
     if (o->op_type == OP_LEAVE ||
        o->op_type == OP_SCOPE ||
        o->op_type == OP_LEAVELOOP ||
+       o->op_type == OP_LEAVESUB ||
        o->op_type == OP_LEAVETRY)
     {
        *ops++ = cUNOPo->op_first;
@@ -1995,11 +2120,15 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit)
        for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
            if (kid == PL_lastgotoprobe)
                continue;
-           if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) &&
-               (ops == opstack ||
-                (ops[-1]->op_type != OP_NEXTSTATE &&
-                 ops[-1]->op_type != OP_DBSTATE)))
-               *ops++ = kid;
+           if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
+               if (ops == opstack)
+                   *ops++ = kid;
+               else if (ops[-1]->op_type == OP_NEXTSTATE ||
+                        ops[-1]->op_type == OP_DBSTATE)
+                   ops[-1] = kid;
+               else
+                   *ops++ = kid;
+           }
            if ((o = dofindlabel(kid, label, ops, oplimit)))
                return o;
        }
@@ -2055,12 +2184,14 @@ PP(pp_goto)
                        goto retry;
                    tmpstr = sv_newmortal();
                    gv_efullname3(tmpstr, gv, Nullch);
-                   DIE(aTHX_ "Goto undefined subroutine &%s",SvPVX(tmpstr));
+                   DIE(aTHX_ "Goto undefined subroutine &%"SVf"",tmpstr);
                }
                DIE(aTHX_ "Goto undefined subroutine");
            }
 
            /* First do some returnish stuff. */
+           SvREFCNT_inc(cv); /* avoid premature free during unwind */
+           FREETMPS;
            cxix = dopoptosub(cxstack_ix);
            if (cxix < 0)
                DIE(aTHX_ "Can't goto subroutine outside a subroutine");
@@ -2079,26 +2210,22 @@ PP(pp_goto)
                EXTEND(PL_stack_sp, items); /* @_ could have been extended. */
                Copy(AvARRAY(av), PL_stack_sp, items, SV*);
                PL_stack_sp += items;
-#ifndef USE_5005THREADS
                SvREFCNT_dec(GvAV(PL_defgv));
                GvAV(PL_defgv) = cx->blk_sub.savearray;
-#endif /* USE_5005THREADS */
                /* abandon @_ if it got reified */
                if (AvREAL(av)) {
                    (void)sv_2mortal((SV*)av);  /* delay until return */
                    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
+                   CLEAR_ARGARRAY(av);
            }
            else if (CvXSUB(cv)) {      /* put GvAV(defgv) back onto stack */
                AV* av;
-#ifdef USE_5005THREADS
-               av = (AV*)PL_curpad[0];
-#else
                av = GvAV(PL_defgv);
-#endif
                items = AvFILLp(av) + 1;
                PL_stack_sp++;
                EXTEND(PL_stack_sp, items); /* @_ could have been extended. */
@@ -2113,6 +2240,7 @@ PP(pp_goto)
 
            /* Now do some callish stuff. */
            SAVETMPS;
+           SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
            if (CvXSUB(cv)) {
 #ifdef PERL_XSUB_OLDSTYLE
                if (CvOLDSTYLE(cv)) {
@@ -2146,7 +2274,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;
@@ -2154,86 +2281,25 @@ PP(pp_goto)
                    cx->blk_sub.hasargs = 0;
                }
                cx->blk_sub.cv = cv;
-               cx->blk_sub.olddepth = CvDEPTH(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];
-               
-                   items = AvFILLp(av) + 1;
-                   if (items) {
-                       /* Mark is at the end of the stack. */
-                       EXTEND(SP, items);
-                       Copy(AvARRAY(av), SP + 1, items, SV*);
-                       SP += items;
-                       PUTBACK ;               
-                   }
-               }
-#endif /* USE_5005THREADS */           
-               SAVEVPTR(PL_curpad);
-               PL_curpad = AvARRAY((AV*)svp[CvDEPTH(cv)]);
-#ifndef USE_5005THREADS
+               PAD_SET_CUR(padlist, CvDEPTH(cv));
                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;
 
@@ -2268,7 +2334,10 @@ PP(pp_goto)
                    CV *gotocv;
                
                    if (PERLDB_SUB_NN) {
-                       SvIVX(sv) = PTR2IV(cv); /* Already upgraded, saved */
+                       (void)SvUPGRADE(sv, SVt_PVIV);
+                       (void)SvIOK_on(sv);
+                       SAVEIV(SvIVX(sv));
+                       SvIVX(sv) = PTR2IV(cv); /* Do it the quickest way */
                    } else {
                        save_item(sv);
                        gv_efullname3(sv, CvGV(cv), Nullch);
@@ -2299,6 +2368,7 @@ PP(pp_goto)
     if (label && *label) {
        OP *gotoprobe = 0;
        bool leaving_eval = FALSE;
+       bool in_block = FALSE;
         PERL_CONTEXT *last_eval_cx = 0;
 
        /* find label */
@@ -2310,7 +2380,7 @@ PP(pp_goto)
            switch (CxTYPE(cx)) {
            case CXt_EVAL:
                leaving_eval = TRUE;
-                if (CxREALEVAL(cx)) {
+                if (!CxTRYBLOCK(cx)) {
                    gotoprobe = (last_eval_cx ?
                                last_eval_cx->blk_eval.old_eval_root :
                                PL_eval_root);
@@ -2324,9 +2394,10 @@ PP(pp_goto)
            case CXt_SUBST:
                continue;
            case CXt_BLOCK:
-               if (ix)
+               if (ix) {
                    gotoprobe = cx->blk_oldcop->op_sibling;
-               else
+                   in_block = TRUE;
+               } else
                    gotoprobe = PL_main_root;
                break;
            case CXt_SUB:
@@ -2383,7 +2454,8 @@ PP(pp_goto)
 
        if (*enterops && enterops[1]) {
            OP *oldop = PL_op;
-           for (ix = 1; enterops[ix]; ix++) {
+           ix = enterops[1]->op_type == OP_ENTER && in_block ? 2 : 1;
+           for (; enterops[ix]; ix++) {
                PL_op = enterops[ix];
                /* Eventually we may want to stack the needed arguments
                 * for each op.  For now, we punt on the hard ones. */
@@ -2519,6 +2591,7 @@ S_docatch(pTHX_ OP *o)
 {
     int ret;
     OP *oldop = PL_op;
+    OP *retop;
     volatile PERL_SI *cursi = PL_curstackinfo;
     dJMPENV;
 
@@ -2526,6 +2599,15 @@ S_docatch(pTHX_ OP *o)
     assert(CATCH_GET == TRUE);
 #endif
     PL_op = o;
+
+    /* Normally, the leavetry at the end of this block of ops will
+     * pop an op off the return stack and continue there. By setting
+     * the op to Nullop, we force an exit from the inner runops()
+     * loop. DAPM.
+     */
+    retop = pop_return();
+    push_return(Nullop);
+
 #ifdef PERL_FLEXIBLE_EXCEPTIONS
  redo_body:
     CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_docatch_body));
@@ -2540,11 +2622,15 @@ S_docatch(pTHX_ OP *o)
 #endif
        break;
     case 3:
+       /* die caught by an inner eval - continue inner loop */
        if (PL_restartop && cursi == PL_curstackinfo) {
            PL_op = PL_restartop;
            PL_restartop = 0;
            goto redo_body;
        }
+       /* a die in this eval - continue in outer loop */
+       if (!PL_restartop)
+           break;
        /* FALL THROUGH */
     default:
        JMPENV_POP;
@@ -2554,11 +2640,11 @@ S_docatch(pTHX_ OP *o)
     }
     JMPENV_POP;
     PL_op = oldop;
-    return Nullop;
+    return retop;
 }
 
 OP *
-Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp)
+Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
 /* sv Text to convert to OP tree. */
 /* startop op_free() this to undo. */
 /* code Short string id of the caller. */
@@ -2573,6 +2659,8 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp)
     char tbuf[TYPE_DIGITS(long) + 12 + 10];
     char *tmpbuf = tbuf;
     char *safestr;
+    int runtime;
+    CV* runcv = Nullcv;        /* initialise to avoid compiler warnings */
 
     ENTER;
     lex_start(sv);
@@ -2611,37 +2699,92 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp)
 #endif
     PL_hints &= HINT_UTF8;
 
+    /* we get here either during compilation, or via pp_regcomp at runtime */
+    runtime = PL_op && (PL_op->op_type == OP_REGCOMP);
+    if (runtime)
+       runcv = find_runcv(NULL);
+
     PL_op = &dummy;
     PL_op->op_type = OP_ENTEREVAL;
     PL_op->op_flags = 0;                       /* Avoid uninit warning. */
     PUSHBLOCK(cx, CXt_EVAL|(PL_curcop == &PL_compiling ? 0 : CXp_REAL), SP);
     PUSHEVAL(cx, 0, Nullgv);
-    rop = doeval(G_SCALAR, startop);
+
+    if (runtime)
+       rop = doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
+    else
+       rop = doeval(G_SCALAR, startop, PL_compcv, PL_cop_seqmax);
     POPBLOCK(cx,PL_curpm);
     POPEVAL(cx);
 
     (*startop)->op_type = OP_NULL;
     (*startop)->op_ppaddr = PL_ppaddr[OP_NULL];
     lex_end();
-    *avp = (AV*)SvREFCNT_inc(PL_comppad);
+    /* XXX DAPM do this properly one year */
+    *padp = (AV*)SvREFCNT_inc(PL_comppad);
     LEAVE;
     if (PL_curcop == &PL_compiling)
-       PL_compiling.op_private = PL_hints;
+       PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
 #ifdef OP_IN_REGISTER
     op = PL_opsave;
 #endif
     return rop;
 }
 
+
+/*
+=for apidoc find_runcv
+
+Locate the CV corresponding to the currently executing sub or eval.
+If db_seqp is non_null, skip CVs that are in the DB package and populate
+*db_seqp with the cop sequence number at the point that the DB:: code was
+entered. (allows debuggers to eval in the scope of the breakpoint rather
+than in in the scope of the debuger itself).
+
+=cut
+*/
+
+CV*
+Perl_find_runcv(pTHX_ U32 *db_seqp)
+{
+    I32                 ix;
+    PERL_SI     *si;
+    PERL_CONTEXT *cx;
+
+    if (db_seqp)
+       *db_seqp = PL_curcop->cop_seq;
+    for (si = PL_curstackinfo; si; si = si->si_prev) {
+       for (ix = si->si_cxix; ix >= 0; ix--) {
+           cx = &(si->si_cxstack[ix]);
+           if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
+               CV *cv = cx->blk_sub.cv;
+               /* skip DB:: code */
+               if (db_seqp && PL_debstash && CvSTASH(cv) == PL_debstash) {
+                   *db_seqp = cx->blk_oldcop->cop_seq;
+                   continue;
+               }
+               return cv;
+           }
+           else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx))
+               return PL_compcv;
+       }
+    }
+    return PL_main_cv;
+}
+
+
+/* Compile a require/do, an eval '', or a /(?{...})/.
+ * In the last case, startop is non-null, and contains the address of
+ * a pointer that should be set to the just-compiled code.
+ * outside is the lexically enclosing CV (if any) that invoked us.
+ */
+
 /* With USE_5005THREADS, eval_owner must be held on entry to doeval */
 STATIC OP *
-S_doeval(pTHX_ int gimme, OP** startop)
+S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
 {
     dSP;
     OP *saveop = PL_op;
-    CV *caller;
-    AV* comppadlist;
-    I32 i;
 
     PL_in_eval = ((saveop && saveop->op_type == OP_REQUIRE)
                  ? (EVAL_INREQUIRE | (PL_in_eval & EVAL_INEVAL))
@@ -2649,27 +2792,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];
-       if (CxTYPE(cx) == CXt_EVAL)
-           break;
-       else if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
-           caller = cx->blk_sub.cv;
-           break;
-       }
-    }
-
     SAVESPTR(PL_compcv);
     PL_compcv = (CV*)NEWSV(1104,0);
     sv_upgrade((SV *)PL_compcv, SVt_PVCV);
@@ -2677,36 +2799,13 @@ S_doeval(pTHX_ int gimme, OP** startop)
     assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
     cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
 
-#ifdef USE_5005THREADS
-    CvOWNER(PL_compcv) = 0;
-    New(666, CvMUTEXP(PL_compcv), 1, perl_mutex);
-    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 */
-
-    comppadlist = newAV();
-    AvREAL_off(comppadlist);
-    av_store(comppadlist, 0, (SV*)PL_comppad_name);
-    av_store(comppadlist, 1, (SV*)PL_comppad);
-    CvPADLIST(PL_compcv) = comppadlist;
-
-    if (!saveop ||
-       (saveop->op_type != OP_REQUIRE && saveop->op_type != OP_DOFILE))
-    {
-       CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(caller);
-    }
+    CvOUTSIDE_SEQ(PL_compcv) = seq;
+    CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outside);
+
+    /* set up a scratch pad */
+
+    CvPADLIST(PL_compcv) = pad_new(padnew_SAVE);
+
 
     SAVEMORTALIZESV(PL_compcv);        /* must remain until end of current statement */
 
@@ -2732,8 +2831,7 @@ S_doeval(pTHX_ int gimme, OP** startop)
     else
        sv_setpv(ERRSV,"");
     if (yyparse() || PL_error_count || !PL_eval_root) {
-       SV **newsp;
-       I32 gimme;
+       SV **newsp;                     /* Used by POPBLOCK. */
        PERL_CONTEXT *cx;
        I32 optype = 0;                 /* Might be reset by POPEVAL. */
        STRLEN n_a;
@@ -2764,22 +2862,29 @@ S_doeval(pTHX_ int gimme, OP** startop)
            Perl_croak(aTHX_ "%sCompilation failed in regexp",
                       (*msg ? msg : "Unknown error\n"));
        }
-#ifdef USE_5005THREADS
-       MUTEX_LOCK(&PL_eval_mutex);
-       PL_eval_owner = 0;
-       COND_SIGNAL(&PL_eval_cond);
-       MUTEX_UNLOCK(&PL_eval_mutex);
-#endif /* USE_5005THREADS */
+       else {
+           char* msg = SvPVx(ERRSV, n_a);
+           if (!*msg) {
+               sv_setpv(ERRSV, "Compilation error");
+           }
+       }
        RETPUSHUNDEF;
     }
     CopLINE_set(&PL_compiling, 0);
     if (startop) {
        *startop = PL_eval_root;
-       SvREFCNT_dec(CvOUTSIDE(PL_compcv));
-       CvOUTSIDE(PL_compcv) = Nullcv;
     } else
        SAVEFREEOP(PL_eval_root);
-    if (gimme & G_VOID)
+
+    /* Set the context for this new optree.
+     * If the last op is an OP_REQUIRE, force scalar context.
+     * Otherwise, propagate the context from the eval(). */
+    if (PL_eval_root->op_type == OP_LEAVEEVAL
+           && cUNOPx(PL_eval_root)->op_first->op_type == OP_LINESEQ
+           && cLISTOPx(cUNOPx(PL_eval_root)->op_first)->op_last->op_type
+           == OP_REQUIRE)
+       scalar(PL_eval_root);
+    else if (gimme & G_VOID)
        scalarvoid(PL_eval_root);
     else if (gimme & G_ARRAY)
        list(PL_eval_root);
@@ -2806,19 +2911,14 @@ S_doeval(pTHX_ int gimme, OP** startop)
     SP = PL_stack_base + POPMARK;              /* pop original mark */
     PL_op = saveop;                    /* The caller may need it. */
     PL_lex_state = LEX_NOTPARSING;     /* $^S needs this. */
-#ifdef USE_5005THREADS
-    MUTEX_LOCK(&PL_eval_mutex);
-    PL_eval_owner = 0;
-    COND_SIGNAL(&PL_eval_cond);
-    MUTEX_UNLOCK(&PL_eval_mutex);
-#endif /* USE_5005THREADS */
 
     RETURNOP(PL_eval_start);
 }
 
 STATIC PerlIO *
-S_doopen_pmc(pTHX_ const char *name, const char *mode)
+S_doopen_pm(pTHX_ const char *name, const char *mode)
 {
+#ifndef PERL_DISABLE_PMC
     STRLEN namelen = strlen(name);
     PerlIO *fp;
 
@@ -2846,6 +2946,9 @@ S_doopen_pmc(pTHX_ const char *name, const char *mode)
        fp = PerlIO_open(name, mode);
     }
     return fp;
+#else
+    return PerlIO_open(name, mode);
+#endif /* !PERL_DISABLE_PMC */
 }
 
 PP(pp_require)
@@ -2897,7 +3000,7 @@ PP(pp_require)
                    PERL_VERSION, PERL_SUBVERSION);
            }
            if (ckWARN(WARN_PORTABLE))
-               Perl_warner(aTHX_ WARN_PORTABLE,
+               Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
                         "v-string in use/require non-portable");
            RETPUSHYES;
        }
@@ -2915,11 +3018,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--"
@@ -2944,8 +3047,19 @@ PP(pp_require)
 
     if (path_is_absolute(name)) {
        tryname = name;
-       tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE);
+       tryrsfp = doopen_pm(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_pm(newname,PERL_SCRIPT_MODE);
+       }
+    }
+#endif
     if (!tryrsfp) {
        AV *ar = GvAVn(PL_incgv);
        I32 i;
@@ -3079,8 +3193,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;
@@ -3094,15 +3211,7 @@ 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);
+                   tryrsfp = doopen_pm(tryname, PERL_SCRIPT_MODE);
                    if (tryrsfp) {
                        if (tryname[0] == '.' && tryname[1] == '/')
                            tryname += 2;
@@ -3145,7 +3254,7 @@ PP(pp_require)
        RETPUSHUNDEF;
     }
     else
-       SETERRNO(0, SS$_NORMAL);
+       SETERRNO(0, SS_NORMAL);
 
     /* Assume success here to prevent recursive requirement. */
     len = strlen(name);
@@ -3195,20 +3304,12 @@ PP(pp_require)
     CopLINE_set(&PL_compiling, 0);
 
     PUTBACK;
-#ifdef USE_5005THREADS
-    MUTEX_LOCK(&PL_eval_mutex);
-    if (PL_eval_owner && PL_eval_owner != thr)
-       while (PL_eval_owner)
-           COND_WAIT(&PL_eval_cond, &PL_eval_mutex);
-    PL_eval_owner = thr;
-    MUTEX_UNLOCK(&PL_eval_mutex);
-#endif /* USE_5005THREADS */
 
     /* Store and reset encoding. */
     encoding = PL_encoding;
     PL_encoding = Nullsv;
 
-    op = DOCATCH(doeval(gimme, NULL));
+    op = DOCATCH(doeval(gimme, NULL, Nullcv, PL_curcop->cop_seq));
     
     /* Restore encoding. */
     PL_encoding = encoding;
@@ -3232,8 +3333,10 @@ PP(pp_entereval)
     char *safestr;
     STRLEN len;
     OP *ret;
+    CV* runcv;
+    U32 seq;
 
-    if (!SvPV(sv,len) || !len)
+    if (!SvPV(sv,len))
        RETPUSHUNDEF;
     TAINT_PROPER("eval");
 
@@ -3279,6 +3382,12 @@ PP(pp_entereval)
         PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
         SAVEFREESV(PL_compiling.cop_io);
     }
+    /* special case: an eval '' executed within the DB package gets lexically
+     * placed in the first non-DB CV rather than the current CV - this
+     * allows the debugger to execute code, find lexicals etc, in the
+     * scope of the code being debugged. Passing &seq gets find_runcv
+     * to do the dirty work for us */
+    runcv = find_runcv(&seq);
 
     push_return(PL_op->op_next);
     PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
@@ -3289,16 +3398,8 @@ PP(pp_entereval)
     if (PERLDB_LINE && PL_curstash != PL_debstash)
        save_lines(CopFILEAV(&PL_compiling), PL_linestr);
     PUTBACK;
-#ifdef USE_5005THREADS
-    MUTEX_LOCK(&PL_eval_mutex);
-    if (PL_eval_owner && PL_eval_owner != thr)
-       while (PL_eval_owner)
-           COND_WAIT(&PL_eval_cond, &PL_eval_mutex);
-    PL_eval_owner = thr;
-    MUTEX_UNLOCK(&PL_eval_mutex);
-#endif /* USE_5005THREADS */
-    ret = doeval(gimme, NULL);
-    if (PERLDB_INTER && was != PL_sub_generation /* Some subs defined here. */
+    ret = doeval(gimme, NULL, runcv, seq);
+    if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */
        && ret != PL_op->op_next) {     /* Successive compilation. */
        strcpy(safestr, "_<(eval )");   /* Anything fake and short. */
     }
@@ -3361,7 +3462,7 @@ PP(pp_leaveeval)
        /* Unassume the success we assumed earlier. */
        SV *nsv = cx->blk_eval.old_namesv;
        (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
-       retop = Perl_die(aTHX_ "%s did not return a true value", SvPVX(nsv));
+       retop = Perl_die(aTHX_ "%"SVf" did not return a true value", nsv);
        /* die_where() did LEAVE, or we won't be here */
     }
     else {
@@ -3398,13 +3499,14 @@ PP(pp_leavetry)
     register SV **mark;
     SV **newsp;
     PMOP *newpm;
+    OP* retop;
     I32 gimme;
     register PERL_CONTEXT *cx;
     I32 optype;
 
     POPBLOCK(cx,newpm);
     POPEVAL(cx);
-    pop_return();
+    retop = pop_return();
 
     TAINT_NOT;
     if (gimme == G_VOID)
@@ -3436,7 +3538,7 @@ PP(pp_leavetry)
 
     LEAVE;
     sv_setpv(ERRSV,"");
-    RETURN;
+    RETURNOP(retop);
 }
 
 STATIC void
@@ -3450,16 +3552,25 @@ S_doparseform(pTHX_ SV *sv)
     bool noblank   = FALSE;
     bool repeat    = FALSE;
     bool postspace = FALSE;
-    U16 *fops;
-    register U16 *fpc;
-    U16 *linepc = 0;
+    U32 *fops;
+    register U32 *fpc;
+    U32 *linepc = 0;
     register I32 arg;
     bool ischop;
+    int maxops = 2; /* FF_LINEMARK + FF_END) */
 
     if (len == 0)
        Perl_croak(aTHX_ "Null picture in formline");
 
-    New(804, fops, (send - s)*3+10, U16);    /* Almost certainly too long... */
+    /* estimate the buffer size needed */
+    for (base = s; s <= send; s++) {
+       if (*s == '\n' || *s == '@' || *s == '^')
+           maxops += 10;
+    }
+    s = base;
+    base = Nullch;
+
+    New(804, fops, maxops, U32);
     fpc = fops;
 
     if (s < send) {
@@ -3495,14 +3606,14 @@ S_doparseform(pTHX_ SV *sv)
                if (postspace)
                    *fpc++ = FF_SPACE;
                *fpc++ = FF_LITERAL;
-               *fpc++ = arg;
+               *fpc++ = (U16)arg;
            }
            postspace = FALSE;
            if (s <= send)
                skipspaces--;
            if (skipspaces) {
                *fpc++ = FF_SKIP;
-               *fpc++ = skipspaces;
+               *fpc++ = (U16)skipspaces;
            }
            skipspaces = 0;
            if (s <= send)
@@ -3513,7 +3624,7 @@ S_doparseform(pTHX_ SV *sv)
                    arg = fpc - linepc + 1;
                else
                    arg = 0;
-               *fpc++ = arg;
+               *fpc++ = (U16)arg;
            }
            if (s < send) {
                linepc = fpc;
@@ -3536,7 +3647,7 @@ S_doparseform(pTHX_ SV *sv)
            arg = (s - base) - 1;
            if (arg) {
                *fpc++ = FF_LITERAL;
-               *fpc++ = arg;
+               *fpc++ = (U16)arg;
            }
 
            base = s - 1;
@@ -3561,7 +3672,7 @@ S_doparseform(pTHX_ SV *sv)
                }
                *fpc++ = s - base;              /* fieldsize for FETCH */
                *fpc++ = FF_DECIMAL;
-                *fpc++ = arg;
+                *fpc++ = (U16)arg;
             }
             else if (*s == '0' && s[1] == '#') {  /* Zero padded decimals */
                 arg = ischop ? 512 : 0;
@@ -3579,7 +3690,7 @@ S_doparseform(pTHX_ SV *sv)
                 }
                 *fpc++ = s - base;                /* fieldsize for FETCH */
                 *fpc++ = FF_0DECIMAL;
-               *fpc++ = arg;
+               *fpc++ = (U16)arg;
            }
            else {
                I32 prespace = 0;
@@ -3608,7 +3719,7 @@ S_doparseform(pTHX_ SV *sv)
                *fpc++ = ischop ? FF_CHECKCHOP : FF_CHECKNL;
 
                if (prespace)
-                   *fpc++ = prespace;
+                   *fpc++ = (U16)prespace;
                *fpc++ = FF_ITEM;
                if (ismore)
                    *fpc++ = FF_MORE;
@@ -3622,14 +3733,15 @@ S_doparseform(pTHX_ SV *sv)
     }
     *fpc++ = FF_END;
 
+    assert (fpc <= fops + maxops); /* ensure our buffer estimate was valid */
     arg = fpc - fops;
     { /* need to jump to the next word */
         int z;
        z = WORD_ALIGN - SvCUR(sv) % WORD_ALIGN;
-       SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U16) + 4);
+       SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U32) + 4);
        s = SvPVX(sv) + SvCUR(sv) + z;
     }
-    Copy(fops, s, arg, U16);
+    Copy(fops, s, arg, U32);
     Safefree(fops);
     sv_magic(sv, Nullsv, PERL_MAGIC_fm, Nullch, 0);
     SvCOMPILED_on(sv);
@@ -3712,7 +3824,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] == '/'))))