X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_ctl.c;h=55ec3c39315fa12519322e3746c99552bef0d5db;hb=2d862febb32638bf1f7663134644cf7e37f284ad;hp=2bebcbcf58ad1769feeb348d6616d492e2f7d908;hpb=f3fd7796410b671022d50f0c339d72cecaf4eef7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_ctl.c b/pp_ctl.c index 2bebcbc..55ec3c3 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1,6 +1,7 @@ /* pp_ctl.c * - * Copyright (c) 1991-2002, Larry Wall + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + * 2000, 2001, 2002, 2003, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -21,7 +22,7 @@ #include "perl.h" #ifndef WORD_ALIGN -#define WORD_ALIGN sizeof(U16) +#define WORD_ALIGN sizeof(U32) #endif #define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o)) @@ -97,7 +98,7 @@ PP(pp_regcomp) memNE(PM_GETRE(pm)->precomp, t, len)) { if (PM_GETRE(pm)) { - ReREFCNT_dec(PM_GETRE(pm)); + ReREFCNT_dec(PM_GETRE(pm)); PM_SETRE(pm, Null(REGEXP*)); /* crucial if regcomp aborts */ } if (PL_op->op_flags & OPf_SPECIAL) @@ -156,9 +157,19 @@ PP(pp_substcont) register char *m = cx->sb_m; char *orig = cx->sb_orig; register REGEXP *rx = cx->sb_rx; + SV *nsv = Nullsv; + + { + REGEXP *old = PM_GETRE(pm); + if(old != rx) { + if(old) + ReREFCNT_dec(old); + PM_SETRE(pm,rx); + } + } rxres_restore(&cx->sb_rxres, rx); - PL_reg_match_utf8 = SvUTF8(cx->sb_targ) ? 1 : 0; + RX_MATCH_UTF8_set(rx, SvUTF8(cx->sb_targ)); if (cx->sb_iters++) { I32 saviters = cx->sb_iters; @@ -178,11 +189,22 @@ PP(pp_substcont) { SV *targ = cx->sb_targ; - sv_catpvn(dstr, s, cx->sb_strend - s); + if (DO_UTF8(dstr) && !SvUTF8(targ)) + sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv); + else + sv_catpvn(dstr, s, cx->sb_strend - s); cx->sb_rxtainted |= RX_MATCH_TAINTED(rx); - (void)SvOOK_off(targ); - Safefree(SvPVX(targ)); +#ifdef PERL_COPY_ON_WRITE + if (SvIsCOW(targ)) { + sv_force_normal_flags(targ, SV_COW_DROP_PV); + } else +#endif + { + (void)SvOOK_off(targ); + if (SvLEN(targ)) + Safefree(SvPVX(targ)); + } SvPVX(targ) = SvPVX(dstr); SvCUR_set(targ, SvCUR(dstr)); SvLEN_set(targ, SvLEN(dstr)); @@ -192,7 +214,7 @@ PP(pp_substcont) sv_free(dstr); TAINT_IF(cx->sb_rxtainted & 1); - PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1))); + PUSHs(sv_2mortal(newSViv(saviters - 1))); (void)SvPOK_only_UTF8(targ); TAINT_IF(cx->sb_rxtainted); @@ -200,6 +222,7 @@ PP(pp_substcont) SvTAINT(targ); LEAVE_SCOPE(cx->sb_oldsave); + ReREFCNT_dec(rx); POPSUBST(cx); RETURNOP(pm->op_next); } @@ -213,8 +236,12 @@ PP(pp_substcont) cx->sb_strend = s + (cx->sb_strend - m); } cx->sb_m = m = rx->startp[0] + orig; - if (m > s) - sv_catpvn(dstr, s, m-s); + if (m > s) { + if (DO_UTF8(dstr) && !SvUTF8(cx->sb_targ)) + sv_catpvn_utf8_upgrade(dstr, s, m - s, nsv); + else + sv_catpvn(dstr, s, m-s); + } cx->sb_s = rx->endp[0] + orig; { /* Update the pos() information. */ SV *sv = cx->sb_targ; @@ -231,6 +258,7 @@ PP(pp_substcont) sv_pos_b2u(sv, &i); mg->mg_len = i; } + ReREFCNT_inc(rx); cx->sb_rxtainted |= RX_MATCH_TAINTED(rx); rxres_save(&cx->sb_rxres, rx); RETURNOP(pm->op_pmreplstart); @@ -243,7 +271,11 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx) U32 i; if (!p || p[1] < rx->nparens) { +#ifdef PERL_COPY_ON_WRITE + i = 7 + rx->nparens * 2; +#else i = 6 + rx->nparens * 2; +#endif if (!p) New(501, p, i, UV); else @@ -254,6 +286,11 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx) *p++ = PTR2UV(RX_MATCH_COPIED(rx) ? rx->subbeg : Nullch); RX_MATCH_COPIED_off(rx); +#ifdef PERL_COPY_ON_WRITE + *p++ = PTR2UV(rx->saved_copy); + rx->saved_copy = Nullsv; +#endif + *p++ = rx->nparens; *p++ = PTR2UV(rx->subbeg); @@ -270,11 +307,17 @@ Perl_rxres_restore(pTHX_ void **rsp, REGEXP *rx) UV *p = (UV*)*rsp; U32 i; - if (RX_MATCH_COPIED(rx)) - Safefree(rx->subbeg); + RX_MATCH_COPY_FREE(rx); RX_MATCH_COPIED_set(rx, *p); *p++ = 0; +#ifdef PERL_COPY_ON_WRITE + if (rx->saved_copy) + SvREFCNT_dec (rx->saved_copy); + rx->saved_copy = INT2PTR(SV*,*p); + *p++ = 0; +#endif + rx->nparens = *p++; rx->subbeg = INT2PTR(char*,*p++); @@ -292,6 +335,11 @@ Perl_rxres_free(pTHX_ void **rsp) if (p) { Safefree(INT2PTR(char*,*p)); +#ifdef PERL_COPY_ON_WRITE + if (p[1]) { + SvREFCNT_dec (INT2PTR(SV*,p[1])); + } +#endif Safefree(p); *rsp = Null(void*); } @@ -301,7 +349,7 @@ PP(pp_formline) { dSP; dMARK; dORIGMARK; register SV *tmpForm = *++MARK; - register U16 *fpc; + register U32 *fpc; register char *t; register char *f; register char *s; @@ -319,7 +367,9 @@ PP(pp_formline) bool gotsome = FALSE; STRLEN len; STRLEN fudge = SvCUR(tmpForm) * (IN_BYTES ? 1 : 3) + 1; - bool item_is_utf = FALSE; + bool item_is_utf8 = FALSE; + bool targ_is_utf8 = FALSE; + SV * nsv = Nullsv; if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) { if (SvREADONLY(tmpForm)) { @@ -330,15 +380,16 @@ PP(pp_formline) else doparseform(tmpForm); } - SvPV_force(PL_formtarget, len); + if (DO_UTF8(PL_formtarget)) + targ_is_utf8 = TRUE; t = SvGROW(PL_formtarget, len + fudge + 1); /* XXX SvCUR bad */ t += len; f = SvPV(tmpForm, len); /* need to jump to the next word */ s = f + len + WORD_ALIGN - SvCUR(tmpForm) % WORD_ALIGN; - fpc = (U16*)s; + fpc = (U32*)s; for (;;) { DEBUG_f( { @@ -378,6 +429,21 @@ PP(pp_formline) case FF_LITERAL: arg = *fpc++; + if (targ_is_utf8 && !SvUTF8(tmpForm)) { + SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); + *t = '\0'; + sv_catpvn_utf8_upgrade(PL_formtarget, f, arg, nsv); + t = SvEND(PL_formtarget); + break; + } + if (!targ_is_utf8 && DO_UTF8(tmpForm)) { + SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); + *t = '\0'; + sv_utf8_upgrade(PL_formtarget); + SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1); + t = SvEND(PL_formtarget); + targ_is_utf8 = TRUE; + } while (arg--) *t++ = *f++; break; @@ -422,13 +488,13 @@ PP(pp_formline) break; s++; } - item_is_utf = TRUE; + item_is_utf8 = TRUE; itemsize = s - item; sv_pos_b2u(sv, &itemsize); break; } } - item_is_utf = FALSE; + item_is_utf8 = FALSE; if (itemsize > fieldsize) itemsize = fieldsize; send = chophere = s + itemsize; @@ -483,11 +549,11 @@ PP(pp_formline) itemsize = chophere - item; sv_pos_b2u(sv, &itemsize); } - item_is_utf = TRUE; + item_is_utf8 = TRUE; break; } } - item_is_utf = FALSE; + item_is_utf8 = FALSE; if (itemsize <= fieldsize) { send = chophere = s + itemsize; while (s < send) { @@ -543,7 +609,15 @@ PP(pp_formline) case FF_ITEM: arg = itemsize; s = item; - if (item_is_utf) { + if (item_is_utf8) { + if (!targ_is_utf8) { + SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); + *t = '\0'; + sv_utf8_upgrade(PL_formtarget); + SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1); + t = SvEND(PL_formtarget); + targ_is_utf8 = TRUE; + } while (arg--) { if (UTF8_IS_CONTINUED(*s)) { STRLEN skip = UTF8SKIP(s); @@ -569,6 +643,21 @@ PP(pp_formline) } break; } + if (targ_is_utf8 && !item_is_utf8) { + SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); + *t = '\0'; + sv_catpvn_utf8_upgrade(PL_formtarget, s, arg, nsv); + for (; t < SvEND(PL_formtarget); t++) { +#ifdef EBCDIC + int ch = *t++ = *s++; + if (iscntrl(ch)) +#else + if (!(*t & ~31)) +#endif + *t = ' '; + } + break; + } while (arg--) { #ifdef EBCDIC int ch = *t++ = *s++; @@ -592,22 +681,32 @@ PP(pp_formline) case FF_LINEGLOB: item = s = SvPV(sv, len); itemsize = len; - item_is_utf = FALSE; /* XXX is this correct? */ + if ((item_is_utf8 = DO_UTF8(sv))) + itemsize = sv_len_utf8(sv); if (itemsize) { + bool chopped = FALSE; gotsome = TRUE; - send = s + itemsize; + send = s + len; while (s < send) { if (*s++ == '\n') { - if (s == send) + if (s == send) { itemsize--; + chopped = TRUE; + } else lines++; } } SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); - sv_catpvn(PL_formtarget, item, itemsize); + if (targ_is_utf8) + SvUTF8_on(PL_formtarget); + sv_catsv(PL_formtarget, sv); + if (chopped) + SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) - 1); SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1); t = SvPVX(PL_formtarget) + SvCUR(PL_formtarget); + if (item_is_utf8) + targ_is_utf8 = TRUE; } break; @@ -703,6 +802,8 @@ PP(pp_formline) if (strnEQ(linemark, linemark - arg, arg)) DIE(aTHX_ "Runaway format"); } + if (targ_is_utf8) + SvUTF8_on(PL_formtarget); FmLINES(PL_formtarget) = lines; SP = ORIGMARK; RETURNOP(cLISTOP->op_first); @@ -742,6 +843,8 @@ PP(pp_formline) case FF_END: *t = '\0'; SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget)); + if (targ_is_utf8) + SvUTF8_on(PL_formtarget); FmLINES(PL_formtarget) += lines; SP = ORIGMARK; RETPUSHYES; @@ -1015,6 +1118,16 @@ PP(pp_flop) /* Control. */ +static char *context_name[] = { + "pseudo-block", + "subroutine", + "eval", + "loop", + "substitution", + "block", + "format" +}; + STATIC I32 S_dopoptolabel(pTHX_ char *label) { @@ -1025,30 +1138,16 @@ S_dopoptolabel(pTHX_ char *label) cx = &cxstack[i]; switch (CxTYPE(cx)) { case CXt_SUBST: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s", - OP_NAME(PL_op)); - break; case CXt_SUB: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s", - OP_NAME(PL_op)); - break; case CXt_FORMAT: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s", - OP_NAME(PL_op)); - break; case CXt_EVAL: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s", - OP_NAME(PL_op)); - break; case CXt_NULL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s", - OP_NAME(PL_op)); - return -1; + Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s", + context_name[CxTYPE(cx)], OP_NAME(PL_op)); + if (CxTYPE(cx) == CXt_NULL) + return -1; + break; case CXt_LOOP: if (!cx->blk_loop.label || strNE(label, cx->blk_loop.label) ) { @@ -1160,30 +1259,16 @@ S_dopoptoloop(pTHX_ I32 startingblock) cx = &cxstack[i]; switch (CxTYPE(cx)) { case CXt_SUBST: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s", - OP_NAME(PL_op)); - break; case CXt_SUB: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s", - OP_NAME(PL_op)); - break; case CXt_FORMAT: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s", - OP_NAME(PL_op)); - break; case CXt_EVAL: - if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s", - OP_NAME(PL_op)); - break; case CXt_NULL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s", - OP_NAME(PL_op)); - return -1; + Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s", + context_name[CxTYPE(cx)], OP_NAME(PL_op)); + if ((CxTYPE(cx)) == CXt_NULL) + return -1; + break; case CXt_LOOP: DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i)); return i; @@ -1244,8 +1329,6 @@ OP * Perl_die_where(pTHX_ char *message, STRLEN msglen) { STRLEN n_a; - IO *io; - MAGIC *mg; if (PL_in_eval) { I32 cxix; @@ -1280,8 +1363,6 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) sv_setpvn(ERRSV, message, msglen); } } - else - message = SvPVx(ERRSV, msglen); while ((cxix = dopoptoeval(cxstack_ix)) < 0 && PL_curstackinfo->si_prev) @@ -1298,6 +1379,8 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) POPBLOCK(cx,PL_curpm); if (CxTYPE(cx) != CXt_EVAL) { + if (!message) + message = SvPVx(ERRSV, msglen); PerlIO_write(Perl_error_log, "panic: die ", 11); PerlIO_write(Perl_error_log, message, msglen); my_exit(1); @@ -1327,30 +1410,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) if (!message) message = SvPVx(ERRSV, msglen); - /* if STDERR is tied, print to it instead */ - if (PL_stderrgv && (io = GvIOp(PL_stderrgv)) - && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) { - dSP; ENTER; - PUSHMARK(SP); - XPUSHs(SvTIED_obj((SV*)io, mg)); - XPUSHs(sv_2mortal(newSVpvn(message, msglen))); - PUTBACK; - call_method("PRINT", G_SCALAR); - LEAVE; - } - else { -#ifdef USE_SFIO - /* SFIO can really mess with your errno */ - int e = errno; -#endif - PerlIO *serr = Perl_error_log; - - PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen); - (void)PerlIO_flush(serr); -#ifdef USE_SFIO - errno = e; -#endif - } + write_to_stderr(message, msglen); my_failure_exit(); /* NOTREACHED */ return 0; @@ -1562,8 +1622,18 @@ PP(pp_caller) (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0)) mask = newSVpvn(WARN_NONEstring, WARNsize) ; else if (old_warnings == pWARN_ALL || - (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) - mask = newSVpvn(WARN_ALLstring, WARNsize) ; + (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) { + /* Get the bit mask for $warnings::Bits{all}, because + * it could have been extended by warnings::register */ + SV **bits_all; + HV *bits = get_hv("warnings::Bits", FALSE); + if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) { + mask = newSVsv(*bits_all); + } + else { + mask = newSVpvn(WARN_ALLstring, WARNsize) ; + } + } else mask = newSVsv(old_warnings); PUSHs(sv_2mortal(mask)); @@ -1600,7 +1670,8 @@ PP(pp_dbstate) PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp; FREETMPS; - if (PL_op->op_private || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace)) + if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */ + || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace)) { dSP; register CV *cv; @@ -1629,7 +1700,7 @@ PP(pp_dbstate) push_return(PL_op->op_next); PUSHBLOCK(cx, CXt_SUB, SP); - PUSHSUB(cx); + PUSHSUB_DB(cx); CvDEPTH(cv)++; (void)SvREFCNT_inc(cv); PAD_SET_CUR(CvPADLIST(cv),1); @@ -1820,7 +1891,7 @@ PP(pp_return) /* Unassume the success we assumed earlier. */ SV *nsv = cx->blk_eval.old_namesv; (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD); - DIE(aTHX_ "%s did not return a true value", SvPVX(nsv)); + DIE(aTHX_ "%"SVf" did not return a true value", nsv); } break; case CXt_FORMAT: @@ -1865,6 +1936,7 @@ PP(pp_return) } PL_stack_sp = newsp; + LEAVE; /* Stack values are safe: */ if (popsub2) { POPSUB(cx,sv); /* release CV and @_ ... */ @@ -1873,7 +1945,6 @@ PP(pp_return) sv = Nullsv; PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); if (clear_errsv) sv_setpv(ERRSV,""); @@ -1949,6 +2020,7 @@ PP(pp_last) SP = newsp; PUTBACK; + LEAVE; /* Stack values are safe: */ switch (pop2) { case CXt_LOOP: @@ -1961,7 +2033,6 @@ PP(pp_last) } PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return nextop; } @@ -2031,6 +2102,7 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) if (o->op_type == OP_LEAVE || o->op_type == OP_SCOPE || o->op_type == OP_LEAVELOOP || + o->op_type == OP_LEAVESUB || o->op_type == OP_LEAVETRY) { *ops++ = cUNOPo->op_first; @@ -2048,11 +2120,15 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { if (kid == PL_lastgotoprobe) continue; - if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && - (ops == opstack || - (ops[-1]->op_type != OP_NEXTSTATE && - ops[-1]->op_type != OP_DBSTATE))) - *ops++ = kid; + if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) { + if (ops == opstack) + *ops++ = kid; + else if (ops[-1]->op_type == OP_NEXTSTATE || + ops[-1]->op_type == OP_DBSTATE) + ops[-1] = kid; + else + *ops++ = kid; + } if ((o = dofindlabel(kid, label, ops, oplimit))) return o; } @@ -2108,12 +2184,14 @@ PP(pp_goto) goto retry; tmpstr = sv_newmortal(); gv_efullname3(tmpstr, gv, Nullch); - DIE(aTHX_ "Goto undefined subroutine &%s",SvPVX(tmpstr)); + DIE(aTHX_ "Goto undefined subroutine &%"SVf"",tmpstr); } DIE(aTHX_ "Goto undefined subroutine"); } /* First do some returnish stuff. */ + SvREFCNT_inc(cv); /* avoid premature free during unwind */ + FREETMPS; cxix = dopoptosub(cxstack_ix); if (cxix < 0) DIE(aTHX_ "Can't goto subroutine outside a subroutine"); @@ -2142,6 +2220,8 @@ PP(pp_goto) AvFLAGS(av) = AVf_REIFY; PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av); } + else + CLEAR_ARGARRAY(av); } else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */ AV* av; @@ -2160,6 +2240,7 @@ PP(pp_goto) /* Now do some callish stuff. */ SAVETMPS; + SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */ if (CvXSUB(cv)) { #ifdef PERL_XSUB_OLDSTYLE if (CvOLDSTYLE(cv)) { @@ -2253,7 +2334,10 @@ PP(pp_goto) CV *gotocv; if (PERLDB_SUB_NN) { - SvIVX(sv) = PTR2IV(cv); /* Already upgraded, saved */ + (void)SvUPGRADE(sv, SVt_PVIV); + (void)SvIOK_on(sv); + SAVEIV(SvIVX(sv)); + SvIVX(sv) = PTR2IV(cv); /* Do it the quickest way */ } else { save_item(sv); gv_efullname3(sv, CvGV(cv), Nullch); @@ -2284,6 +2368,7 @@ PP(pp_goto) if (label && *label) { OP *gotoprobe = 0; bool leaving_eval = FALSE; + bool in_block = FALSE; PERL_CONTEXT *last_eval_cx = 0; /* find label */ @@ -2295,7 +2380,7 @@ PP(pp_goto) switch (CxTYPE(cx)) { case CXt_EVAL: leaving_eval = TRUE; - if (CxREALEVAL(cx)) { + if (!CxTRYBLOCK(cx)) { gotoprobe = (last_eval_cx ? last_eval_cx->blk_eval.old_eval_root : PL_eval_root); @@ -2309,9 +2394,10 @@ PP(pp_goto) case CXt_SUBST: continue; case CXt_BLOCK: - if (ix) + if (ix) { gotoprobe = cx->blk_oldcop->op_sibling; - else + in_block = TRUE; + } else gotoprobe = PL_main_root; break; case CXt_SUB: @@ -2368,7 +2454,8 @@ PP(pp_goto) if (*enterops && enterops[1]) { OP *oldop = PL_op; - for (ix = 1; enterops[ix]; ix++) { + ix = enterops[1]->op_type == OP_ENTER && in_block ? 2 : 1; + for (; enterops[ix]; ix++) { PL_op = enterops[ix]; /* Eventually we may want to stack the needed arguments * for each op. For now, we punt on the hard ones. */ @@ -2573,7 +2660,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp) char *tmpbuf = tbuf; char *safestr; int runtime; - CV* runcv; + CV* runcv = Nullcv; /* initialise to avoid compiler warnings */ ENTER; lex_start(sv); @@ -2615,7 +2702,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp) /* we get here either during compilation, or via pp_regcomp at runtime */ runtime = PL_op && (PL_op->op_type == OP_REGCOMP); if (runtime) - runcv = find_runcv(); + runcv = find_runcv(NULL); PL_op = &dummy; PL_op->op_type = OP_ENTEREVAL; @@ -2649,22 +2736,35 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp) =for apidoc find_runcv Locate the CV corresponding to the currently executing sub or eval. +If db_seqp is non_null, skip CVs that are in the DB package and populate +*db_seqp with the cop sequence number at the point that the DB:: code was +entered. (allows debuggers to eval in the scope of the breakpoint rather +than in in the scope of the debuger itself). =cut */ CV* -Perl_find_runcv(pTHX) +Perl_find_runcv(pTHX_ U32 *db_seqp) { I32 ix; PERL_SI *si; PERL_CONTEXT *cx; + if (db_seqp) + *db_seqp = PL_curcop->cop_seq; for (si = PL_curstackinfo; si; si = si->si_prev) { for (ix = si->si_cxix; ix >= 0; ix--) { cx = &(si->si_cxstack[ix]); - if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) - return cx->blk_sub.cv; + if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) { + CV *cv = cx->blk_sub.cv; + /* skip DB:: code */ + if (db_seqp && PL_debstash && CvSTASH(cv) == PL_debstash) { + *db_seqp = cx->blk_oldcop->cop_seq; + continue; + } + return cv; + } else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx)) return PL_compcv; } @@ -2700,7 +2800,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq) cxstack[cxstack_ix].blk_eval.cv = PL_compcv; CvOUTSIDE_SEQ(PL_compcv) = seq; - CvOUTSIDE(PL_compcv) = outside ? (CV*)SvREFCNT_inc(outside) : outside; + CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outside); /* set up a scratch pad */ @@ -2731,8 +2831,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq) else sv_setpv(ERRSV,""); if (yyparse() || PL_error_count || !PL_eval_root) { - SV **newsp; - I32 gimme; + SV **newsp; /* Used by POPBLOCK. */ PERL_CONTEXT *cx; I32 optype = 0; /* Might be reset by POPEVAL. */ STRLEN n_a; @@ -2776,7 +2875,16 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq) *startop = PL_eval_root; } else SAVEFREEOP(PL_eval_root); - if (gimme & G_VOID) + + /* Set the context for this new optree. + * If the last op is an OP_REQUIRE, force scalar context. + * Otherwise, propagate the context from the eval(). */ + if (PL_eval_root->op_type == OP_LEAVEEVAL + && cUNOPx(PL_eval_root)->op_first->op_type == OP_LINESEQ + && cLISTOPx(cUNOPx(PL_eval_root)->op_first)->op_last->op_type + == OP_REQUIRE) + scalar(PL_eval_root); + else if (gimme & G_VOID) scalarvoid(PL_eval_root); else if (gimme & G_ARRAY) list(PL_eval_root); @@ -2808,8 +2916,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq) } STATIC PerlIO * -S_doopen_pmc(pTHX_ const char *name, const char *mode) +S_doopen_pm(pTHX_ const char *name, const char *mode) { +#ifndef PERL_DISABLE_PMC STRLEN namelen = strlen(name); PerlIO *fp; @@ -2837,6 +2946,9 @@ S_doopen_pmc(pTHX_ const char *name, const char *mode) fp = PerlIO_open(name, mode); } return fp; +#else + return PerlIO_open(name, mode); +#endif /* !PERL_DISABLE_PMC */ } PP(pp_require) @@ -2935,7 +3047,7 @@ PP(pp_require) if (path_is_absolute(name)) { tryname = name; - tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE); + tryrsfp = doopen_pm(name,PERL_SCRIPT_MODE); } #ifdef MACOS_TRADITIONAL if (!tryrsfp) { @@ -2944,7 +3056,7 @@ PP(pp_require) MacPerl_CanonDir(name, newname, 1); if (path_is_absolute(newname)) { tryname = newname; - tryrsfp = doopen_pmc(newname,PERL_SCRIPT_MODE); + tryrsfp = doopen_pm(newname,PERL_SCRIPT_MODE); } } #endif @@ -3099,7 +3211,7 @@ PP(pp_require) #endif TAINT_PROPER("require"); tryname = SvPVX(namesv); - tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE); + tryrsfp = doopen_pm(tryname, PERL_SCRIPT_MODE); if (tryrsfp) { if (tryname[0] == '.' && tryname[1] == '/') tryname += 2; @@ -3222,6 +3334,7 @@ PP(pp_entereval) STRLEN len; OP *ret; CV* runcv; + U32 seq; if (!SvPV(sv,len)) RETPUSHUNDEF; @@ -3269,7 +3382,12 @@ PP(pp_entereval) PL_compiling.cop_io = newSVsv(PL_curcop->cop_io); SAVEFREESV(PL_compiling.cop_io); } - runcv = find_runcv(); + /* special case: an eval '' executed within the DB package gets lexically + * placed in the first non-DB CV rather than the current CV - this + * allows the debugger to execute code, find lexicals etc, in the + * scope of the code being debugged. Passing &seq gets find_runcv + * to do the dirty work for us */ + runcv = find_runcv(&seq); push_return(PL_op->op_next); PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP); @@ -3280,7 +3398,7 @@ PP(pp_entereval) if (PERLDB_LINE && PL_curstash != PL_debstash) save_lines(CopFILEAV(&PL_compiling), PL_linestr); PUTBACK; - ret = doeval(gimme, NULL, runcv, PL_curcop->cop_seq); + ret = doeval(gimme, NULL, runcv, seq); if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */ && ret != PL_op->op_next) { /* Successive compilation. */ strcpy(safestr, "_<(eval )"); /* Anything fake and short. */ @@ -3344,7 +3462,7 @@ PP(pp_leaveeval) /* Unassume the success we assumed earlier. */ SV *nsv = cx->blk_eval.old_namesv; (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD); - retop = Perl_die(aTHX_ "%s did not return a true value", SvPVX(nsv)); + retop = Perl_die(aTHX_ "%"SVf" did not return a true value", nsv); /* die_where() did LEAVE, or we won't be here */ } else { @@ -3434,16 +3552,25 @@ S_doparseform(pTHX_ SV *sv) bool noblank = FALSE; bool repeat = FALSE; bool postspace = FALSE; - U16 *fops; - register U16 *fpc; - U16 *linepc = 0; + U32 *fops; + register U32 *fpc; + U32 *linepc = 0; register I32 arg; bool ischop; + int maxops = 2; /* FF_LINEMARK + FF_END) */ if (len == 0) Perl_croak(aTHX_ "Null picture in formline"); - New(804, fops, (send - s)*3+10, U16); /* Almost certainly too long... */ + /* estimate the buffer size needed */ + for (base = s; s <= send; s++) { + if (*s == '\n' || *s == '@' || *s == '^') + maxops += 10; + } + s = base; + base = Nullch; + + New(804, fops, maxops, U32); fpc = fops; if (s < send) { @@ -3606,14 +3733,15 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = FF_END; + assert (fpc <= fops + maxops); /* ensure our buffer estimate was valid */ arg = fpc - fops; { /* need to jump to the next word */ int z; z = WORD_ALIGN - SvCUR(sv) % WORD_ALIGN; - SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U16) + 4); + SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U32) + 4); s = SvPVX(sv) + SvCUR(sv) + z; } - Copy(fops, s, arg, U16); + Copy(fops, s, arg, U32); Safefree(fops); sv_magic(sv, Nullsv, PERL_MAGIC_fm, Nullch, 0); SvCOMPILED_on(sv);