This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid an assertion failure when overloading readpipe.
[perl5.git] / toke.c
diff --git a/toke.c b/toke.c
index 87c26be..5c4e4e2 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -677,6 +677,7 @@ Perl_lex_start(pTHX_ SV *line)
     SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp);
     SAVEINT(PL_expect);
 
     SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp);
     SAVEINT(PL_expect);
 
+    PL_copline = NOLINE;
     PL_lex_state = LEX_NORMAL;
     PL_expect = XSTATE;
     Newx(parser->lex_brackstack, 120, char);
     PL_lex_state = LEX_NORMAL;
     PL_expect = XSTATE;
     Newx(parser->lex_brackstack, 120, char);
@@ -735,13 +736,12 @@ Perl_lex_end(pTHX)
  */
 
 STATIC void
  */
 
 STATIC void
-S_incline(pTHX_ char *s)
+S_incline(pTHX_ const char *s)
 {
     dVAR;
 {
     dVAR;
-    char *t;
-    char *n;
-    char *e;
-    char ch;
+    const char *t;
+    const char *n;
+    const char *e;
 
     CopLINE_inc(PL_curcop);
     if (*s++ != '#')
 
     CopLINE_inc(PL_curcop);
     if (*s++ != '#')
@@ -781,34 +781,48 @@ S_incline(pTHX_ char *s)
     if (*e != '\n' && *e != '\0')
        return;         /* false alarm */
 
     if (*e != '\n' && *e != '\0')
        return;         /* false alarm */
 
-    ch = *t;
-    *t = '\0';
     if (t - s > 0) {
     if (t - s > 0) {
+       const STRLEN len = t - s;
 #ifndef USE_ITHREADS
        const char * const cf = CopFILE(PL_curcop);
        STRLEN tmplen = cf ? strlen(cf) : 0;
        if (tmplen > 7 && strnEQ(cf, "(eval ", 6)) {
            /* must copy *{"::_<(eval N)[oldfilename:L]"}
             * to *{"::_<newfilename"} */
 #ifndef USE_ITHREADS
        const char * const cf = CopFILE(PL_curcop);
        STRLEN tmplen = cf ? strlen(cf) : 0;
        if (tmplen > 7 && strnEQ(cf, "(eval ", 6)) {
            /* must copy *{"::_<(eval N)[oldfilename:L]"}
             * to *{"::_<newfilename"} */
-           char smallbuf[256], smallbuf2[256];
-           char *tmpbuf, *tmpbuf2;
-           GV **gvp, *gv2;
-           STRLEN tmplen2 = strlen(s);
-           if (tmplen + 3 < sizeof smallbuf)
+           /* However, the long form of evals is only turned on by the
+              debugger - usually they're "(eval %lu)" */
+           char smallbuf[128];
+           char *tmpbuf;
+           GV **gvp;
+           STRLEN tmplen2 = len;
+           if (tmplen + 2 <= sizeof smallbuf)
                tmpbuf = smallbuf;
            else
                tmpbuf = smallbuf;
            else
-               Newx(tmpbuf, tmplen + 3, char);
-           if (tmplen2 + 3 < sizeof smallbuf2)
-               tmpbuf2 = smallbuf2;
-           else
-               Newx(tmpbuf2, tmplen2 + 3, char);
-           tmpbuf[0] = tmpbuf2[0] = '_';
-           tmpbuf[1] = tmpbuf2[1] = '<';
-           memcpy(tmpbuf + 2, cf, ++tmplen);
-           memcpy(tmpbuf2 + 2, s, ++tmplen2);
-           ++tmplen; ++tmplen2;
+               Newx(tmpbuf, tmplen + 2, char);
+           tmpbuf[0] = '_';
+           tmpbuf[1] = '<';
+           memcpy(tmpbuf + 2, cf, tmplen);
+           tmplen += 2;
            gvp = (GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, FALSE);
            if (gvp) {
            gvp = (GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, FALSE);
            if (gvp) {
+               char *tmpbuf2;
+               GV *gv2;
+
+               if (tmplen2 + 2 <= sizeof smallbuf)
+                   tmpbuf2 = smallbuf;
+               else
+                   Newx(tmpbuf2, tmplen2 + 2, char);
+
+               if (tmpbuf2 != smallbuf || tmpbuf != smallbuf) {
+                   /* Either they malloc'd it, or we malloc'd it,
+                      so no prefix is present in ours.  */
+                   tmpbuf2[0] = '_';
+                   tmpbuf2[1] = '<';
+               }
+
+               memcpy(tmpbuf2 + 2, s, tmplen2);
+               tmplen2 += 2;
+
                gv2 = *(GV**)hv_fetch(PL_defstash, tmpbuf2, tmplen2, TRUE);
                if (!isGV(gv2)) {
                    gv_init(gv2, PL_defstash, tmpbuf2, tmplen2, FALSE);
                gv2 = *(GV**)hv_fetch(PL_defstash, tmpbuf2, tmplen2, TRUE);
                if (!isGV(gv2)) {
                    gv_init(gv2, PL_defstash, tmpbuf2, tmplen2, FALSE);
@@ -817,15 +831,15 @@ S_incline(pTHX_ char *s)
                    GvHV(gv2) = (HV*)SvREFCNT_inc(GvHV(*gvp));
                    GvAV(gv2) = (AV*)SvREFCNT_inc(GvAV(*gvp));
                }
                    GvHV(gv2) = (HV*)SvREFCNT_inc(GvHV(*gvp));
                    GvAV(gv2) = (AV*)SvREFCNT_inc(GvAV(*gvp));
                }
+
+               if (tmpbuf2 != smallbuf) Safefree(tmpbuf2);
            }
            if (tmpbuf != smallbuf) Safefree(tmpbuf);
            }
            if (tmpbuf != smallbuf) Safefree(tmpbuf);
-           if (tmpbuf2 != smallbuf2) Safefree(tmpbuf2);
        }
 #endif
        CopFILE_free(PL_curcop);
        }
 #endif
        CopFILE_free(PL_curcop);
-       CopFILE_set(PL_curcop, s);
+       CopFILE_setn(PL_curcop, s, len);
     }
     }
-    *t = ch;
     CopLINE_set(PL_curcop, atoi(n)-1);
 }
 
     CopLINE_set(PL_curcop, atoi(n)-1);
 }
 
