delete unused vars PL_av_fetch_sv, PL_hv_fetch_sv
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index d623f2b..ba5e200 100644 (file)
--- a/op.c
+++ b/op.c
@@ -352,7 +352,7 @@ Perl_allocmy(pTHX_ const char *const name)
 {
     dVAR;
     PADOFFSET off;
-    const bool is_our = (PL_in_my == KEY_our);
+    const bool is_our = (PL_parser->in_my == KEY_our);
 
     /* complain about "my $<special_var>" etc etc */
     if (*name &&
@@ -373,24 +373,25 @@ 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_in_my_stash && *name != '$') {
+    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_in_my == KEY_state ? "state" : "my"));
+                    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,
-                   PL_in_my_stash,
+                   PL_parser->in_my_stash,
                    (is_our
                        /* $_ is always in main::, even with our */
                        ? (PL_curstash && !strEQ(name,"$_") ? PL_curstash : PL_defstash)
                        : NULL
                    ),
                    0, /*  not fake */
-                   PL_in_my == KEY_state
+                   PL_parser->in_my == KEY_state
     );
     return off;
 }
@@ -782,8 +783,8 @@ S_scalarboolean(pTHX_ OP *o)
        if (ckWARN(WARN_SYNTAX)) {
            const line_t oldline = CopLINE(PL_curcop);
 
-           if (PL_copline != NOLINE)
-               CopLINE_set(PL_curcop, PL_copline);
+           if (PL_parser && PL_parser->copline != NOLINE)
+               CopLINE_set(PL_curcop, PL_parser->copline);
            Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Found = in conditional, should be ==");
            CopLINE_set(PL_curcop, oldline);
        }
@@ -1818,7 +1819,6 @@ S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
 
     /* fake up C<use attributes $pkg,$rv,@attrs> */
     ENTER;             /* need to protect against side-effects of 'use' */
-    SAVEI8(PL_expect);
     stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
 
 #define ATTRSMODULE "attributes"
@@ -1970,11 +1970,13 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp)
        if (cUNOPo->op_first->op_type != OP_GV) { /* MJD 20011224 */
            yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
                        OP_DESC(o),
-                       PL_in_my == KEY_our ? "our" : PL_in_my == KEY_state ? "state" : "my"));
+                       PL_parser->in_my == KEY_our
+                           ? "our"
+                           : PL_parser->in_my == KEY_state ? "state" : "my"));
        } else if (attrs) {
            GV * const gv = cGVOPx_gv(cUNOPo->op_first);
-           PL_in_my = FALSE;
-           PL_in_my_stash = NULL;
+           PL_parser->in_my = FALSE;
+           PL_parser->in_my_stash = NULL;
            apply_attrs(GvSTASH(gv),
                        (type == OP_RV2SV ? GvSV(gv) :
                         type == OP_RV2AV ? (SV*)GvAV(gv) :
@@ -1991,14 +1993,16 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp)
     {
        yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
                          OP_DESC(o),
-                         PL_in_my == KEY_our ? "our" : PL_in_my == KEY_state ? "state" : "my"));
+                         PL_parser->in_my == KEY_our
+                           ? "our"
+                           : PL_parser->in_my == KEY_state ? "state" : "my"));
        return o;
     }
     else if (attrs && type != OP_PUSHMARK) {
        HV *stash;
 
-       PL_in_my = FALSE;
-       PL_in_my_stash = NULL;
+       PL_parser->in_my = FALSE;
+       PL_parser->in_my_stash = NULL;
 
        /* check for C<my Dog $spot> when deciding package */
        stash = PAD_COMPNAME_TYPE(o->op_targ);
@@ -2008,7 +2012,7 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp)
     }
     o->op_flags |= OPf_MOD;
     o->op_private |= OPpLVAL_INTRO;
-    if (PL_in_my == KEY_state)
+    if (PL_parser->in_my == KEY_state)
        o->op_private |= OPpPAD_STATE;
     return o;
 }
@@ -2042,8 +2046,8 @@ Perl_my_attrs(pTHX_ OP *o, OP *attrs)
        else
            o = append_list(OP_LIST, (LISTOP*)o, (LISTOP*)rops);
     }
