Update Maintainers.pl for encoding::warnings
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 93bbf21..c6f38fa 100644 (file)
--- a/op.c
+++ b/op.c
@@ -57,7 +57,7 @@ context is, either upward in the syntax tree, or either forward or
 backward in the execution order.  (The bottom-up parser builds that
 part of the execution order it knows about, but if you follow the "next"
 links around, you'll find it's actually a closed loop through the
-top level node.
+top level node.)
 
 Whenever the bottom-up parser gets to a node that supplies context to
 its components, it invokes that portion of the top-down pass that applies
@@ -103,6 +103,7 @@ recursive, but it's recursive on basic blocks, not on tree nodes.
 #include "keywords.h"
 
 #define CALL_PEEP(o) CALL_FPTR(PL_peepp)(aTHX_ o)
+#define CALL_OPFREEHOOK(o) if (PL_opfreehook) CALL_FPTR(PL_opfreehook)(aTHX_ o)
 
 #if defined(PL_OP_SLAB_ALLOC)
 
@@ -399,14 +400,6 @@ Perl_allocmy(pTHX_ const char *const name)
     /* check for duplicate declaration */
     pad_check_dup(name, is_our, (PL_curstash ? PL_curstash : PL_defstash));
 
-    if (PL_parser->in_my_stash && *name != '$') {
-       yyerror(Perl_form(aTHX_
-                   "Can't declare class for non-scalar %s in \"%s\"",
-                    name,
-                    is_our ? "our"
-                           : PL_parser->in_my == KEY_state ? "state" : "my"));
-    }
-
     /* allocate a spare slot and store the name in that slot */
 
     off = pad_add_name(name,
@@ -490,6 +483,11 @@ Perl_op_free(pTHX_ OP *o)
        }
     }
 
+    /* Call the op_free hook if it has been set. Do it now so that it's called
+     * at the right time for refcounted ops, but still before all of the kids
+     * are freed. */
+    CALL_OPFREEHOOK(o);
+
     if (o->op_flags & OPf_KIDS) {
         register OP *kid, *nextkid;
        for (kid = cUNOPo->op_first; kid; kid = nextkid) {
@@ -2772,7 +2770,7 @@ Perl_token_getmad(pTHX_ TOKEN* tk, OP* o, char slot)
     /* faked up qw list? */
     if (slot == '(' &&
        tm->mad_type == MAD_SV &&
-       SvPVX((const SV *)tm->mad_val)[0] == 'q')
+       SvPVX((SV *)tm->mad_val)[0] == 'q')
            slot = 'x';
 
     if (o) {
@@ -2929,7 +2927,7 @@ Perl_newMADsv(pTHX_ char key, SV* sv)
 }
 
 MADPROP *
-Perl_newMADPROP(pTHX_ char key, char type, const void* val, I32 vlen)
+Perl_newMADPROP(pTHX_ char key, char type, void* val, I32 vlen)
 {
     MADPROP *mp;
     Newxz(mp, 1, MADPROP);
@@ -3347,6 +3345,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
        SvREFCNT_dec(PAD_SVl(cPADOPo->op_padix));
        PAD_SETSV(cPADOPo->op_padix, swash);
        SvPADTMP_on(swash);
+       SvREADONLY_on(swash);
 #else
        cSVOPo->op_sv = swash;
 #endif
@@ -3865,7 +3864,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
            SV *meth;
 
            if (version->op_type != OP_CONST || !SvNIOKp(vesv))
-               Perl_croak(aTHX_ "Version number must be constant number");
+               Perl_croak(aTHX_ "Version number must be a constant number");
 
            /* Make copy of idop so we don't free it twice */
            pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)idop)->op_sv));
@@ -3963,7 +3962,11 @@ PERL_LOADMOD_DENY, PERL_LOADMOD_NOIMPORT, or PERL_LOADMOD_IMPORT_OPS
 (or 0 for no flags). ver, if specified, provides version semantics
 similar to C<use Foo::Bar VERSION>.  The optional trailing SV*
 arguments can be used to specify arguments to the module's import()
-method, similar to C<use Foo::Bar VERSION LIST>.
+method, similar to C<use Foo::Bar VERSION LIST>.  They must be
+terminated with a final NULL pointer.  Note that this list can only
+be omitted when the PERL_LOADMOD_NOIMPORT flag has been used.
+Otherwise at least a single NULL pointer to designate the default
+import list is required.
 
 =cut */
 
@@ -4333,7 +4336,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                      ((LISTOP*)right)->op_last->op_type == OP_CONST)
                    {
                        SV *sv = ((SVOP*)((LISTOP*)right)->op_last)->op_sv;
-                       if (SvIVX(sv) == 0)
+                       if (SvIOK(sv) && SvIVX(sv) == 0)
                            sv_setiv(sv, PL_modcount+1);
                    }
                }
