Regen Unicode tables to include a warning:
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 7e8d32e..282027a 100644 (file)
--- a/op.c
+++ b/op.c
@@ -26,7 +26,7 @@
 #define OP_REFCNT_LOCK         NOOP
 #define OP_REFCNT_UNLOCK       NOOP
 #define OpREFCNT_set(o,n)      NOOP
-#define OpREFCNT_dec(o)                0
+#define OpREFCNT_dec(o)                ((o)->op_targ--)
 
 #ifdef PL_OP_SLAB_ALLOC 
 #define SLAB_SIZE 8192
@@ -475,13 +475,13 @@ Perl_pad_sv(pTHX_ PADOFFSET po)
     dTHR;
 #ifdef USE_THREADS
     DEBUG_X(PerlIO_printf(Perl_debug_log,
-                         "0x%"UVxf" Pad 0x%"UVxf" sv %d\n",
-                         PTR2UV(thr), PTR2UV(PL_curpad), po));
+                         "0x%"UVxf" Pad 0x%"UVxf" sv %"IVdf"\n",
+                         PTR2UV(thr), PTR2UV(PL_curpad), (IV)po));
 #else
     if (!po)
        Perl_croak(aTHX_ "panic: pad_sv po");
-    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" sv %d\n",
-                         PTR2UV(PL_curpad), po));
+    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" sv %"IVdf"\n",
+                         PTR2UV(PL_curpad), (IV)po));
 #endif /* USE_THREADS */
     return PL_curpad[po];              /* eventually we'll turn this into a macro */
 }
@@ -498,11 +498,11 @@ Perl_pad_free(pTHX_ PADOFFSET po)
        Perl_croak(aTHX_ "panic: pad_free po");
 #ifdef USE_THREADS
     DEBUG_X(PerlIO_printf(Perl_debug_log,
-                         "0x%"UVxf" Pad 0x%"UVxf" free %d\n",
-                         PTR2UV(thr), PTR2UV(PL_curpad), po));
+                         "0x%"UVxf" Pad 0x%"UVxf" free %"IVd"\n",
+                         PTR2UV(thr), PTR2UV(PL_curpad), (IV)po));
 #else
-    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" free %d\n",
-                         PTR2UV(PL_curpad), po));
+    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" free %"IVdf"\n",
+                         PTR2UV(PL_curpad), (IV)po));
 #endif /* USE_THREADS */
     if (PL_curpad[po] && PL_curpad[po] != &PL_sv_undef)
        SvPADTMP_off(PL_curpad[po]);
@@ -520,11 +520,11 @@ Perl_pad_swipe(pTHX_ PADOFFSET po)
        Perl_croak(aTHX_ "panic: pad_swipe po");
 #ifdef USE_THREADS
     DEBUG_X(PerlIO_printf(Perl_debug_log,
-                         "0x%"UVxf" Pad 0x%"UVxf" swipe %d\n",
-                         PTR2UV(thr), PTR2UV(PL_curpad), po));
+                         "0x%"UVxf" Pad 0x%"UVxf" swipe %"IVdf"\n",
+                         PTR2UV(thr), PTR2UV(PL_curpad), (IV)po));
 #else
-    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" swipe %d\n",
-                         PTR2UV(PL_curpad), po));
+    DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" swipe %"IVdf"\n",
+                         PTR2UV(PL_curpad), (IV)po));
 #endif /* USE_THREADS */
     SvPADTMP_off(PL_curpad[po]);
     PL_curpad[po] = NEWSV(1107,0);
@@ -659,6 +659,7 @@ Perl_op_free(pTHX_ OP *o)
                OP_REFCNT_UNLOCK;
                return;
            }
+           o->op_targ = 0;             /* XXXXXX */
            OP_REFCNT_UNLOCK;
            break;
        default:
@@ -718,16 +719,18 @@ S_op_clear(pTHX_ OP *o)
     case OP_GV:
     case OP_AELEMFAST:
 #ifdef USE_ITHREADS