-    PL_in_my = FALSE;
-    PL_in_my_stash = NULL;
+    PL_parser->in_my = FALSE;
+    PL_parser->in_my_stash = NULL;
     return o;
 }
 
@@ -2261,10 +2265,11 @@ Perl_localize(pTHX_ OP *o, I32 lex)
        NOOP;
 #endif
     else {
-       if ( PL_bufptr > PL_oldbufptr && PL_bufptr[-1] == ','
+       if ( PL_parser->bufptr > PL_parser->oldbufptr
+           && PL_parser->bufptr[-1] == ','
            && ckWARN(WARN_PARENTHESIS))
        {
-           char *s = PL_bufptr;
+           char *s = PL_parser->bufptr;
            bool sigil = FALSE;
 
            /* some heuristics to detect a potential error */
@@ -2287,8 +2292,13 @@ Perl_localize(pTHX_ OP *o, I32 lex)
            if (sigil && (*s == ';' || *s == '=')) {
                Perl_warner(aTHX_ packWARN(WARN_PARENTHESIS),
                                "Parentheses missing around \"%s\" list",
-                               lex ? (PL_in_my == KEY_our ? "our" : PL_in_my == KEY_state ? "state" : "my")
-                               : "local");
+                               lex
+                                   ? (PL_parser->in_my == KEY_our
+                                       ? "our"
+                                       : PL_parser->in_my == KEY_state
+                                           ? "state"
+                                           : "my")
+                                   : "local");
            }
        }
     }
@@ -2296,8 +2306,8 @@ Perl_localize(pTHX_ OP *o, I32 lex)
        o = my(o);
     else
        o = mod(o, OP_NULL);            /* a bit kludgey */
-    PL_in_my = FALSE;
-    PL_in_my_stash = NULL;
+    PL_parser->in_my = FALSE;
+    PL_parser->in_my_stash = NULL;
     return o;
 }
 
@@ -2818,7 +2828,7 @@ Perl_mad_free(pTHX_ MADPROP* mp)
        return;
     if (mp->mad_next)
        mad_free(mp->mad_next);
-/*    if (PL_lex_state != LEX_NOTPARSING && mp->mad_vlen)
+/*    if (PL_parser && PL_parser->lex_state != LEX_NOTPARSING && mp->mad_vlen)
        PerlIO_printf(PerlIO_stderr(), "DESTROYING '%c'=<%s>\n", mp->mad_key & 255, mp->mad_val); */
     switch (mp->mad_type) {
     case MAD_NULL:
@@ -3650,15 +3660,11 @@ Perl_package(pTHX_ OP *o)
 
     PL_curstash = gv_stashsv(sv, GV_ADD);
 
-    /* In case mg.c:Perl_magic_setisa faked
-       this package earlier, we clear the fake flag */
-    HvMROMETA(PL_curstash)->fake = 0;
-
     sv_setsv(PL_curstname, sv);
 
     PL_hints |= HINT_BLOCK_SCOPE;
-    PL_copline = NOLINE;
-    PL_expect = XSTATE;
+    PL_parser->copline = NOLINE;
+    PL_parser->expect = XSTATE;
 
 #ifndef PERL_MAD
     op_free(o);
@@ -3782,8 +3788,8 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
      */
 
     PL_hints |= HINT_BLOCK_SCOPE;
-    PL_copline = NOLINE;
-    PL_expect = XSTATE;
+    PL_parser->copline = NOLINE;
+    PL_parser->expect = XSTATE;
     PL_cop_seqmax++; /* Purely for B::*'s benefit */
 
 #ifdef PERL_MAD
@@ -3861,17 +3867,19 @@ Perl_vload_module(pTHX_ U32 flags, SV *name, SV *ver, va_list *args)
            sv = va_arg(*args, SV*);
        }
     }