@@ -4553,6 +4556,8 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
                return newop;
            }
            op_free(first);
+           if (other->op_type == OP_LEAVE)
+               other = newUNOP(OP_NULL, OPf_SPECIAL, other);
            return other;
        }
        else {
@@ -4690,6 +4695,8 @@ Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop, OP *falseop)
            op_free(first);
            op_free(dead);
        }
+       if (live->op_type == OP_LEAVE)
+           live = newUNOP(OP_NULL, OPf_SPECIAL, live);
        return live;
     }
     NewOp(1101, logop, 1, LOGOP);
@@ -5521,7 +5528,6 @@ CV *
 Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
 {
     dVAR;
-    const char *aname;
     GV *gv;
     const char *ps;
     STRLEN ps_len;
@@ -5537,6 +5543,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
           || PL_madskills)
        ? GV_ADDMULTI : GV_ADDMULTI | GV_NOINIT;
     const char * const name = o ? SvPV_nolen_const(cSVOPo->op_sv) : NULL;
+    bool has_name;
 
     if (proto) {
        assert(proto->op_type == OP_CONST);
@@ -5545,20 +5552,23 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
     else
        ps = NULL;
 
-    if (!name && PERLDB_NAMEANON && CopLINE(PL_curcop)) {
+    if (name) {
+       gv = gv_fetchsv(cSVOPo->op_sv, gv_fetch_flags, SVt_PVCV);
+       has_name = TRUE;
+    } else if (PERLDB_NAMEANON && CopLINE(PL_curcop)) {
        SV * const sv = sv_newmortal();
        Perl_sv_setpvf(aTHX_ sv, "%s[%s:%"IVdf"]",
                       PL_curstash ? "__ANON__" : "__ANON__::__ANON__",
                       CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
-       aname = SvPVX_const(sv);
+       gv = gv_fetchsv(sv, gv_fetch_flags, SVt_PVCV);
+       has_name = TRUE;
+    } else if (PL_curstash) {
+       gv = gv_fetchpvs("__ANON__", gv_fetch_flags, SVt_PVCV);
+       has_name = FALSE;
+    } else {
+       gv = gv_fetchpvs("__ANON__::__ANON__", gv_fetch_flags, SVt_PVCV);
+       has_name = FALSE;
     }
-    else
-       aname = NULL;
-
-    gv = name ? gv_fetchsv(cSVOPo->op_sv, gv_fetch_flags, SVt_PVCV)
-       : gv_fetchpv(aname ? aname
-                    : (PL_curstash ? "__ANON__" : "__ANON__::__ANON__"),
-                    gv_fetch_flags, SVt_PVCV);
 
     if (!PL_madskills) {
        if (o)
@@ -5682,69 +5692,34 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        PL_compcv = NULL;
        goto done;
     }
-    if (attrs) {
-       HV *stash;
-       SV *rcv;
-
-       /* Need to do a C<use attributes $stash_of_cv,\&cv,@attrs>
-        * before we clobber PL_compcv.
-        */
-       if (cv && (!block
+    if (cv) {                          /* must reuse cv if autoloaded */
+       /* transfer PL_compcv to cv */
+       if (block
 #ifdef PERL_MAD
-                   || block->op_type == OP_NULL
+                  && block->op_type != OP_NULL
 #endif
-                   )) {
-           rcv = MUTABLE_SV(cv);
-           /* Might have had built-in attributes applied -- propagate them. */
-           CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS);
-           if (CvGV(cv) && GvSTASH(CvGV(cv)))
-               stash = GvSTASH(CvGV(cv));
-           else if (CvSTASH(cv))
-               stash = CvSTASH(cv);
-           else
-               stash = PL_curstash;
+       ) {
+           cv_undef(cv);
+           CvFLAGS(cv) = CvFLAGS(PL_compcv);
+           if (!CvWEAKOUTSIDE(cv))
+               SvREFCNT_dec(CvOUTSIDE(cv));
+           CvOUTSIDE(cv) = CvOUTSIDE(PL_compcv);
+           CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(PL_compcv);
+           CvOUTSIDE(PL_compcv) = 0;
+           CvPADLIST(cv) = CvPADLIST(PL_compcv);
+           CvPADLIST(PL_compcv) = 0;
+           /* inner references to PL_compcv must be fixed up ... */
+           pad_fixup_inner_anons(CvPADLIST(cv), PL_compcv, cv);
+           if (PERLDB_INTER)/* Advice debugger on the new sub. */
+             ++PL_sub_generation;
        }
        else {
-           /* possibly about to re-define existing subr -- ignore old cv */
-           rcv = MUTABLE_SV(PL_compcv);
-           if (name && GvSTASH(gv))
-               stash = GvSTASH(gv);
-           else
-               stash = PL_curstash;
-       }
-       apply_attrs(stash, rcv, attrs, FALSE);
-    }
-    if (cv) {                          /* must reuse cv if autoloaded */
-       if (
-#ifdef PERL_MAD
-           (
-#endif
-            !block
-#ifdef PERL_MAD
-            || block->op_type == OP_NULL) && !PL_madskills
-#endif
-            ) {
-           /* got here with just attrs -- work done, so bug out */
-           SAVEFREESV(PL_compcv);
-           goto done;
+           /* Might have had built-in attributes applied -- propagate them. */
+           CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS);
        }
-       /* transfer PL_compcv to cv */
-       cv_undef(cv);
-       CvFLAGS(cv) = CvFLAGS(PL_compcv);
-       if (!CvWEAKOUTSIDE(cv))
-           SvREFCNT_dec(CvOUTSIDE(cv));
-       CvOUTSIDE(cv) = CvOUTSIDE(PL_compcv);
-       CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(PL_compcv);
-       CvOUTSIDE(PL_compcv) = 0;
-       CvPADLIST(cv) = CvPADLIST(PL_compcv);
-       CvPADLIST(PL_compcv) = 0;
-       /* inner references to PL_compcv must be fixed up ... */
-       pad_fixup_inner_anons(CvPADLIST(cv), PL_compcv, cv);
        /* ... before we throw it away */
        SvREFCNT_dec(PL_compcv);
        PL_compcv = cv;
-       if (PERLDB_INTER)/* Advice debugger on the new sub. */
-         ++PL_sub_generation;
     }
     else {
        cv = PL_compcv;
@@ -5760,9 +5735,16 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
             mro_method_changed_in(GvSTASH(gv)); /* sub Foo::bar { (shift)+1 } */
        }
     }
-    CvGV(cv) = gv;
-    CvFILE_set_from_cop(cv, PL_curcop);
-    CvSTASH(cv) = PL_curstash;
+    if (!CvGV(cv)) {
+       CvGV(cv) = gv;
+       CvFILE_set_from_cop(cv, PL_curcop);
+       CvSTASH(cv) = PL_curstash;
+    }
+    if (attrs) {
+       /* Need to do a C<use attributes $stash_of_cv,\&cv,@attrs>. */
+       HV *stash = name && GvSTASH(CvGV(cv)) ? GvSTASH(CvGV(cv)) : PL_curstash;
+       apply_attrs(stash, MUTABLE_SV(cv), attrs, FALSE);
+    }
 
     if (ps)
        sv_setpvn(MUTABLE_SV(cv), ps, ps_len);
@@ -5832,7 +5814,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
            CvCONST_on(cv);
     }
 
-    if (name || aname) {
+    if (has_name) {
        if (PERLDB_SUBLINE && PL_curstash != PL_debstash) {
            SV * const sv = newSV(0);
            SV * const tmpstr = sv_newmortal();
@@ -6464,6 +6446,8 @@ Perl_ck_delete(pTHX_ OP *o)
            Perl_croak(aTHX_ "%s argument is not a HASH or ARRAY element or slice",
                  OP_DESC(o));
        }
+       if (kid->op_private & OPpLVAL_INTRO)
+           o->op_private |= OPpLVAL_INTRO;
        op_null(kid);
     }
     return o;
@@ -7690,20 +7674,15 @@ Perl_ck_shift(pTHX_ OP *o)
     PERL_ARGS_ASSERT_CK_SHIFT;
 
     if (!(o->op_flags & OPf_KIDS)) {
-       OP *argop;
-       /* FIXME - this can be refactored to reduce code in #ifdefs  */
-#ifdef PERL_MAD
-       OP * const oldo = o;
-#else
-       op_free(o);
-#endif
-       argop = newUNOP(OP_RV2AV, 0,
+       OP *argop = newUNOP(OP_RV2AV, 0,
            scalar(newGVOP(OP_GV, 0, CvUNIQUE(PL_compcv) ? PL_argvgv : PL_defgv)));
 #ifdef PERL_MAD
+       OP * const oldo = o;
        o = newUNOP(type, 0, scalar(argop));
        op_getmad(oldo,o,'O');
        return o;
 #else
+       op_free(o);
        return newUNOP(type, 0, scalar(argop));
 #endif
     }
@@ -8969,6 +8948,7 @@ const_sv_xsub(pTHX_ CV* cv)
     if (items != 0) {
        NOOP;
 #if 0
+       /* diag_listed_as: SKIPME */
         Perl_croak(aTHX_ "usage: %s::%s()",
                    HvNAME_get(GvSTASH(CvGV(cv))), GvNAME(CvGV(cv)));
 #endif