Regen Unicode tables to include a warning:
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 052d1c1..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
@@ -448,7 +448,7 @@ Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype)
                   (sv = names[PL_padix]) && sv != &PL_sv_undef)
                continue;
            sv = *av_fetch(PL_comppad, PL_padix, TRUE);
-           if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)))
+           if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)) && !IS_PADGV(sv))
                break;
        }
        retval = PL_padix;
@@ -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,14 +719,18 @@ S_op_clear(pTHX_ OP *o)
     case OP_GV:
     case OP_AELEMFAST:
 #ifdef USE_ITHREADS
-       if (PL_curpad) {
-           SvREFCNT_dec(cGVOPo);
-           PL_curpad[cPADOPo->op_padix] = Nullsv;
+       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;
        }
-       pad_free(cPADOPo->op_padix);
-       cPADOPo->op_padix = 0;
 #else
-       SvREFCNT_dec(cGVOPo);
+       SvREFCNT_dec(cSVOPo->op_sv);
        cSVOPo->op_sv = Nullsv;
 #endif
        break;
@@ -752,25 +757,48 @@ 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;
     }
 
-    if (o->op_targ > 0)
+    if (o->op_targ > 0) {
        pad_free(o->op_targ);
+       o->op_targ = 0;
+    }
 }
 
 STATIC void
 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))
        SvREFCNT_dec(cop->cop_warnings);
 }
@@ -831,12 +859,12 @@ S_scalarboolean(pTHX_ OP *o)
     if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) {
        dTHR;
        if (ckWARN(WARN_SYNTAX)) {
-           line_t oldline = PL_curcop->cop_line;
+           line_t oldline = CopLINE(PL_curcop);
 
            if (PL_copline != NOLINE)
-               PL_curcop->cop_line = PL_copline;
+               CopLINE_set(PL_curcop, PL_copline);
            Perl_warner(aTHX_ WARN_SYNTAX, "Found = in conditional, should be ==");
-           PL_curcop->cop_line = oldline;
+           CopLINE_set(PL_curcop, oldline);
        }
     }
     return scalar(o);
@@ -1298,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;
@@ -2807,8 +2835,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl)
        OP *curop;
        if (pm->op_pmflags & PMf_EVAL) {
            curop = 0;
-           if (PL_curcop->cop_line < PL_multi_end)
-               PL_curcop->cop_line = PL_multi_end;
+           if (CopLINE(PL_curcop) < PL_multi_end)
+               CopLINE_set(PL_curcop, PL_multi_end);
        }
 #ifdef USE_THREADS
        else if (repl->op_type == OP_THREADSV
@@ -2935,6 +2963,7 @@ Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv)
 {
     dTHR;
 #ifdef USE_ITHREADS
+    GvIN_PAD_on(gv);
     return newPADOP(type, flags, SvREFCNT_inc(gv));
 #else
     return newSVOP(type, flags, SvREFCNT_inc(gv));
@@ -3229,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*)((SVOP*)tmpop)->op_sv; /* XXXXXX */
+#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 */
@@ -3282,7 +3317,7 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
     register COP *cop;
 
     NewOp(1101, cop, 1, COP);
-    if (PERLDB_LINE && PL_curcop->cop_line && PL_curstash != PL_debstash) {
+    if (PERLDB_LINE && CopLINE(PL_curcop) && PL_curstash != PL_debstash) {
        cop->op_type = OP_DBSTATE;
        cop->op_ppaddr = PL_ppaddr[ OP_DBSTATE ];
     }
@@ -3311,20 +3346,29 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
 
 
     if (PL_copline == NOLINE)
-        cop->cop_line = PL_curcop->cop_line;
+        CopLINE_set(cop, CopLINE(PL_curcop));
     else {
-       cop->cop_line = PL_copline;
+       CopLINE_set(cop, PL_copline);
         PL_copline = NOLINE;
     }
+#ifdef USE_ITHREADS
+    CopFILE_set(cop, CopFILE(PL_curcop));      /* XXXXX share in a pvtable? */
+#else
     CopFILEGV_set(cop, (GV*)SvREFCNT_inc(CopFILEGV(PL_curcop)));
-    cop->cop_stash = PL_curstash;
+#endif
+    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
        }
     }
 
@@ -3436,14 +3480,14 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
            break;
        }
        if (warnop) {
-           line_t oldline = PL_curcop->cop_line;
-           PL_curcop->cop_line = PL_copline;
+           line_t oldline = CopLINE(PL_curcop);
+           CopLINE_set(PL_curcop, PL_copline);
            Perl_warner(aTHX_ WARN_UNSAFE,
                 "Value of %s%s can be \"0\"; test with defined()",
                 PL_op_desc[warnop],
                 ((warnop == OP_READLINE || warnop == OP_GLOB)
                  ? " construct" : "() operator"));
-           PL_curcop->cop_line = oldline;
+           CopLINE_set(PL_curcop, oldline);
        }
     }
 