-    {
-       const line_t ocopline = PL_copline;
-       COP * const ocurcop = PL_curcop;
-       const U8 oexpect = PL_expect;
 
-       utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
-               veop, modname, imop);
-       PL_expect = oexpect;
-       PL_copline = ocopline;
-       PL_curcop = ocurcop;
-    }
+    /* utilize() fakes up a BEGIN { require ..; import ... }, so make sure
+     * that it has a PL_parser to play with while doing that, and also
+     * that it doesn't mess with any existing parser, by creating a tmp
+     * new parser with lex_start(). This won't actually be used for much,
+     * since pp_require() will create another parser for the real work. */
+
+    ENTER;
+    SAVEVPTR(PL_curcop);
+    lex_start(NULL, NULL, FALSE);
+    utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
+           veop, modname, imop);
+    LEAVE;
 }
 
 OP *
@@ -4065,7 +4073,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                o->op_private |= OPpASSIGN_COMMON;
        }
 
-       if (right && right->op_type == OP_SPLIT) {
+       if (right && right->op_type == OP_SPLIT && !PL_madskills) {
            OP* tmpop = ((LISTOP*)right)->op_first;
            if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
                PMOP * const pm = (PMOP*)tmpop;
@@ -4095,11 +4103,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                        tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
                        tmpop->op_sibling = NULL;       /* don't free split */
                        right->op_next = tmpop->op_next;  /* fix starting loc */
-#ifdef PERL_MAD
-                       op_getmad(o,right,'R');         /* blow off assign */
-#else
                        op_free(o);                     /* blow off assign */
-#endif
                        right->op_flags &= ~OPf_WANT;
                                /* "I don't know and I don't care." */
                        return right;
@@ -4180,11 +4184,12 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
        HINTS_REFCNT_UNLOCK;
     }
 
-    if (PL_copline == NOLINE)
+    if (PL_parser && PL_parser->copline == NOLINE)
         CopLINE_set(cop, CopLINE(PL_curcop));
     else {
-       CopLINE_set(cop, PL_copline);
-        PL_copline = NOLINE;
+       CopLINE_set(cop, PL_parser->copline);
+       if (PL_parser)
+           PL_parser->copline = NOLINE;
     }
 #ifdef USE_ITHREADS
     CopFILE_set(cop, CopFILE(PL_curcop));      /* XXX share in a pvtable? */
@@ -4231,7 +4236,8 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
     /* optimize "!a && b" to "a || b", and "!a || b" to "a && b" */
     if (first->op_type == OP_NOT
        && (first->op_flags & OPf_SPECIAL)
-       && (first->op_flags & OPf_KIDS)) {
+       && (first->op_flags & OPf_KIDS)
+       && !PL_madskills) {
        if (type == OP_AND || type == OP_OR) {
            if (type == OP_AND)
                type = OP_OR;
@@ -4242,11 +4248,7 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
            if (o->op_next)
                first->op_next = o->op_next;
            cUNOPo->op_first = NULL;
-#ifdef PERL_MAD
-           op_getmad(o,first,'O');
-#else
            op_free(o);
-#endif
        }
     }
     if (first->op_type == OP_CONST) {
@@ -4330,7 +4332,7 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
        }
        if (warnop) {
            const line_t oldline = CopLINE(PL_curcop);
-           CopLINE_set(PL_curcop, PL_copline);
+           CopLINE_set(PL_curcop, PL_parser->copline);
            Perl_warner(aTHX_ packWARN(WARN_MISC),
                 "Value of %s%s can be \"0\"; test with defined()",
                 PL_op_desc[warnop],
@@ -4599,7 +4601,7 @@ whileline, OP *expr, OP *block, OP *cont, I32 has_my)
     redo = LINKLIST(listop);
 
     if (expr) {
-       PL_copline = (line_t)whileline;
+       PL_parser->copline = (line_t)whileline;
        scalar(listop);
        o = new_logop(OP_AND, 0, &expr, &listop);
        if (o == expr && o->op_type == OP_CONST && !SvTRUE(cSVOPo->op_sv)) {
@@ -4758,7 +4760,7 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
     wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont, 0);
     if (madsv)
        op_getmad(madsv, (OP*)loop, 'v');
-    PL_copline = forline;
+    PL_parser->copline = forline;
     return newSTATEOP(0, label, wop);
 }
 
@@ -5322,8 +5324,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                        && (!const_sv || sv_cmp(cv_const_sv(cv), const_sv))))
                {
                    const line_t oldline = CopLINE(PL_curcop);
-                   if (PL_copline != NOLINE)
-                       CopLINE_set(PL_curcop, PL_copline);
+                   if (PL_parser && PL_parser->copline != NOLINE)
+                       CopLINE_set(PL_curcop, PL_parser->copline);
                    Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
                        CvCONST(cv) ? "Constant subroutine %s redefined"
                                    : "Subroutine %s redefined", name);
