X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_ctl.c;h=1ee85a6d870d53a89a840133079d9c73594794a2;hb=ee580363108be8ac33155650c6c18d2e5cf051f3;hp=ae246016589e37faeb225f3e6217efef25e9a709;hpb=940cb80d04d066d4fedfc4486ab57e435ee74514;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_ctl.c b/pp_ctl.c index ae24601..1ee85a6 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -86,10 +86,11 @@ PP(pp_regcomp) { else { t = SvPV(tmpstr, len); - /* JMR: Check against the last compiled regexp */ - if ( ! pm->op_pmregexp || ! pm->op_pmregexp->precomp - || strnNE(pm->op_pmregexp->precomp, t, len) - || pm->op_pmregexp->precomp[len]) { + /* Check against the last compiled regexp. */ + if (!pm->op_pmregexp || !pm->op_pmregexp->precomp || + pm->op_pmregexp->prelen != len || + memNE(pm->op_pmregexp->precomp, t, len)) + { if (pm->op_pmregexp) { ReREFCNT_dec(pm->op_pmregexp); pm->op_pmregexp = Null(REGEXP*); /* crucial if regcomp aborts */ @@ -533,7 +534,7 @@ PP(pp_grepstart) djSP; SV *src; - if (stack_base + *markstack_ptr == sp) { + if (stack_base + *markstack_ptr == SP) { (void)POPMARK; if (GIMME_V == G_SCALAR) XPUSHs(&sv_no); @@ -572,7 +573,7 @@ PP(pp_mapstart) PP(pp_mapwhile) { djSP; - I32 diff = (sp - stack_base) - *markstack_ptr; + I32 diff = (SP - stack_base) - *markstack_ptr; I32 count; I32 shift; SV** src; @@ -582,11 +583,11 @@ PP(pp_mapwhile) if (diff) { if (diff > markstack_ptr[-1] - markstack_ptr[-2]) { shift = diff - (markstack_ptr[-1] - markstack_ptr[-2]); - count = (sp - stack_base) - markstack_ptr[-1] + 2; + count = (SP - stack_base) - markstack_ptr[-1] + 2; - EXTEND(sp,shift); - src = sp; - dst = (sp += shift); + EXTEND(SP,shift); + src = SP; + dst = (SP += shift); markstack_ptr[-1] += shift; *markstack_ptr += shift; while (--count) @@ -650,8 +651,9 @@ PP(pp_sort) RETPUSHUNDEF; } + ENTER; + SAVEPPTR(sortcop); if (op->op_flags & OPf_STACKED) { - ENTER; if (op->op_flags & OPf_SPECIAL) { OP *kid = cLISTOP->op_first->op_sibling; /* pass pushmark */ kid = kUNOP->op_first; /* pass rv2gv */ @@ -703,7 +705,6 @@ PP(pp_sort) max = --up - myorigmark; if (sortcop) { if (max > 1) { - AV *oldstack; PERL_CONTEXT *cx; SV** newsp; bool oldcatch = CATCH_GET; @@ -711,14 +712,8 @@ PP(pp_sort) SAVETMPS; SAVEOP(); - oldstack = curstack; - if (!sortstack) { - sortstack = newAV(); - AvREAL_off(sortstack); - av_extend(sortstack, 32); - } CATCH_SET(TRUE); - SWITCHSTACK(curstack, sortstack); + PUSHSTACK(SI_SORT); if (sortstash != stash) { firstgv = gv_fetchpv("a", TRUE, SVt_PV); secondgv = gv_fetchpv("b", TRUE, SVt_PV); @@ -742,10 +737,9 @@ PP(pp_sort) qsortsv(myorigmark+1, max, sortcv); POPBLOCK(cx,curpm); - SWITCHSTACK(sortstack, oldstack); + POPSTACK(); CATCH_SET(oldcatch); } - LEAVE; } else { if (max > 1) { @@ -754,6 +748,7 @@ PP(pp_sort) (op->op_private & OPpLOCALE) ? sv_cmp_locale : sv_cmp); } } + LEAVE; stack_sp = ORIGMARK + max; return nextop; } @@ -789,7 +784,7 @@ PP(pp_flip) } else { sv_setiv(targ, 0); - sp--; + SP--; RETURNOP(((CONDOP*)cUNOP->op_first)->op_false); } } @@ -1009,7 +1004,7 @@ dounwind(I32 cxix) while (cxstack_ix > cxix) { cx = &cxstack[cxstack_ix]; DEBUG_l(PerlIO_printf(Perl_debug_log, "Unwinding block %ld, type %s\n", - (long) cxstack_ix+1, block_type[cx->cx_type])); + (long) cxstack_ix, block_type[cx->cx_type])); /* Note: we don't need to restore the base context info till the end. */ switch (cx->cx_type) { case CXt_SUBST: @@ -1034,7 +1029,7 @@ dounwind(I32 cxix) OP * die_where(char *message) { - dTHR; + dSP; if (in_eval) { I32 cxix; register PERL_CONTEXT *cx; @@ -1064,7 +1059,11 @@ die_where(char *message) else sv_setpv(ERRSV, message); - cxix = dopoptoeval(cxstack_ix); + while ((cxix = dopoptoeval(cxstack_ix)) < 0 && curstackinfo->si_prev) { + dounwind(-1); + POPSTACK(); + } + if (cxix >= 0) { I32 optype; @@ -1132,6 +1131,7 @@ PP(pp_caller) register PERL_CONTEXT *cx; I32 dbcxix; I32 gimme; + HV *hv; SV *sv; I32 count = 0; @@ -1161,14 +1161,22 @@ PP(pp_caller) } if (GIMME != G_ARRAY) { - dTARGET; - - sv_setpv(TARG, HvNAME(cx->blk_oldcop->cop_stash)); - PUSHs(TARG); + hv = cx->blk_oldcop->cop_stash; + if (!hv) + PUSHs(&sv_undef); + else { + dTARGET; + sv_setpv(TARG, HvNAME(hv)); + PUSHs(TARG); + } RETURN; } - PUSHs(sv_2mortal(newSVpv(HvNAME(cx->blk_oldcop->cop_stash), 0))); + hv = cx->blk_oldcop->cop_stash; + if (!hv) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(HvNAME(hv), 0))); PUSHs(sv_2mortal(newSVpv(SvPVX(GvSV(cx->blk_oldcop->cop_filegv)), 0))); PUSHs(sv_2mortal(newSViv((I32)cx->blk_oldcop->cop_line))); if (!MAXARG) @@ -1214,10 +1222,10 @@ PP(pp_caller) AvREAL_off(dbargs); /* XXX Should be REIFY */ } - if (AvMAX(dbargs) < AvFILL(ary) + off) - av_extend(dbargs, AvFILL(ary) + off); - Copy(AvALLOC(ary), AvARRAY(dbargs), AvFILL(ary) + 1 + off, SV*); - AvFILL(dbargs) = AvFILL(ary) + off; + if (AvMAX(dbargs) < AvFILLp(ary) + off) + av_extend(dbargs, AvFILLp(ary) + off); + Copy(AvALLOC(ary), AvARRAY(dbargs), AvFILLp(ary) + 1 + off, SV*); + AvFILLp(dbargs) = AvFILLp(ary) + off; } RETURN; } @@ -1274,7 +1282,7 @@ PP(pp_dbstate) if (op->op_private || SvIV(DBsingle) || SvIV(DBsignal) || SvIV(DBtrace)) { - SV **sp; + djSP; register CV *cv; register PERL_CONTEXT *cx; I32 gimme = G_ARRAY; @@ -1296,10 +1304,10 @@ PP(pp_dbstate) SAVESTACK_POS(); debug = 0; hasargs = 0; - sp = stack_sp; + SPAGAIN; push_return(op->op_next); - PUSHBLOCK(cx, CXt_SUB, sp); + PUSHBLOCK(cx, CXt_SUB, SP); PUSHSUB(cx); CvDEPTH(cv)++; (void)SvREFCNT_inc(cv); @@ -1336,8 +1344,9 @@ PP(pp_enteriter) SAVESPTR(*svp); } else { - svp = &GvSV((GV*)POPs); /* symbol table variable */ - SAVESPTR(*svp); + GV *gv = (GV*)POPs; + (void)save_scalar(gv); + svp = &GvSV(gv); /* symbol table variable */ } ENTER; @@ -1348,7 +1357,7 @@ PP(pp_enteriter) cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs); else { cx->blk_loop.iterary = curstack; - AvFILL(curstack) = sp - stack_base; + AvFILLp(curstack) = SP - stack_base; cx->blk_loop.iterix = MARK - stack_base; } @@ -1424,7 +1433,7 @@ PP(pp_return) PMOP *newpm; I32 optype = 0; - if (curstack == sortstack) { + if (curstackinfo->si_type == SI_SORT) { if (cxstack_ix == sortcxix || dopoptosub(cxstack_ix) <= sortcxix) { if (cxstack_ix > sortcxix) dounwind(sortcxix); @@ -1710,11 +1719,14 @@ PP(pp_goto) if (cxix < cxstack_ix) dounwind(cxix); TOPBLOCK(cx); + if (cx->cx_type == CXt_EVAL && cx->blk_eval.old_op_type == OP_ENTEREVAL) + DIE("Can't goto subroutine from an eval-string"); mark = stack_sp; - if (cx->blk_sub.hasargs) { /* put @_ back onto stack */ + if (cx->cx_type == CXt_SUB && + cx->blk_sub.hasargs) { /* put @_ back onto stack */ AV* av = cx->blk_sub.argarray; - items = AvFILL(av) + 1; + items = AvFILLp(av) + 1; stack_sp++; EXTEND(stack_sp, items); /* @_ could have been extended. */ Copy(AvARRAY(av), stack_sp, items, SV*); @@ -1726,7 +1738,8 @@ PP(pp_goto) AvREAL_off(av); av_clear(av); } - if (!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) + if (cx->cx_type == CXt_SUB && + !(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) SvREFCNT_dec(cx->blk_sub.cv); oldsave = scopestack[scopestack_ix - 1]; LEAVE_SCOPE(oldsave); @@ -1736,15 +1749,15 @@ PP(pp_goto) if (CvXSUB(cv)) { if (CvOLDSTYLE(cv)) { I32 (*fp3)_((int,int,int)); - while (sp > mark) { - sp[1] = sp[0]; - sp--; + while (SP > mark) { + SP[1] = SP[0]; + SP--; } fp3 = (I32(*)_((int,int,int)))CvXSUB(cv); items = (*fp3)(CvXSUBANY(cv).any_i32, mark - stack_base + 1, items); - sp = stack_base + items; + SP = stack_base + items; } else { stack_sp--; /* There is no cv arg. */ @@ -1756,6 +1769,12 @@ PP(pp_goto) else { AV* padlist = CvPADLIST(cv); SV** svp = AvARRAY(padlist); + if (cx->cx_type == CXt_EVAL) { + in_eval = cx->blk_eval.old_in_eval; + eval_root = cx->blk_eval.old_eval_root; + cx->cx_type = CXt_SUB; + cx->blk_sub.hasargs = 0; + } cx->blk_sub.cv = cv; cx->blk_sub.olddepth = CvDEPTH(cv); CvDEPTH(cv)++; @@ -1764,10 +1783,10 @@ PP(pp_goto) else { /* save temporaries on recursion? */ if (CvDEPTH(cv) == 100 && dowarn) sub_crush_depth(cv); - if (CvDEPTH(cv) > AvFILL(padlist)) { + if (CvDEPTH(cv) > AvFILLp(padlist)) { AV *newpad = newAV(); SV **oldpad = AvARRAY(svp[CvDEPTH(cv)-1]); - I32 ix = AvFILL((AV*)svp[1]); + I32 ix = AvFILLp((AV*)svp[1]); svp = AvARRAY(svp[0]); for ( ;ix > 0; ix--) { if (svp[ix] != &sv_undef) { @@ -1801,7 +1820,7 @@ PP(pp_goto) AvFLAGS(av) = AVf_REIFY; } av_store(padlist, CvDEPTH(cv), (SV*)newpad); - AvFILL(padlist) = CvDEPTH(cv); + AvFILLp(padlist) = CvDEPTH(cv); svp = AvARRAY(padlist); } } @@ -1809,12 +1828,12 @@ PP(pp_goto) if (!cx->blk_sub.hasargs) { AV* av = (AV*)curpad[0]; - items = AvFILL(av) + 1; + items = AvFILLp(av) + 1; if (items) { /* Mark is at the end of the stack. */ - EXTEND(sp, items); - Copy(AvARRAY(av), sp + 1, items, SV*); - sp += items; + EXTEND(SP, items); + Copy(AvARRAY(av), SP + 1, items, SV*); + SP += items; PUTBACK ; } } @@ -1849,7 +1868,7 @@ PP(pp_goto) } } Copy(mark,AvARRAY(av),items,SV*); - AvFILL(av) = items - 1; + AvFILLp(av) = items - 1; while (items--) { if (*mark) @@ -1857,14 +1876,26 @@ PP(pp_goto) mark++; } } - if (PERLDB_SUB && curstash != debstash) { + if (PERLDB_SUB) { /* Checking curstash breaks DProf. */ /* * We do not care about using sv to call CV; * it's for informational purposes only. */ SV *sv = GvSV(DBsub); - save_item(sv); - gv_efullname3(sv, CvGV(cv), Nullch); + CV *gotocv; + + if (PERLDB_SUB_NN) { + SvIVX(sv) = (IV)cv; /* Already upgraded, saved */ + } else { + save_item(sv); + gv_efullname3(sv, CvGV(cv), Nullch); + } + if ( PERLDB_GOTO + && (gotocv = perl_get_cv("DB::goto", FALSE)) ) { + PUSHMARK( stack_sp ); + perl_call_sv((SV*)gotocv, G_SCALAR | G_NODEBUG); + stack_sp--; + } } RETURNOP(CvSTART(cv)); } @@ -1969,7 +2000,7 @@ PP(pp_goto) do_undump = FALSE; } - if (curstack == signalstack) { + if (top_env->je_prev) { restartop = retop; JMPENV_JUMP(3); } @@ -2133,7 +2164,11 @@ sv_compile_2op(SV *sv, OP** startop, char *code, AV** avp) safestr = savepv(tmpbuf); SAVEDELETE(defstash, safestr, strlen(safestr)); SAVEI32(hints); +#ifdef OP_IN_REGISTER + opsave = op; +#else SAVEPPTR(op); +#endif hints = 0; op = &dummy; @@ -2150,6 +2185,9 @@ sv_compile_2op(SV *sv, OP** startop, char *code, AV** avp) lex_end(); *avp = (AV*)SvREFCNT_inc(comppad); LEAVE; +#ifdef OP_IN_REGISTER + op = opsave; +#endif return rop; } @@ -2162,6 +2200,7 @@ doeval(int gimme, OP** startop) HV *newstash; CV *caller; AV* comppadlist; + I32 i; in_eval = 1; @@ -2178,6 +2217,16 @@ doeval(int gimme, OP** startop) SAVEI32(max_intro_pending); caller = compcv; + for (i = cxstack_ix - 1; i >= 0; i--) { + PERL_CONTEXT *cx = &cxstack[i]; + if (cx->cx_type == CXt_EVAL) + break; + else if (cx->cx_type == CXt_SUB) { + caller = cx->blk_sub.cv; + break; + } + } + SAVESPTR(compcv); compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)compcv, SVt_PVCV); @@ -2297,7 +2346,7 @@ doeval(int gimme, OP** startop) CV *cv = perl_get_cv("DB::postponed", FALSE); if (cv) { dSP; - PUSHMARK(sp); + PUSHMARK(SP); XPUSHs((SV*)compiling.cop_filegv); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); @@ -2325,6 +2374,7 @@ PP(pp_require) register PERL_CONTEXT *cx; SV *sv; char *name; + STRLEN len; char *tryname; SV *namesv = Nullsv; SV** svp; @@ -2339,12 +2389,12 @@ PP(pp_require) SvPV(sv,na),patchlevel); RETPUSHYES; } - name = SvPV(sv, na); - if (!*name) + name = SvPV(sv, len); + if (!(name && len > 0 && *name)) DIE("Null filename used"); TAINT_PROPER("require"); if (op->op_type == OP_REQUIRE && - (svp = hv_fetch(GvHVn(incgv), name, SvCUR(sv), 0)) && + (svp = hv_fetch(GvHVn(incgv), name, len, 0)) && *svp != &sv_undef) RETPUSHYES; @@ -2404,7 +2454,7 @@ PP(pp_require) SvREFCNT_dec(namesv); if (!tryrsfp) { if (op->op_type == OP_REQUIRE) { - SV *msg = sv_2mortal(newSVpvf("Can't locate %s in @INC", name)); + SV *msg = sv_2mortal(newSVpvf("Can't locate file '%s' in @INC", name)); SV *dirmsgsv = NEWSV(0, 0); AV *ar = GvAVn(incgv); I32 i; @@ -2578,10 +2628,10 @@ PP(pp_leaveeval) * (Note that the fact that compcv and friends are still set here * is, AFAIK, an accident.) --Chip */ - if (AvFILL(comppad_name) >= 0) { + if (AvFILLp(comppad_name) >= 0) { SV **svp = AvARRAY(comppad_name); I32 ix; - for (ix = AvFILL(comppad_name); ix >= 0; ix--) { + for (ix = AvFILLp(comppad_name); ix >= 0; ix--) { SV *sv = svp[ix]; if (sv && sv != &sv_undef && *SvPVX(sv) == '&') { SvREFCNT_dec(sv); @@ -2606,21 +2656,22 @@ PP(pp_leaveeval) assert(CvDEPTH(compcv) == 1); #endif CvDEPTH(compcv) = 0; + lex_end(); if (optype == OP_REQUIRE && - !(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) + !(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp)) { /* Unassume the success we assumed earlier. */ char *name = cx->blk_eval.old_name; (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); retop = die("%s did not return a true value", name); + /* die_where() did LEAVE, or we won't be here */ + } + else { + LEAVE; + if (!(save_flags & OPf_SPECIAL)) + sv_setpv(ERRSV,""); } - - lex_end(); - LEAVE; - - if (!(save_flags & OPf_SPECIAL)) - sv_setpv(ERRSV,""); RETURNOP(retop); } @@ -3524,9 +3575,10 @@ qsortsv( if (j != i) { /* Looks like we really need to move some things */ + int k; temp = array[i]; - for (--i; i >= j; --i) - array[i + 1] = array[i]; + for (k = i - 1; k >= j; --k) + array[k + 1] = array[k]; array[j] = temp; } }