@@ -3739,11 +3783,13 @@ Perl_newFOROP(pTHX_ I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *blo
        }
        else if (sv->op_type == OP_PADSV) { /* private variable */
            padoff = sv->op_targ;
+           sv->op_targ = 0;
            op_free(sv);
            sv = Nullop;
        }
        else if (sv->op_type == OP_THREADSV) { /* per-thread variable */
            padoff = sv->op_targ;
+           sv->op_targ = 0;
            iterflags |= OPf_SPECIAL;
            op_free(sv);
            sv = Nullop;
@@ -3898,9 +3944,9 @@ Perl_cv_undef(pTHX_ CV *cv)
     }
 }
 
-#ifdef DEBUG_CLOSURES
+#ifdef DEBUGGING
 STATIC void
-cv_dump(CV *cv)
+S_cv_dump(pTHX_ CV *cv)
 {
     CV *outside = CvOUTSIDE(cv);
     AV* padlist = CvPADLIST(cv);
@@ -3943,7 +3989,7 @@ cv_dump(CV *cv)
                          SvIVX(pname[ix]));
     }
 }
-#endif /* DEBUG_CLOSURES */
+#endif /* DEBUGGING */
 
 STATIC CV *
 S_cv_clone2(pTHX_ CV *proto, CV *outside)
@@ -3980,6 +4026,7 @@ S_cv_clone2(pTHX_ CV *proto, CV *outside)
     MUTEX_INIT(CvMUTEXP(cv));
     CvOWNER(cv)                = 0;
 #endif /* USE_THREADS */
+    CvFILE(cv)         = CvFILE(proto);
     CvGV(cv)           = (GV*)SvREFCNT_inc(CvGV(proto));
     CvSTASH(cv)                = CvSTASH(proto);
     CvROOT(cv)         = CvROOT(proto);
@@ -4038,6 +4085,9 @@ S_cv_clone2(pTHX_ CV *proto, CV *outside)
                PL_curpad[ix] = sv;
            }
        }
+       else if (IS_PADGV(ppad[ix])) {
+           PL_curpad[ix] = SvREFCNT_inc(ppad[ix]);
+       }
        else {
            SV* sv = NEWSV(0,0);
            SvPADTMP_on(sv);
@@ -4242,12 +4292,12 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                                        && HvNAME(GvSTASH(CvGV(cv)))
                                        && strEQ(HvNAME(GvSTASH(CvGV(cv))),
                                                 "autouse"))) {
-               line_t oldline = PL_curcop->cop_line;
-               PL_curcop->cop_line = PL_copline;
+               line_t oldline = CopLINE(PL_curcop);
+               CopLINE_set(PL_curcop, PL_copline);
                Perl_warner(aTHX_ WARN_REDEFINE,
                        const_sv ? "Constant subroutine %s redefined"
                                 : "Subroutine %s redefined", name);
-               PL_curcop->cop_line = oldline;
+               CopLINE_set(PL_curcop, oldline);
            }
            SvREFCNT_dec(cv);
            cv = Nullcv;
@@ -4305,6 +4355,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        }
     }
     CvGV(cv) = (GV*)SvREFCNT_inc(gv);
+    CvFILE(cv) = CopFILE(PL_curcop);
     CvSTASH(cv) = PL_curstash;
 #ifdef USE_THREADS
     CvOWNER(cv) = 0;
@@ -4351,7 +4402,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
            SV *namesv;
 
-           if (SvIMMORTAL(PL_curpad[ix]))
+           if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
                continue;
            /*
             * The only things that a clonable function needs in its
@@ -4375,7 +4426,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        AvFLAGS(av) = AVf_REIFY;
 
        for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
-           if (SvIMMORTAL(PL_curpad[ix]))
+           if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
                continue;
            if (!SvPADMY(PL_curpad[ix]))
                SvPADTMP_on(PL_curpad[ix]);
@@ -4427,8 +4478,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        if (strEQ(s, "BEGIN")) {
            I32 oldscope = PL_scopestack_ix;
            ENTER;
-           SAVESPTR(CopFILEGV(&PL_compiling));
-           SAVEI16(PL_compiling.cop_line);
+           SAVECOPFILE(&PL_compiling);
+           SAVECOPLINE(&PL_compiling);
            save_svref(&PL_rs);
            sv_setsv(PL_rs, PL_nrs);
 
@@ -4476,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 = PL_curcop->cop_line;
-    PL_curcop->cop_line = 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),
@@ -4494,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;
-    PL_curcop->cop_line = oldline;
+    LEAVE;
 }
 
 CV *
@@ -4518,11 +4575,11 @@ Perl_newXS(pTHX_ char *name, XSUBADDR_t subaddr, char *filename)
            if (ckWARN(WARN_REDEFINE) && !(CvGV(cv) && GvSTASH(CvGV(cv))
                            && HvNAME(GvSTASH(CvGV(cv)))
                            && strEQ(HvNAME(GvSTASH(CvGV(cv))), "autouse"))) {
-               line_t oldline = PL_curcop->cop_line;
+               line_t oldline = CopLINE(PL_curcop);
                if (PL_copline != NOLINE)
-                   PL_curcop->cop_line = PL_copline;
+                   CopLINE_set(PL_curcop, PL_copline);
                Perl_warner(aTHX_ WARN_REDEFINE, "Subroutine %s redefined",name);
-               PL_curcop->cop_line = oldline;
+               CopLINE_set(PL_curcop, oldline);
            }
            SvREFCNT_dec(cv);
            cv = 0;
@@ -4547,6 +4604,8 @@ Perl_newXS(pTHX_ char *name, XSUBADDR_t subaddr, char *filename)
     CvOWNER(cv) = 0;
 #endif /* USE_THREADS */
     (void)gv_fetchfile(filename);