@@ -5543,7 +5545,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
     }
 
   done:
-    PL_copline = NOLINE;
+    if (PL_parser)
+       PL_parser->copline = NOLINE;
     LEAVE_SCOPE(floor);
     return cv;
 }
@@ -5639,7 +5642,7 @@ Perl_newCONSTSUB(pTHX_ HV *stash, const char *name, SV *sv)
     ENTER;
 
     SAVECOPLINE(PL_curcop);
-    CopLINE_set(PL_curcop, PL_copline);
+    CopLINE_set(PL_curcop, PL_parser ? PL_parser->copline : NOLINE);
 
     SAVEHINTS();
     PL_hints &= ~HINT_BLOCK_SCOPE;
@@ -5752,8 +5755,8 @@ Perl_newXS(pTHX_ const char *name, XSUBADDR_t subaddr, const char *filename)
                        const char *redefined_name = HvNAME_get(stash);
                        if ( strEQ(redefined_name,"autouse") ) {
                            const line_t oldline = CopLINE(PL_curcop);
-                           if (PL_copline != NOLINE)
-                               CopLINE_set(PL_curcop, PL_copline);
+                           if (PL_parser && PL_parser->copline != NOLINE)
+                               CopLINE_set(PL_curcop, PL_parser->copline);
                            Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
                                        CvCONST(cv) ? "Constant subroutine %s redefined"
                                                    : "Subroutine %s redefined"
@@ -5819,8 +5822,8 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
     if ((cv = GvFORM(gv))) {
        if (ckWARN(WARN_REDEFINE)) {
            const line_t oldline = CopLINE(PL_curcop);
-           if (PL_copline != NOLINE)
-               CopLINE_set(PL_curcop, PL_copline);
+           if (PL_parser && PL_parser->copline != NOLINE)
+               CopLINE_set(PL_curcop, PL_parser->copline);
            Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
                        o ? "Format %"SVf" redefined"
                        : "Format STDOUT redefined", SVfARG(cSVOPo->op_sv));
@@ -5847,7 +5850,8 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
 #else
     op_free(o);
 #endif
-    PL_copline = NOLINE;
+    if (PL_parser)
+       PL_parser->copline = NOLINE;
     LEAVE_SCOPE(floor);
 #ifdef PERL_MAD
     return pegop;
@@ -6964,7 +6968,10 @@ Perl_ck_sassign(pTHX_ OP *o)
     if ((PL_opargs[kid->op_type] & OA_TARGLEX)
        && !(kid->op_flags & OPf_STACKED)
        /* Cannot steal the second time! */
-       && !(kid->op_private & OPpTARGET_MY))
+       && !(kid->op_private & OPpTARGET_MY)
+       /* Keep the full thing for madskills */
+       && !PL_madskills
+       )
     {
        OP * const kkid = kid->op_sibling;
 
@@ -6977,13 +6984,8 @@ Perl_ck_sassign(pTHX_ OP *o)
            /* Now we do not need PADSV and SASSIGN. */
            kid->op_sibling = o->op_sibling;    /* NULL */
            cLISTOPo->op_first = NULL;
-#ifdef PERL_MAD
-           op_getmad(o,kid,'O');
-           op_getmad(kkid,kid,'M');
-#else
            op_free(o);
            op_free(kkid);
-#endif
            kid->op_private |= OPpTARGET_MY;    /* Used for context settings */
            return kid;
        }