@@ -906,27 +920,15 @@ S_skipspace2(pTHX_ register char *s, SV **svp)
 #endif
 
 STATIC void
 #endif
 
 STATIC void
-S_update_debugger_info_pv(pTHX_ const char *buf, STRLEN len)
+S_update_debugger_info(pTHX_ SV *orig_sv, const char *buf, STRLEN len)
 {
     AV *av = CopFILEAVx(PL_curcop);
     if (av) {
 {
     AV *av = CopFILEAVx(PL_curcop);
     if (av) {
-       SV * const sv = newSV(0);
-       sv_upgrade(sv, SVt_PVMG);
-       sv_setpvn(sv, buf, len);
-       (void)SvIOK_on(sv);
-       SvIV_set(sv, 0);
-       av_store(av, (I32)CopLINE(PL_curcop), sv);
-    }
-}
-
-STATIC void
-S_update_debugger_info_sv(pTHX_ SV *orig_sv)
-{
-    AV *av = CopFILEAVx(PL_curcop);
-    if (av) {
-       SV * const sv = newSV(0);
-       sv_upgrade(sv, SVt_PVMG);
-       sv_setsv(sv, orig_sv);
+       SV * const sv = newSV_type(SVt_PVMG);
+       if (orig_sv)
+           sv_setsv(sv, orig_sv);
+       else
+           sv_setpvn(sv, buf, len);
        (void)SvIOK_on(sv);
        SvIV_set(sv, 0);
        av_store(av, (I32)CopLINE(PL_curcop), sv);
        (void)SvIOK_on(sv);
        SvIV_set(sv, 0);
        av_store(av, (I32)CopLINE(PL_curcop), sv);
@@ -1024,10 +1026,10 @@ S_skipspace(pTHX_ register char *s)
            /* XXX these shouldn't really be added here, can't set PL_faketokens */
            if (PL_minus_p) {
 #ifdef PERL_MAD
            /* XXX these shouldn't really be added here, can't set PL_faketokens */
            if (PL_minus_p) {
 #ifdef PERL_MAD
-               sv_catpv(PL_linestr,
+               sv_catpvs(PL_linestr,
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #else
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #else
-               sv_setpv(PL_linestr,
+               sv_setpvs(PL_linestr,
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #endif
                PL_minus_n = PL_minus_p = 0;
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #endif
                PL_minus_n = PL_minus_p = 0;
@@ -1097,7 +1099,7 @@ S_skipspace(pTHX_ register char *s)
         * so store the line into the debugger's array of lines
         */
        if (PERLDB_LINE && PL_curstash != PL_debstash)
         * so store the line into the debugger's array of lines
         */
        if (PERLDB_LINE && PL_curstash != PL_debstash)
-           update_debugger_info_pv(PL_bufptr, PL_bufend - PL_bufptr);
+           update_debugger_info(NULL, PL_bufptr, PL_bufend - PL_bufptr);
     }
 
 #ifdef PERL_MAD
     }
 
 #ifdef PERL_MAD
@@ -2022,7 +2024,7 @@ S_scan_const(pTHX_ char *start)
                    *d++ = NATIVE_TO_NEED(has_utf8,*s++);
            }
            else if (s[2] == '{' /* This should match regcomp.c */
                    *d++ = NATIVE_TO_NEED(has_utf8,*s++);
            }
            else if (s[2] == '{' /* This should match regcomp.c */
-                    || ((s[2] == 'p' || s[2] == '?') && s[3] == '{'))
+                   || (s[2] == '?' && s[3] == '{'))
            {
                I32 count = 1;
                char *regparse = s + (s[2] == '{' ? 3 : 4);
            {
                I32 count = 1;
                char *regparse = s + (s[2] == '{' ? 3 : 4);
@@ -2670,7 +2672,7 @@ S_intuit_method(pTHX_ char *start, GV *gv, CV *cv)
        if (indirgv && GvCVu(indirgv))
            return 0;
        /* filehandle or package name makes it a method */
        if (indirgv && GvCVu(indirgv))
            return 0;
        /* filehandle or package name makes it a method */
-       if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) {
+       if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, 0)) {
 #ifdef PERL_MAD
            soff = s - SvPVX(PL_linestr);
 #endif
 #ifdef PERL_MAD
            soff = s - SvPVX(PL_linestr);
 #endif
@@ -2902,7 +2904,7 @@ S_find_in_my_stash(pTHX_ const char *pkgname, I32 len)
             pkgname = SvPV_nolen_const(sv);
     }
 
             pkgname = SvPV_nolen_const(sv);
     }
 
-    return gv_stashpv(pkgname, FALSE);
+    return gv_stashpv(pkgname, 0);
 }
 
 /*
 }
 
 /*
@@ -2920,7 +2922,7 @@ S_readpipe_override(pTHX)
                && GvCVu(gv_readpipe) && GvIMPORTED_CV(gv_readpipe))
            ||
            ((gvp = (GV**)hv_fetchs(PL_globalstash, "readpipe", FALSE))
                && GvCVu(gv_readpipe) && GvIMPORTED_CV(gv_readpipe))
            ||
            ((gvp = (GV**)hv_fetchs(PL_globalstash, "readpipe", FALSE))
-            && (gv_readpipe = *gvp) != (GV*)&PL_sv_undef
+            && (gv_readpipe = *gvp) && isGV_with_GP(gv_readpipe)
             && GvCVu(gv_readpipe) && GvIMPORTED_CV(gv_readpipe)))
     {
        PL_lex_op = (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
             && GvCVu(gv_readpipe) && GvIMPORTED_CV(gv_readpipe)))
     {
        PL_lex_op = (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
@@ -3604,7 +3606,7 @@ Perl_yylex(pTHX)
            PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
            PL_last_lop = PL_last_uni = NULL;
            if (PERLDB_LINE && PL_curstash != PL_debstash)
            PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
            PL_last_lop = PL_last_uni = NULL;
            if (PERLDB_LINE && PL_curstash != PL_debstash)
-               update_debugger_info_sv(PL_linestr);
+               update_debugger_info(PL_linestr, NULL, 0);
            goto retry;
        }
        do {
            goto retry;
        }
        do {
@@ -3685,7 +3687,7 @@ Perl_yylex(pTHX)
                if (PL_madskills)
                    sv_catsv(PL_thiswhite, PL_linestr);
 #endif
                if (PL_madskills)
                    sv_catsv(PL_thiswhite, PL_linestr);
 #endif
-               if (*s == '=' && strnEQ(s, "=cut", 4)) {
+               if (*s == '=' && strnEQ(s, "=cut", 4) && !isALPHA(s[4])) {
                    sv_setpvn(PL_linestr, "", 0);
                    PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = SvPVX(PL_linestr);
                    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
                    sv_setpvn(PL_linestr, "", 0);
                    PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = SvPVX(PL_linestr);
                    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
@@ -3697,7 +3699,7 @@ Perl_yylex(pTHX)
        } while (PL_doextract);
        PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = PL_linestart = s;
        if (PERLDB_LINE && PL_curstash != PL_debstash)
        } while (PL_doextract);
        PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = PL_linestart = s;
        if (PERLDB_LINE && PL_curstash != PL_debstash)
-           update_debugger_info_sv(PL_linestr);
+           update_debugger_info(PL_linestr, NULL, 0);
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
        PL_last_lop = PL_last_uni = NULL;
        if (CopLINE(PL_curcop) == 1) {
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
        PL_last_lop = PL_last_uni = NULL;
        if (CopLINE(PL_curcop) == 1) {
@@ -4130,7 +4132,8 @@ Perl_yylex(pTHX)
            Mop(OP_MODULO);
        }
        PL_tokenbuf[0] = '%';
            Mop(OP_MODULO);
        }
        PL_tokenbuf[0] = '%';
-       s = scan_ident(s, PL_bufend, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1, TRUE);
+       s = scan_ident(s, PL_bufend, PL_tokenbuf + 1,
+               sizeof PL_tokenbuf - 1, FALSE);
        if (!PL_tokenbuf[1]) {
            PREREF('%');
        }
        if (!PL_tokenbuf[1]) {
            PREREF('%');
        }
@@ -4145,8 +4148,7 @@ Perl_yylex(pTHX)
        /* FALL THROUGH */
     case '~':
        if (s[1] == '~'
        /* FALL THROUGH */
     case '~':
        if (s[1] == '~'
-       && (PL_expect == XOPERATOR || PL_expect == XTERMORDORDOR)
-       && FEATURE_IS_ENABLED("~~"))
+           && (PL_expect == XOPERATOR || PL_expect == XTERMORDORDOR))
        {
            s += 2;
            Eop(OP_SMARTMATCH);
        {
            s += 2;
            Eop(OP_SMARTMATCH);
@@ -4806,12 +4808,12 @@ Perl_yylex(pTHX)
                                t++;
                            } while (isSPACE(*t));
                            if (isIDFIRST_lazy_if(t,UTF)) {
                                t++;
                            } while (isSPACE(*t));
                            if (isIDFIRST_lazy_if(t,UTF)) {
-                               STRLEN dummylen;
+                               STRLEN len;
                                t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE,
                                t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE,
-                                             &dummylen);
+                                             &len);
                                while (isSPACE(*t))
                                    t++;
                                while (isSPACE(*t))
                                    t++;
-                               if (*t == ';' && get_cv(tmpbuf, FALSE))
+                               if (*t == ';' && get_cvn_flags(tmpbuf, len, 0))
                                    Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                                                "You need to quote \"%s\"",
                                                tmpbuf);
                                    Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                                                "You need to quote \"%s\"",
                                                tmpbuf);
@@ -5164,7 +5166,7 @@ Perl_yylex(pTHX)
                }
                if (!ogv &&
                    (gvp = (GV**)hv_fetch(PL_globalstash,PL_tokenbuf,len,FALSE)) &&
                }
                if (!ogv &&
                    (gvp = (GV**)hv_fetch(PL_globalstash,PL_tokenbuf,len,FALSE)) &&
-                   (gv = *gvp) != (GV*)&PL_sv_undef &&
+                   (gv = *gvp) && isGV_with_GP(gv) &&
                    GvCVu(gv) && GvIMPORTED_CV(gv))
                {
                    ogv = gv;
                    GvCVu(gv) && GvIMPORTED_CV(gv))
                {
                    ogv = gv;
@@ -5532,7 +5534,7 @@ Perl_yylex(pTHX)
                        }
                    }
                    if (probable_sub) {
                        }
                    }
                    if (probable_sub) {
-                       gv = gv_fetchpv(PL_tokenbuf, TRUE, SVt_PVCV);
+                       gv = gv_fetchpv(PL_tokenbuf, GV_ADD, SVt_PVCV);
                        op_free(yylval.opval);
                        yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv));
                        yylval.opval->op_private |= OPpENTERSUB_NOPAREN;
                        op_free(yylval.opval);
                        yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv));
                        yylval.opval->op_private |= OPpENTERSUB_NOPAREN;