+    CvFILE(cv) = filename;     /* NOTE: not copied, as it is expected to be
+                                  an external constant string */
     CvXSUB(cv) = subaddr;
 
     if (name) {
@@ -4606,17 +4665,18 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
     GvMULTI_on(gv);
     if (cv = GvFORM(gv)) {
        if (ckWARN(WARN_REDEFINE)) {
-           line_t oldline = PL_curcop->cop_line;
+           line_t oldline = CopLINE(PL_curcop);
 
-           PL_curcop->cop_line = PL_copline;
+           CopLINE_set(PL_curcop, PL_copline);
            Perl_warner(aTHX_ WARN_REDEFINE, "Format %s redefined",name);
-           PL_curcop->cop_line = oldline;
+           CopLINE_set(PL_curcop, oldline);
        }
        SvREFCNT_dec(cv);
     }
     cv = PL_compcv;
     GvFORM(gv) = cv;
     CvGV(cv) = (GV*)SvREFCNT_inc(gv);
+    CvFILE(cv) = CopFILE(PL_curcop);
 
     for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
        if (!SvPADMY(PL_curpad[ix]) && !SvIMMORTAL(PL_curpad[ix]))
@@ -5046,6 +5106,7 @@ Perl_ck_rvconst(pTHX_ register OP *o)
 #ifdef USE_ITHREADS
            /* XXXXXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */
            kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP);
+           GvIN_PAD_on(gv);
            PL_curpad[kPADOP->op_padix] = SvREFCNT_inc(gv);
 #else
            kid->op_sv = SvREFCNT_inc(gv);
@@ -5062,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)) {
@@ -5073,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;
 }
 
@@ -5515,6 +5583,7 @@ Perl_ck_sassign(pTHX_ OP *o)
                    return o;
            }
            kid->op_targ = kkid->op_targ;
+           kkid->op_targ = 0;
            /* Now we do not need PADSV and SASSIGN. */
            kid->op_sibling = o->op_sibling;    /* NULL */
            cLISTOPo->op_first = NULL;
@@ -6099,11 +6168,13 @@ Perl_peep(pTHX_ register OP *o)
                            && (((LISTOP*)o)->op_first->op_sibling->op_type
                                == OP_PADSV)
                            && (((LISTOP*)o)->op_first->op_sibling->op_targ
-                               == o->op_next->op_targ))) {
+                               == o->op_next->op_targ)))
+                   {
                        goto ignore_optimization;
                    }
                    else {
                        o->op_targ = o->op_next->op_targ;
+                       o->op_next->op_targ = 0;
                        o->op_private |= OPpTARGET_MY;
                    }
                }
@@ -6223,12 +6294,12 @@ Perl_peep(pTHX_ register OP *o)
                        o->op_next->op_sibling->op_type != OP_EXIT &&
                        o->op_next->op_sibling->op_type != OP_WARN &&
                        o->op_next->op_sibling->op_type != OP_DIE) {
-                   line_t oldline = PL_curcop->cop_line;
+                   line_t oldline = CopLINE(PL_curcop);
 
-                   PL_curcop->cop_line = ((COP*)o->op_next)->cop_line;
+                   CopLINE_set(PL_curcop, CopLINE((COP*)o->op_next));
                    Perl_warner(aTHX_ WARN_SYNTAX, "Statement unlikely to be reached");
                    Perl_warner(aTHX_ WARN_SYNTAX, "(Maybe you meant system() when you said exec()?)\n");
-                   PL_curcop->cop_line = oldline;
+                   CopLINE_set(PL_curcop, oldline);
                }
            }
            break;