X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_ctl.c;h=1ee85a6d870d53a89a840133079d9c73594794a2;hb=ee580363108be8ac33155650c6c18d2e5cf051f3;hp=33247e3edde5b2f27a8719991424c85c87a2d306;hpb=301d9039fb19ffce344369e333240632e80d95d5;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_ctl.c b/pp_ctl.c index 33247e3..1ee85a6 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -86,11 +86,10 @@ PP(pp_regcomp) { else { t = SvPV(tmpstr, len); - /* JMR: Check against the last compiled regexp - To know for sure, we'd need the length of precomp. - But we don't have it, so we must ... take a guess. */ + /* Check against the last compiled regexp. */ if (!pm->op_pmregexp || !pm->op_pmregexp->precomp || - memNE(pm->op_pmregexp->precomp, t, len + 1)) + pm->op_pmregexp->prelen != len || + memNE(pm->op_pmregexp->precomp, t, len)) { if (pm->op_pmregexp) { ReREFCNT_dec(pm->op_pmregexp); @@ -535,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); @@ -574,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; @@ -584,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) @@ -652,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 */ @@ -705,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; @@ -713,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); @@ -744,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) { @@ -756,6 +748,7 @@ PP(pp_sort) (op->op_private & OPpLOCALE) ? sv_cmp_locale : sv_cmp); } } + LEAVE; stack_sp = ORIGMARK + max; return nextop; } @@ -791,7 +784,7 @@ PP(pp_flip) } else { sv_setiv(targ, 0); - sp--; + SP--; RETURNOP(((CONDOP*)cUNOP->op_first)->op_false); } } @@ -1036,7 +1029,7 @@ dounwind(I32 cxix) OP * die_where(char *message) { - dTHR; + dSP; if (in_eval) { I32 cxix; register PERL_CONTEXT *cx; @@ -1066,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; @@ -1285,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; @@ -1307,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); @@ -1360,7 +1357,7 @@ PP(pp_enteriter) cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs); else { cx->blk_loop.iterary = curstack; - AvFILLp(curstack) = sp - stack_base; + AvFILLp(curstack) = SP - stack_base; cx->blk_loop.iterix = MARK - stack_base; } @@ -1436,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); @@ -1722,8 +1719,11 @@ 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 = AvFILLp(av) + 1; @@ -1738,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); @@ -1748,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. */ @@ -1768,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)++; @@ -1824,9 +1831,9 @@ PP(pp_goto) 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 ; } } @@ -1869,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)); } @@ -1981,7 +2000,7 @@ PP(pp_goto) do_undump = FALSE; } - if (curstack == signalstack) { + if (top_env->je_prev) { restartop = retop; JMPENV_JUMP(3); } @@ -2145,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; @@ -2162,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; } @@ -2320,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); @@ -2348,6 +2374,7 @@ PP(pp_require) register PERL_CONTEXT *cx; SV *sv; char *name; + STRLEN len; char *tryname; SV *namesv = Nullsv; SV** svp; @@ -2362,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; @@ -2427,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; @@ -2629,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); } @@ -3547,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; } }