@@ -5568,7 +5570,7 @@ Perl_yylex(pTHX)
                            d = PL_tokenbuf;
                            while (isLOWER(*d))
                                d++;
                            d = PL_tokenbuf;
                            while (isLOWER(*d))
                                d++;
-                           if (!*d && !gv_stashpv(PL_tokenbuf,FALSE))
+                           if (!*d && !gv_stashpv(PL_tokenbuf, 0))
                                Perl_warner(aTHX_ packWARN(WARN_RESERVED), PL_warn_reserved,
                                       PL_tokenbuf);
                        }
                                Perl_warner(aTHX_ packWARN(WARN_RESERVED), PL_warn_reserved,
                                       PL_tokenbuf);
                        }
@@ -6366,7 +6368,7 @@ Perl_yylex(pTHX)
                *PL_tokenbuf = '\0';
                s = force_word(s,WORD,TRUE,TRUE,FALSE);
                if (isIDFIRST_lazy_if(PL_tokenbuf,UTF))
                *PL_tokenbuf = '\0';
                s = force_word(s,WORD,TRUE,TRUE,FALSE);
                if (isIDFIRST_lazy_if(PL_tokenbuf,UTF))
-                   gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), TRUE);
+                   gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), GV_ADD);
                else if (*s == '<')
                    yyerror("<> should be quotes");
            }
                else if (*s == '<')
                    yyerror("<> should be quotes");
            }