-       if (PL_curpad) {
-           GV *gv = cGVOPo;
-           pad_swipe(cPADOPo->op_padix);
-           /* No GvIN_PAD_off(gv) here, because other references may still
-            * exist on the pad */
-           SvREFCNT_dec(gv);
-       }
-       cPADOPo->op_padix = 0;
+       if (cPADOPo->op_padix > 0) {
+           if (PL_curpad) {
+               GV *gv = cGVOPo;
+               pad_swipe(cPADOPo->op_padix);
+               /* No GvIN_PAD_off(gv) here, because other references may still
+                * exist on the pad */
+               SvREFCNT_dec(gv);
+           }
+           cPADOPo->op_padix = 0;
+       }
 #else
-       SvREFCNT_dec(cGVOPo);
+       SvREFCNT_dec(cSVOPo->op_sv);
        cSVOPo->op_sv = Nullsv;
 #endif
        break;
@@ -754,11 +757,26 @@ S_op_clear(pTHX_ OP *o)
        break;
     case OP_SUBST:
        op_free(cPMOPo->op_pmreplroot);
-       cPMOPo->op_pmreplroot = Nullop;
-       /* FALL THROUGH */
+       goto clear_pmop;
     case OP_PUSHRE:
+#ifdef USE_ITHREADS
+       if ((PADOFFSET)cPMOPo->op_pmreplroot) {
+           if (PL_curpad) {
+               GV *gv = (GV*)PL_curpad[(PADOFFSET)cPMOPo->op_pmreplroot];
+               pad_swipe((PADOFFSET)cPMOPo->op_pmreplroot);
+               /* No GvIN_PAD_off(gv) here, because other references may still
+                * exist on the pad */
+               SvREFCNT_dec(gv);
+           }
+       }
+#else
+       SvREFCNT_dec((SV*)cPMOPo->op_pmreplroot);
+#endif
+       /* FALL THROUGH */
     case OP_MATCH:
     case OP_QR:
+clear_pmop:
+       cPMOPo->op_pmreplroot = Nullop;
        ReREFCNT_dec(cPMOPo->op_pmregexp);
        cPMOPo->op_pmregexp = (REGEXP*)NULL;
        break;
@@ -776,7 +794,9 @@ S_cop_free(pTHX_ COP* cop)
     Safefree(cop->cop_label);
 #ifdef USE_ITHREADS
     Safefree(CopFILE(cop));            /* XXXXX share in a pvtable? */
+    Safefree(CopSTASHPV(cop));         /* XXXXX share in a pvtable? */
 #else
+    /* NOTE: COP.cop_stash is not refcounted */
     SvREFCNT_dec(CopFILEGV(cop));
 #endif
     if (! specialWARN(cop->cop_warnings))