@@ -6598,8 +6600,8 @@ Perl_yylex(pTHX)
                    if (PL_madskills)
                        nametoke = newSVpvn(s, d - s);
 #endif
                    if (PL_madskills)
                        nametoke = newSVpvn(s, d - s);
 #endif
-                   if (strchr(tmpbuf, ':'))
-                       sv_setpv(PL_subname, tmpbuf);
+                   if (memchr(tmpbuf, ':', len))
+                       sv_setpvn(PL_subname, tmpbuf, len);
                    else {
                        sv_setsv(PL_subname,PL_curstname);
                        sv_catpvs(PL_subname,"::");
                    else {
                        sv_setsv(PL_subname,PL_curstname);
                        sv_catpvs(PL_subname,"::");
@@ -10749,7 +10751,8 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL
            }
            if (PL_lex_state == LEX_NORMAL) {
                if (ckWARN(WARN_AMBIGUOUS) &&
            }
            if (PL_lex_state == LEX_NORMAL) {
                if (ckWARN(WARN_AMBIGUOUS) &&
-                   (keyword(dest, d - dest, 0) || get_cv(dest, FALSE)))
+                   (keyword(dest, d - dest, 0)
+                    || get_cvn_flags(dest, d - dest, 0)))
                {
                    if (funny == '#')
                        funny = '@';
                {
                    if (funny == '#')
                        funny = '@';
@@ -10773,20 +10776,16 @@ void
 Perl_pmflag(pTHX_ U32* pmfl, int ch)
 {
     PERL_UNUSED_CONTEXT;
 Perl_pmflag(pTHX_ U32* pmfl, int ch)
 {
     PERL_UNUSED_CONTEXT;
-    if (ch == 'i')
-       *pmfl |= PMf_FOLD;
-    else if (ch == 'g')
-       *pmfl |= PMf_GLOBAL;
-    else if (ch == 'c')
-       *pmfl |= PMf_CONTINUE;
-    else if (ch == 'o')
-       *pmfl |= PMf_KEEP;
-    else if (ch == 'm')
-       *pmfl |= PMf_MULTILINE;
-    else if (ch == 's')
-       *pmfl |= PMf_SINGLELINE;
-    else if (ch == 'x')
-       *pmfl |= PMf_EXTENDED;
+    if (ch<256) {
+        char c = (char)ch;
+        switch (c) {
+            CASE_STD_PMMOD_FLAGS_PARSE_SET(pmfl);
+            case GLOBAL_PAT_MOD:    *pmfl |= PMf_GLOBAL; break;
+            case CONTINUE_PAT_MOD:  *pmfl |= PMf_CONTINUE; break;
+            case ONCE_PAT_MOD:      *pmfl |= PMf_KEEP; break;
+            case KEEPCOPY_PAT_MOD:  *pmfl |= PMf_KEEPCOPY; break;
+        }
+    }
 }
 
 STATIC char *
 }
 
 STATIC char *
@@ -10796,7 +10795,7 @@ S_scan_pat(pTHX_ char *start, I32 type)
     PMOP *pm;
     char *s = scan_str(start,!!PL_madskills,FALSE);
     const char * const valid_flags =
     PMOP *pm;
     char *s = scan_str(start,!!PL_madskills,FALSE);
     const char * const valid_flags =
-       (const char *)((type == OP_QR) ? "iomsx" : "iogcmsx");
+       (const char *)((type == OP_QR) ? QR_PAT_MODS : M_PAT_MODS);
 #ifdef PERL_MAD
     char *modstart;
 #endif
 #ifdef PERL_MAD
     char *modstart;
 #endif
@@ -10829,7 +10828,8 @@ S_scan_pat(pTHX_ char *start, I32 type)
     if ((pm->op_pmflags & PMf_CONTINUE) && !(pm->op_pmflags & PMf_GLOBAL)
            && ckWARN(WARN_REGEXP))
     {
     if ((pm->op_pmflags & PMf_CONTINUE) && !(pm->op_pmflags & PMf_GLOBAL)
            && ckWARN(WARN_REGEXP))
     {
-        Perl_warner(aTHX_ packWARN(WARN_REGEXP), "Use of /c modifier is meaningless without /g" );
+        Perl_warner(aTHX_ packWARN(WARN_REGEXP), 
+            "Use of /c modifier is meaningless without /g" );
     }
 
     pm->op_pmpermflags = pm->op_pmflags;
     }
 
     pm->op_pmpermflags = pm->op_pmflags;
@@ -10893,11 +10893,11 @@ S_scan_subst(pTHX_ char *start)
 #endif
 
     while (*s) {
 #endif
 
     while (*s) {
-       if (*s == 'e') {
+       if (*s == EXEC_PAT_MOD) {
            s++;
            es++;
        }
            s++;
            es++;
        }
-       else if (strchr("iogcmsx", *s))
+       else if (strchr(S_PAT_MODS, *s))
            pmflag(&pm->op_pmflags,*s++);
        else
            break;
            pmflag(&pm->op_pmflags,*s++);
        else
            break;
@@ -11008,7 +11008,7 @@ S_scan_trans(pTHX_ char *start)
     }
   no_more:
 
     }
   no_more:
 
-    tbl = PerlMemShared_calloc(complement&&!del?258:256, sizeof(short));
+    tbl = (short *)PerlMemShared_calloc(complement&&!del?258:256, sizeof(short));
     o = newPVOP(OP_TRANS, 0, (char*)tbl);
     o->op_private &= ~OPpTRANS_ALL;
     o->op_private |= del|squash|complement|
     o = newPVOP(OP_TRANS, 0, (char*)tbl);
     o->op_private &= ~OPpTRANS_ALL;
     o->op_private |= del|squash|complement|
@@ -11150,8 +11150,8 @@ S_scan_heredoc(pTHX_ register char *s)
        s--;
 #endif
 
        s--;
 #endif
 
-    tmpstr = newSV(79);
-    sv_upgrade(tmpstr, SVt_PVIV);
+    tmpstr = newSV_type(SVt_PVIV);
+    SvGROW(tmpstr, 80);
     if (term == '\'') {
        op_type = OP_CONST;
        SvIV_set(tmpstr, -1);
     if (term == '\'') {
        op_type = OP_CONST;
        SvIV_set(tmpstr, -1);
@@ -11260,7 +11260,7 @@ S_scan_heredoc(pTHX_ register char *s)
            PL_bufend[-1] = '\n';
 #endif
        if (PERLDB_LINE && PL_curstash != PL_debstash)
            PL_bufend[-1] = '\n';
 #endif
        if (PERLDB_LINE && PL_curstash != PL_debstash)
-           update_debugger_info_sv(PL_linestr);
+           update_debugger_info(PL_linestr, NULL, 0);
        if (*s == term && memEQ(s,PL_tokenbuf,len)) {
            STRLEN off = PL_bufend - 1 - SvPVX_const(PL_linestr);
            *(SvPVX(PL_linestr) + off ) = ' ';
        if (*s == term && memEQ(s,PL_tokenbuf,len)) {
            STRLEN off = PL_bufend - 1 - SvPVX_const(PL_linestr);
            *(SvPVX(PL_linestr) + off ) = ' ';
@@ -11378,7 +11378,7 @@ S_scan_inputsymbol(pTHX_ char *start)
                && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline))
                ||
                ((gvp = (GV**)hv_fetchs(PL_globalstash, "readline", FALSE))
                && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline))
                ||
                ((gvp = (GV**)hv_fetchs(PL_globalstash, "readline", FALSE))
-               && (gv_readline = *gvp) != (GV*)&PL_sv_undef
+                && (gv_readline = *gvp) && isGV_with_GP(gv_readline)
                && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline)))
            readline_overriden = TRUE;
 
                && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline)))
            readline_overriden = TRUE;
 
@@ -11556,8 +11556,8 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
 
     /* create a new SV to hold the contents.  79 is the SV's initial length.
        What a random number. */
 
     /* create a new SV to hold the contents.  79 is the SV's initial length.
        What a random number. */
-    sv = newSV(79);
-    sv_upgrade(sv, SVt_PVIV);
+    sv = newSV_type(SVt_PVIV);
+    SvGROW(sv, 80);
     SvIV_set(sv, termcode);
     (void)SvPOK_only(sv);              /* validate pointer */
 
     SvIV_set(sv, termcode);
     (void)SvPOK_only(sv);              /* validate pointer */
 
@@ -11757,7 +11757,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
 
        /* update debugger info */
        if (PERLDB_LINE && PL_curstash != PL_debstash)
 
        /* update debugger info */
        if (PERLDB_LINE && PL_curstash != PL_debstash)
-           update_debugger_info_sv(PL_linestr);
+           update_debugger_info(PL_linestr, NULL, 0);
 
        /* having changed the buffer, we must update PL_bufend */
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
 
        /* having changed the buffer, we must update PL_bufend */
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
@@ -12385,8 +12385,7 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags)
     save_item(PL_subname);
     SAVESPTR(PL_compcv);
 
     save_item(PL_subname);
     SAVESPTR(PL_compcv);
 
-    PL_compcv = (CV*)newSV(0);
-    sv_upgrade((SV *)PL_compcv, is_format ? SVt_PVFM : SVt_PVCV);
+    PL_compcv = (CV*)newSV_type(is_format ? SVt_PVFM : SVt_PVCV);
     CvFLAGS(PL_compcv) |= flags;
 
     PL_subline = CopLINE(PL_curcop);
     CvFLAGS(PL_compcv) |= flags;
 
     PL_subline = CopLINE(PL_curcop);