@@ -1306,7 +1326,7 @@ Perl_mod(pTHX_ OP *o, I32 type)
        }
        else {                          /* lvalue subroutine call */
            o->op_private |= OPpLVAL_INTRO;
-           if (type == OP_GREPSTART || type == OP_ENTERSUB) {
+           if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN) {
                /* Backward compatibility mode: */
                o->op_private |= OPpENTERSUB_INARGS;
                break;
@@ -3238,7 +3258,13 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                {
                    tmpop = ((UNOP*)left)->op_first;
                    if (tmpop->op_type == OP_GV && !pm->op_pmreplroot) {
-                       pm->op_pmreplroot = (OP*)cGVOPx(tmpop);
+#ifdef USE_ITHREADS
+                       pm->op_pmreplroot = (OP*)cPADOPx(tmpop)->op_padix;
+                       cPADOPx(tmpop)->op_padix = 0;   /* steal it */
+#else
+                       pm->op_pmreplroot = (OP*)cSVOPx(tmpop)->op_sv;
+                       cSVOPx(tmpop)->op_sv = Nullsv;  /* steal it */
+#endif
                        pm->op_pmflags |= PMf_ONCE;
                        tmpop = cUNOPo->op_first;       /* to list (nulled) */
                        tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
@@ -3330,14 +3356,19 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
 #else
     CopFILEGV_set(cop, (GV*)SvREFCNT_inc(CopFILEGV(PL_curcop)));
 #endif
-    cop->cop_stash = PL_curstash;
+    CopSTASH_set(cop, PL_curstash);
 
     if (PERLDB_LINE && PL_curstash != PL_debstash) {
        SV **svp = av_fetch(CopFILEAV(PL_curcop), (I32)CopLINE(cop), FALSE);
        if (svp && *svp != &PL_sv_undef && !SvIOK(*svp)) {
            (void)SvIOK_on(*svp);
            SvIVX(*svp) = 1;
+#ifndef USE_ITHREADS
+           /* XXX This nameless kludge interferes with cloning SVs. :-(
+            * What's more, it seems entirely redundant when considering
+            * PL_DBsingle exists to do the same thing */
            SvSTASH(*svp) = (HV*)cop;
+#endif
        }
     }
 
@@ -4496,15 +4527,24 @@ void
 Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv)
 {
     dTHR;
-    U32 oldhints = PL_hints;
-    HV *old_cop_stash = PL_curcop->cop_stash;
-    HV *old_curstash = PL_curstash;
-    line_t oldline = CopLINE(PL_curcop);
-    CopLINE_set(PL_curcop, PL_copline);
 
+    ENTER;
+    SAVECOPLINE(PL_curcop);
+    SAVEHINTS();
+
+    CopLINE_set(PL_curcop, PL_copline);
     PL_hints &= ~HINT_BLOCK_SCOPE;
-    if(stash)
-       PL_curstash = PL_curcop->cop_stash = stash;
+
+    if (stash) {
+       SAVESPTR(PL_curstash);
+       SAVECOPSTASH(PL_curcop);
+       PL_curstash = stash;
+#ifdef USE_ITHREADS
+       CopSTASHPV(PL_curcop) = stash ? HvNAME(stash) : Nullch;
+#else
+       CopSTASH(PL_curcop) = stash;
+#endif
+    }
 
     newATTRSUB(
        start_subparse(FALSE, 0),
@@ -4514,10 +4554,7 @@ Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv)
        newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
     );
 
-    PL_hints = oldhints;
-    PL_curcop->cop_stash = old_cop_stash;
-    PL_curstash = old_curstash;
-    CopLINE_set(PL_curcop, oldline);
+    LEAVE;
 }
 
 CV *
@@ -5086,10 +5123,10 @@ Perl_ck_ftst(pTHX_ OP *o)
     dTHR;
     I32 type = o->op_type;
 
-    if (o->op_flags & OPf_REF)
-       return o;
-
-    if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) {
+    if (o->op_flags & OPf_REF) {
+       /* nothing */
+    }
+    else if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) {
        SVOP *kid = (SVOP*)cUNOPo->op_first;
 
        if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
@@ -5097,17 +5134,24 @@ Perl_ck_ftst(pTHX_ OP *o)
            OP *newop = newGVOP(type, OPf_REF,
                gv_fetchpv(SvPVx(kid->op_sv, n_a), TRUE, SVt_PVIO));
            op_free(o);
-           return newop;
+           o = newop;
        }
     }
     else {
        op_free(o);
        if (type == OP_FTTTY)
-           return newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE,
+           o =  newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE,
                                SVt_PVIO));
        else
-           return newUNOP(type, 0, newDEFSVOP());
+           o = newUNOP(type, 0, newDEFSVOP());
+    }
+#ifdef USE_LOCALE
+    if (type == OP_FTTEXT || type == OP_FTBINARY) {
+       o->op_private = 0;
+       if (PL_hints & HINT_LOCALE)
+           o->op_private |= OPpLOCALE;
     }
+#endif
     return o;
 }