X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/a2287a13f4e99299ebd9c06f9f98e1bdc7f5089e..405dffcb17b9cc9d0e5d7b41835b998ca7f1d873:/pp_ctl.c diff --git a/pp_ctl.c b/pp_ctl.c index d47e983..f2c9856 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -40,7 +40,6 @@ PP(pp_wantarray) { - dVAR; dSP; I32 cxix; const PERL_CONTEXT *cx; @@ -68,14 +67,12 @@ PP(pp_wantarray) PP(pp_regcreset) { - dVAR; TAINT_NOT; return NORMAL; } PP(pp_regcomp) { - dVAR; dSP; PMOP *pm = (PMOP*)cLOGOP->op_other; SV **args; @@ -145,7 +142,7 @@ PP(pp_regcomp) const bool was_tainted = TAINT_get; if (pm->op_flags & OPf_STACKED) lhs = args[-1]; - else if (pm->op_private & OPpTARGET_MY) + else if (pm->op_targ) lhs = PAD_SV(pm->op_targ); else lhs = DEFSV; SvGETMAGIC(lhs); @@ -153,7 +150,7 @@ PP(pp_regcomp) modified by get-magic), to avoid incorrectly setting the RXf_TAINTED flag with RX_TAINT_on further down. */ TAINT_set(was_tainted); -#if NO_TAINT_SUPPORT +#ifdef NO_TAINT_SUPPORT PERL_UNUSED_VAR(was_tainted); #endif } @@ -191,7 +188,6 @@ PP(pp_regcomp) PP(pp_substcont) { - dVAR; dSP; PERL_CONTEXT *cx = &cxstack[cxstack_ix]; PMOP * const pm = (PMOP*) cLOGOP->op_other; @@ -214,7 +210,7 @@ PP(pp_substcont) rxres_restore(&cx->sb_rxres, rx); if (cx->sb_iters++) { - const I32 saviters = cx->sb_iters; + const SSize_t saviters = cx->sb_iters; if (cx->sb_iters > cx->sb_maxiters) DIE(aTHX_ "Substitution loop"); @@ -292,7 +288,7 @@ PP(pp_substcont) POPSUBST(cx); PERL_ASYNC_CHECK(); RETURNOP(pm->op_next); - assert(0); /* NOTREACHED */ + NOT_REACHED; /* NOTREACHED */ } cx->sb_iters = saviters; } @@ -319,8 +315,8 @@ PP(pp_substcont) if (!(mg = mg_find_mglob(sv))) { mg = sv_magicext_mglob(sv); } - assert(SvPOK(dstr)); - MgBYTEPOS_set(mg, sv, SvPVX(dstr), m - orig); + assert(SvPOK(sv)); + MgBYTEPOS_set(mg, sv, SvPVX(sv), m - orig); } if (old != rx) (void)ReREFCNT_inc(rx); @@ -457,7 +453,7 @@ S_rxres_free(pTHX_ void **rsp) PP(pp_formline) { - dVAR; dSP; dMARK; dORIGMARK; + dSP; dMARK; dORIGMARK; SV * const tmpForm = *++MARK; SV *formsv; /* contains text of original format */ U32 *fpc; /* format ops program counter */ @@ -678,7 +674,7 @@ PP(pp_formline) goto append; case FF_CHOP: /* (for ^*) chop the current item */ - { + if (sv != &PL_sv_no) { const char *s = chophere; if (chopspace) { while (isSPACE(*s)) @@ -696,6 +692,7 @@ PP(pp_formline) case FF_LINESNGL: /* process ^* */ chopspace = 0; + /* FALLTHROUGH */ case FF_LINEGLOB: /* process @* */ { @@ -704,11 +701,11 @@ PP(pp_formline) const char *const send = s + len; item_is_utf8 = DO_UTF8(sv); + chophere = s + len; if (!len) break; trans = 0; gotsome = TRUE; - chophere = s + len; source = (U8 *) s; to_copy = len; while (s < send) { @@ -796,26 +793,14 @@ PP(pp_formline) case FF_0DECIMAL: /* like FF_DECIMAL but for 0### */ arg = *fpc++; -#if defined(USE_LONG_DOUBLE) fmt = (const char *) - ((arg & FORM_NUM_POINT) ? - "%#0*.*" PERL_PRIfldbl : "%0*.*" PERL_PRIfldbl); -#else - fmt = (const char *) - ((arg & FORM_NUM_POINT) ? - "%#0*.*f" : "%0*.*f"); -#endif + ((arg & FORM_NUM_POINT) ? "%#0*.*" NVff : "%0*.*" NVff); goto ff_dec; case FF_DECIMAL: /* do @##, ^##, where =(precision|flags) */ arg = *fpc++; -#if defined(USE_LONG_DOUBLE) fmt = (const char *) - ((arg & FORM_NUM_POINT) ? "%#*.*" PERL_PRIfldbl : "%*.*" PERL_PRIfldbl); -#else - fmt = (const char *) - ((arg & FORM_NUM_POINT) ? "%#*.*f" : "%*.*f"); -#endif + ((arg & FORM_NUM_POINT) ? "%#*.*" NVff : "%*.*" NVff); ff_dec: /* If the field is marked with ^ and the value is undefined, blank it out. */ @@ -836,12 +821,29 @@ PP(pp_formline) } /* Formats aren't yet marked for locales, so assume "yes". */ { + Size_t max = SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)); + int len; DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED(); - arg &= ~(FORM_NUM_POINT|FORM_NUM_BLANK); + arg &= ~(FORM_NUM_POINT|FORM_NUM_BLANK); +#ifdef USE_QUADMATH + { + const char* qfmt = quadmath_format_single(fmt); + int len; + if (!qfmt) + Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", fmt); + len = quadmath_snprintf(t, max, qfmt, (int) fieldsize, (int) arg, value); + if (len == -1) + Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", qfmt); + if (qfmt != fmt) + Safefree(fmt); + } +#else /* we generate fmt ourselves so it is safe */ GCC_DIAG_IGNORE(-Wformat-nonliteral); - my_snprintf(t, SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)), fmt, (int) fieldsize, (int) arg, value); + len = my_snprintf(t, max, fmt, (int) fieldsize, (int) arg, value); GCC_DIAG_RESTORE; +#endif + PERL_MY_SNPRINTF_POST_GUARD(len, max); RESTORE_LC_NUMERIC(); } t += fieldsize; @@ -915,7 +917,7 @@ PP(pp_formline) PP(pp_grepstart) { - dVAR; dSP; + dSP; SV *src; if (PL_stack_base + *PL_markstack_ptr == SP) { @@ -938,7 +940,7 @@ PP(pp_grepstart) SAVEVPTR(PL_curpm); src = PL_stack_base[*PL_markstack_ptr]; - if (SvPADTMP(src) && !IS_PADGV(src)) { + if (SvPADTMP(src)) { src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src); PL_tmps_floor++; } @@ -956,7 +958,7 @@ PP(pp_grepstart) PP(pp_mapwhile) { - dVAR; dSP; + dSP; const I32 gimme = GIMME_V; I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */ I32 count; @@ -1090,7 +1092,9 @@ PP(pp_mapwhile) /* set $_ to the new source item */ src = PL_stack_base[PL_markstack_ptr[-1]]; - if (SvPADTMP(src) && !IS_PADGV(src)) src = sv_mortalcopy(src); + if (SvPADTMP(src)) { + src = sv_mortalcopy(src); + } SvTEMP_off(src); if (PL_op->op_private & OPpGREP_LEX) PAD_SVl(PL_op->op_targ) = src; @@ -1105,8 +1109,7 @@ PP(pp_mapwhile) PP(pp_range) { - dVAR; - if (GIMME == G_ARRAY) + if (GIMME_V == G_ARRAY) return NORMAL; if (SvTRUEx(PAD_SV(PL_op->op_targ))) return cLOGOP->op_other; @@ -1116,10 +1119,9 @@ PP(pp_range) PP(pp_flip) { - dVAR; dSP; - if (GIMME == G_ARRAY) { + if (GIMME_V == G_ARRAY) { RETURNOP(((LOGOP*)cUNOP->op_first)->op_other); } else { @@ -1171,36 +1173,46 @@ PP(pp_flip) PP(pp_flop) { - dVAR; dSP; + dSP; - if (GIMME == G_ARRAY) { + if (GIMME_V == G_ARRAY) { dPOPPOPssrl; SvGETMAGIC(left); SvGETMAGIC(right); if (RANGE_IS_NUMERIC(left,right)) { - IV i, j; - IV max; + IV i, j, n; if ((SvOK(left) && !SvIOK(left) && SvNV_nomg(left) < IV_MIN) || (SvOK(right) && (SvIOK(right) ? SvIsUV(right) && SvUV(right) > IV_MAX : SvNV_nomg(right) > IV_MAX))) DIE(aTHX_ "Range iterator outside integer range"); i = SvIV_nomg(left); - max = SvIV_nomg(right); - if (max >= i) { - j = max - i + 1; - if (j > SSize_t_MAX) - Perl_croak(aTHX_ "Out of memory during list extend"); - EXTEND_MORTAL(j); - EXTEND(SP, j); + j = SvIV_nomg(right); + if (j >= i) { + /* Dance carefully around signed max. */ + bool overflow = (i <= 0 && j > SSize_t_MAX + i - 1); + if (!overflow) { + n = j - i + 1; + /* The wraparound of signed integers is undefined + * behavior, but here we aim for count >=1, and + * negative count is just wrong. */ + if (n < 1) + overflow = TRUE; + } + if (overflow) + Perl_croak(aTHX_ "Out of memory during list extend"); + EXTEND_MORTAL(n); + EXTEND(SP, n); } else - j = 0; - while (j--) { - SV * const sv = sv_2mortal(newSViv(i++)); + n = 0; + while (n--) { + SV * const sv = sv_2mortal(newSViv(i)); PUSHs(sv); + if (n) /* avoid incrementing above IV_MAX */ + i++; } } else { @@ -1267,7 +1279,6 @@ static const char * const context_name[] = { STATIC I32 S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags) { - dVAR; I32 i; PERL_ARGS_ASSERT_DOPOPTOLABEL; @@ -1322,7 +1333,6 @@ S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags) I32 Perl_dowantarray(pTHX) { - dVAR; const I32 gimme = block_gimme(); return (gimme == G_VOID) ? G_SCALAR : gimme; } @@ -1330,7 +1340,6 @@ Perl_dowantarray(pTHX) I32 Perl_block_gimme(pTHX) { - dVAR; const I32 cxix = dopoptosub(cxstack_ix); if (cxix < 0) return G_VOID; @@ -1344,15 +1353,13 @@ Perl_block_gimme(pTHX) return G_ARRAY; default: Perl_croak(aTHX_ "panic: bad gimme: %d\n", cxstack[cxix].blk_gimme); - assert(0); /* NOTREACHED */ - return 0; } + NOT_REACHED; /* NOTREACHED */ } I32 Perl_is_lvalue_sub(pTHX) { - dVAR; const I32 cxix = dopoptosub(cxstack_ix); assert(cxix >= 0); /* We should only be called from inside subs */ @@ -1366,7 +1373,6 @@ Perl_is_lvalue_sub(pTHX) I32 Perl_was_lvalue_sub(pTHX) { - dVAR; const I32 cxix = dopoptosub(cxstack_ix-1); assert(cxix >= 0); /* We should only be called from inside subs */ @@ -1379,10 +1385,12 @@ Perl_was_lvalue_sub(pTHX) STATIC I32 S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock) { - dVAR; I32 i; PERL_ARGS_ASSERT_DOPOPTOSUB_AT; +#ifndef DEBUGGING + PERL_UNUSED_CONTEXT; +#endif for (i = startingblock; i >= 0; i--) { const PERL_CONTEXT * const cx = &cxstk[i]; @@ -1396,6 +1404,7 @@ S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock) * code block. Hide this faked entry from the world. */ if (cx->cx_type & CXp_SUB_RE_FAKE) continue; + /* FALLTHROUGH */ case CXt_EVAL: case CXt_FORMAT: DEBUG_l( Perl_deb(aTHX_ "(dopoptosub_at(): found sub at cx=%ld)\n", (long)i)); @@ -1408,7 +1417,6 @@ S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock) STATIC I32 S_dopoptoeval(pTHX_ I32 startingblock) { - dVAR; I32 i; for (i = startingblock; i >= 0; i--) { const PERL_CONTEXT *cx = &cxstack[i]; @@ -1426,7 +1434,6 @@ S_dopoptoeval(pTHX_ I32 startingblock) STATIC I32 S_dopoptoloop(pTHX_ I32 startingblock) { - dVAR; I32 i; for (i = startingblock; i >= 0; i--) { const PERL_CONTEXT * const cx = &cxstack[i]; @@ -1456,7 +1463,6 @@ S_dopoptoloop(pTHX_ I32 startingblock) STATIC I32 S_dopoptogiven(pTHX_ I32 startingblock) { - dVAR; I32 i; for (i = startingblock; i >= 0; i--) { const PERL_CONTEXT *cx = &cxstack[i]; @@ -1484,7 +1490,6 @@ S_dopoptogiven(pTHX_ I32 startingblock) STATIC I32 S_dopoptowhen(pTHX_ I32 startingblock) { - dVAR; I32 i; for (i = startingblock; i >= 0; i--) { const PERL_CONTEXT *cx = &cxstack[i]; @@ -1502,7 +1507,6 @@ S_dopoptowhen(pTHX_ I32 startingblock) void Perl_dounwind(pTHX_ I32 cxix) { - dVAR; I32 optype; if (!PL_curstackinfo) /* can happen if die during thread cloning */ @@ -1544,8 +1548,6 @@ Perl_dounwind(pTHX_ I32 cxix) void Perl_qerror(pTHX_ SV *err) { - dVAR; - PERL_ARGS_ASSERT_QERROR; if (PL_in_eval) { @@ -1567,7 +1569,6 @@ Perl_qerror(pTHX_ SV *err) void Perl_die_unwind(pTHX_ SV *msv) { - dVAR; SV *exceptsv = sv_mortalcopy(msv); U8 in_eval = PL_in_eval; PERL_ARGS_ASSERT_DIE_UNWIND; @@ -1627,7 +1628,9 @@ Perl_die_unwind(pTHX_ SV *msv) SV *namesv; PERL_CONTEXT *cx; SV **newsp; +#ifdef DEBUGGING COP *oldcop; +#endif JMPENV *restartjmpenv; OP *restartop; @@ -1644,7 +1647,9 @@ Perl_die_unwind(pTHX_ SV *msv) } POPEVAL(cx); namesv = cx->blk_eval.old_namesv; +#ifdef DEBUGGING oldcop = cx->blk_oldcop; +#endif restartjmpenv = cx->blk_eval.cur_top_env; restartop = cx->blk_eval.retop; @@ -1654,13 +1659,8 @@ Perl_die_unwind(pTHX_ SV *msv) LEAVE; - /* LEAVE could clobber PL_curcop (see save_re_context()) - * XXX it might be better to find a way to avoid messing with - * PL_curcop in save_re_context() instead, but this is a more - * minimal fix --GSAR */ - PL_curcop = oldcop; - if (optype == OP_REQUIRE) { + assert (PL_curcop == oldcop); (void)hv_store(GvHVn(PL_incgv), SvPVX_const(namesv), SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv), @@ -1678,18 +1678,18 @@ Perl_die_unwind(pTHX_ SV *msv) PL_restartjmpenv = restartjmpenv; PL_restartop = restartop; JMPENV_JUMP(3); - assert(0); /* NOTREACHED */ + NOT_REACHED; /* NOTREACHED */ } } write_to_stderr(exceptsv); my_failure_exit(); - assert(0); /* NOTREACHED */ + NOT_REACHED; /* NOTREACHED */ } PP(pp_xor) { - dVAR; dSP; dPOPTOPssrl; + dSP; dPOPTOPssrl; if (SvTRUE(left) != SvTRUE(right)) RETSETYES; else @@ -1697,6 +1697,9 @@ PP(pp_xor) } /* + +=head1 CV Manipulation Functions + =for apidoc caller_cx The XSUB-writer's equivalent of L. The @@ -1758,11 +1761,10 @@ Perl_caller_cx(pTHX_ I32 count, const PERL_CONTEXT **dbcxp) PP(pp_caller) { - dVAR; dSP; const PERL_CONTEXT *cx; const PERL_CONTEXT *dbcx; - I32 gimme; + I32 gimme = GIMME_V; const HEK *stash_hek; I32 count = 0; bool has_arg = MAXARG && TOPs; @@ -1776,7 +1778,7 @@ PP(pp_caller) cx = caller_cx(count + !!(PL_op->op_private & OPpOFFBYONE), &dbcx); if (!cx) { - if (GIMME != G_ARRAY) { + if (gimme != G_ARRAY) { EXTEND(SP, 1); RETPUSHUNDEF; } @@ -1788,7 +1790,7 @@ PP(pp_caller) stash_hek = SvTYPE(CopSTASH(cx->blk_oldcop)) == SVt_PVHV ? HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop)) : NULL; - if (GIMME != G_ARRAY) { + if (gimme != G_ARRAY) { EXTEND(SP, 1); if (!stash_hek) PUSHs(&PL_sv_undef); @@ -1810,7 +1812,7 @@ PP(pp_caller) PUSHTARG; } mPUSHs(newSVpv(OutCopFILE(cx->blk_oldcop), 0)); - lcop = closest_cop(cx->blk_oldcop, cx->blk_oldcop->op_sibling, + lcop = closest_cop(cx->blk_oldcop, OpSIBLING(cx->blk_oldcop), cx->blk_sub.retop, TRUE); if (!lcop) lcop = cx->blk_oldcop; @@ -1818,12 +1820,9 @@ PP(pp_caller) if (!has_arg) RETURN; if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) { - GV * const cvgv = CvGV(dbcx->blk_sub.cv); /* So is ccstack[dbcxix]. */ - if (cvgv && isGV(cvgv)) { - SV * const sv = newSV(0); - gv_efullname3(sv, cvgv, NULL); - mPUSHs(sv); + if (CvHASGV(dbcx->blk_sub.cv)) { + PUSHs(cv_name(dbcx->blk_sub.cv, 0, 0)); PUSHs(boolSV(CxHASARGS(cx))); } else { @@ -1843,9 +1842,16 @@ PP(pp_caller) if (CxTYPE(cx) == CXt_EVAL) { /* eval STRING */ if (CxOLD_OP_TYPE(cx) == OP_ENTEREVAL) { - PUSHs(newSVpvn_flags(SvPVX(cx->blk_eval.cur_text), - SvCUR(cx->blk_eval.cur_text)-2, - SvUTF8(cx->blk_eval.cur_text)|SVs_TEMP)); + SV *cur_text = cx->blk_eval.cur_text; + if (SvCUR(cur_text) >= 2) { + PUSHs(newSVpvn_flags(SvPVX(cur_text), SvCUR(cur_text)-2, + SvUTF8(cur_text)|SVs_TEMP)); + } + else { + /* I think this is will always be "", but be sure */ + PUSHs(sv_2mortal(newSVsv(cur_text))); + } + PUSHs(&PL_sv_no); } /* require */ @@ -1911,7 +1917,6 @@ PP(pp_caller) PP(pp_reset) { - dVAR; dSP; const char * tmps; STRLEN len = 0; @@ -1928,7 +1933,6 @@ PP(pp_reset) PP(pp_dbstate) { - dVAR; PL_curcop = (COP*)PL_op; TAINT_NOT; /* Each statement is presumed innocent */ PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp; @@ -1937,7 +1941,7 @@ PP(pp_dbstate) PERL_ASYNC_CHECK(); if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */ - || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace)) + || PL_DBsingle_iv || PL_DBsignal_iv || PL_DBtrace_iv) { dSP; PERL_CONTEXT *cx; @@ -1990,17 +1994,24 @@ PP(pp_dbstate) return NORMAL; } +/* S_leave_common: Common code that many functions in this file use on + scope exit. */ + /* SVs on the stack that have any of the flags passed in are left as is. Other SVs are protected via the mortals stack if lvalue is true, and - copied otherwise. */ + copied otherwise. + + Also, taintedness is cleared. +*/ STATIC SV ** -S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, +S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 flags, bool lvalue) { bool padtmp = 0; - PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE; + PERL_ARGS_ASSERT_LEAVE_COMMON; + TAINT_NOT; if (flags & SVs_PADTMP) { flags &= ~SVs_PADTMP; padtmp = 1; @@ -2041,7 +2052,7 @@ S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, PP(pp_enter) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; I32 gimme = GIMME_V; @@ -2055,7 +2066,7 @@ PP(pp_enter) PP(pp_leave) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; SV **newsp; PMOP *newpm; @@ -2070,8 +2081,7 @@ PP(pp_leave) gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR); - TAINT_NOT; - SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP, + SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP, PL_op->op_private & OPpLVALUE); PL_curpm = newpm; /* Don't pop $1 et al till now */ @@ -2082,7 +2092,7 @@ PP(pp_leave) PP(pp_enteriter) { - dVAR; dSP; dMARK; + dSP; dMARK; PERL_CONTEXT *cx; const I32 gimme = GIMME_V; void *itervar; /* location of the iteration variable */ @@ -2104,12 +2114,21 @@ PP(pp_enteriter) itervar = &PAD_SVl(PL_op->op_targ); #endif } - else { /* symbol table variable */ + else if (LIKELY(isGV(TOPs))) { /* symbol table variable */ GV * const gv = MUTABLE_GV(POPs); SV** svp = &GvSV(gv); save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV); *svp = newSV(0); itervar = (void *)gv; + save_aliased_sv(gv); + } + else { + SV * const sv = POPs; + assert(SvTYPE(sv) == SVt_PVMG); + assert(SvMAGIC(sv)); + assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref); + itervar = (void *)sv; + cxtype |= CXp_FOR_LVREF; } if (PL_op->op_private & OPpITER_DEF) @@ -2124,32 +2143,35 @@ PP(pp_enteriter) if (SvTYPE(maybe_ary) != SVt_PVAV) { dPOPss; SV * const right = maybe_ary; + if (UNLIKELY(cxtype & CXp_FOR_LVREF)) + DIE(aTHX_ "Assigned value is not a reference"); SvGETMAGIC(sv); SvGETMAGIC(right); if (RANGE_IS_NUMERIC(sv,right)) { + NV nv; cx->cx_type &= ~CXTYPEMASK; cx->cx_type |= CXt_LOOP_LAZYIV; /* Make sure that no-one re-orders cop.h and breaks our assumptions */ assert(CxTYPE(cx) == CXt_LOOP_LAZYIV); #ifdef NV_PRESERVES_UV - if ((SvOK(sv) && ((SvNV_nomg(sv) < (NV)IV_MIN) || - (SvNV_nomg(sv) > (NV)IV_MAX))) + if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) < (NV)IV_MIN) || + (nv > (NV)IV_MAX))) || - (SvOK(right) && ((SvNV_nomg(right) > (NV)IV_MAX) || - (SvNV_nomg(right) < (NV)IV_MIN)))) + (SvOK(right) && (((nv = SvNV_nomg(right)) > (NV)IV_MAX) || + (nv < (NV)IV_MIN)))) #else - if ((SvOK(sv) && ((SvNV_nomg(sv) <= (NV)IV_MIN) + if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) <= (NV)IV_MIN) || - ((SvNV_nomg(sv) > 0) && - ((SvUV_nomg(sv) > (UV)IV_MAX) || - (SvNV_nomg(sv) > (NV)UV_MAX))))) + ((nv > 0) && + ((nv > (NV)UV_MAX) || + (SvUV_nomg(sv) > (UV)IV_MAX))))) || - (SvOK(right) && ((SvNV_nomg(right) <= (NV)IV_MIN) + (SvOK(right) && (((nv = SvNV_nomg(right)) <= (NV)IV_MIN) || - ((SvNV_nomg(right) > 0) && - ((SvUV_nomg(right) > (UV)IV_MAX) || - (SvNV_nomg(right) > (NV)UV_MAX)) + ((nv > 0) && + ((nv > (NV)UV_MAX) || + (SvUV_nomg(right) > (UV)IV_MAX)) )))) #endif DIE(aTHX_ "Range iterator outside integer range"); @@ -2205,7 +2227,7 @@ PP(pp_enteriter) PP(pp_enterloop) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; const I32 gimme = GIMME_V; @@ -2221,7 +2243,7 @@ PP(pp_enterloop) PP(pp_leaveloop) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; I32 gimme; SV **newsp; @@ -2233,8 +2255,7 @@ PP(pp_leaveloop) mark = newsp; newsp = PL_stack_base + cx->blk_loop.resetsp; - TAINT_NOT; - SP = adjust_stack_on_leave(newsp, SP, MARK, gimme, 0, + SP = leave_common(newsp, SP, MARK, gimme, 0, PL_op->op_private & OPpLVALUE); PUTBACK; @@ -2258,10 +2279,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, const char *what = NULL; if (MARK < SP) { assert(MARK+1 == SP); - if ((SvPADTMP(TOPs) || - (SvFLAGS(TOPs) & (SVf_READONLY | SVf_FAKE)) - == SVf_READONLY - ) && + if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) && !SvSMAGICAL(TOPs)) { what = SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef" @@ -2329,11 +2347,9 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK)); else while (++MARK <= SP) { if (*MARK != &PL_sv_undef - && (SvPADTMP(*MARK) - || (SvFLAGS(*MARK) & (SVf_READONLY|SVf_FAKE)) - == SVf_READONLY - ) + && (SvPADTMP(*MARK) || SvREADONLY(*MARK)) ) { + const bool ro = cBOOL( SvREADONLY(*MARK) ); SV *sv; /* Might be flattened array after $#array = */ PUTBACK; @@ -2345,7 +2361,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, /* diag_listed_as: Can't return %s from lvalue subroutine */ Perl_croak(aTHX_ "Can't return a %s from lvalue subroutine", - SvREADONLY(TOPs) ? "readonly value" : "temporary"); + ro ? "readonly value" : "temporary"); } else *++newsp = @@ -2359,7 +2375,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, PP(pp_return) { - dVAR; dSP; dMARK; + dSP; dMARK; PERL_CONTEXT *cx; bool popsub2 = FALSE; bool clear_errsv = FALSE; @@ -2500,7 +2516,7 @@ PP(pp_return) * pp_return */ PP(pp_leavesublv) { - dVAR; dSP; + dSP; SV **newsp; PMOP *newpm; I32 gimme; @@ -2529,7 +2545,6 @@ PP(pp_leavesublv) static I32 S_unwind_loop(pTHX_ const char * const opname) { - dVAR; I32 cxix; if (PL_op->op_flags & OPf_SPECIAL) { cxix = dopoptoloop(cxstack_ix); @@ -2568,7 +2583,6 @@ S_unwind_loop(pTHX_ const char * const opname) PP(pp_last) { - dVAR; PERL_CONTEXT *cx; I32 pop2 = 0; I32 gimme; @@ -2635,7 +2649,6 @@ PP(pp_last) PP(pp_next) { - dVAR; PERL_CONTEXT *cx; const I32 inner = PL_scopestack_ix; @@ -2653,7 +2666,6 @@ PP(pp_next) PP(pp_redo) { - dVAR; const I32 cxix = S_unwind_loop(aTHX_ "redo"); PERL_CONTEXT *cx; I32 oldsave; @@ -2678,7 +2690,6 @@ PP(pp_redo) STATIC OP * S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstack, OP **oplimit) { - dVAR; OP **ops = opstack; static const char* const too_deep = "Target of goto is too deeply nested"; @@ -2700,7 +2711,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac if (o->op_flags & OPf_KIDS) { OP *kid; /* First try all the kids at this level, since that's likeliest. */ - for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { + for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) { if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) { STRLEN kid_label_len; U32 kid_label_flags; @@ -2720,7 +2731,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac return kid; } } - for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { + for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) { if (kid == PL_lastgotoprobe) continue; if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) { @@ -2740,7 +2751,10 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac return 0; } -PP(pp_goto) /* also pp_dump */ + +/* also used for: pp_dump() */ + +PP(pp_goto) { dVAR; dSP; OP *retop = NULL; @@ -2856,7 +2870,6 @@ PP(pp_goto) /* also pp_dump */ SAVETMPS; SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */ if (CvISXSUB(cv)) { - OP* const retop = cx->blk_sub.retop; SV **newsp; I32 gimme; const SSize_t items = arg ? AvFILL(arg) + 1 : 0; @@ -2896,6 +2909,7 @@ PP(pp_goto) /* also pp_dump */ SvREFCNT_dec(arg); } + retop = cx->blk_sub.retop; /* XS subs don't have a CxSUB, so pop it */ POPBLOCK(cx, PL_curpm); /* Push a mark for the start of arglist */ @@ -2903,8 +2917,7 @@ PP(pp_goto) /* also pp_dump */ PUTBACK; (void)(*CvXSUB(cv))(aTHX_ cv); LEAVE; - PERL_ASYNC_CHECK(); - return retop; + goto _return; } else { PADLIST * const padlist = CvPADLIST(cv); @@ -2932,8 +2945,10 @@ PP(pp_goto) /* also pp_dump */ to freed memory as the result of undef *_. So put it in the callee’s pad, donating our refer- ence count. */ - SvREFCNT_dec(PAD_SVl(0)); - PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg); + if (arg) { + SvREFCNT_dec(PAD_SVl(0)); + PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg); + } /* GvAV(PL_defgv) might have been modified on scope exit, so restore it. */ @@ -2955,8 +2970,8 @@ PP(pp_goto) /* also pp_dump */ } } } - PERL_ASYNC_CHECK(); - RETURNOP(CvSTART(cv)); + retop = CvSTART(cv); + goto putback_return; } } else { @@ -3004,13 +3019,13 @@ PP(pp_goto) /* also pp_dump */ case CXt_LOOP_PLAIN: case CXt_GIVEN: case CXt_WHEN: - gotoprobe = cx->blk_oldcop->op_sibling; + gotoprobe = OpSIBLING(cx->blk_oldcop); break; case CXt_SUBST: continue; case CXt_BLOCK: if (ix) { - gotoprobe = cx->blk_oldcop->op_sibling; + gotoprobe = OpSIBLING(cx->blk_oldcop); in_block = TRUE; } else gotoprobe = PL_main_root; @@ -3020,7 +3035,7 @@ PP(pp_goto) /* also pp_dump */ gotoprobe = CvROOT(cx->blk_sub.cv); break; } - /* FALL THROUGH */ + /* FALLTHROUGH */ case CXt_FORMAT: case CXt_NULL: DIE(aTHX_ "Can't \"goto\" out of a pseudo block"); @@ -3032,14 +3047,17 @@ PP(pp_goto) /* also pp_dump */ break; } if (gotoprobe) { + OP *sibl1, *sibl2; + retop = dofindlabel(gotoprobe, label, label_len, label_flags, enterops, enterops + GOTO_DEPTH); if (retop) break; - if (gotoprobe->op_sibling && - gotoprobe->op_sibling->op_type == OP_UNSTACK && - gotoprobe->op_sibling->op_sibling) { - retop = dofindlabel(gotoprobe->op_sibling->op_sibling, + if ( (sibl1 = OpSIBLING(gotoprobe)) && + sibl1->op_type == OP_UNSTACK && + (sibl2 = OpSIBLING(sibl1))) + { + retop = dofindlabel(sibl2, label, label_len, label_flags, enterops, enterops + GOTO_DEPTH); if (retop) @@ -3075,7 +3093,7 @@ PP(pp_goto) /* also pp_dump */ I32 oldsave; if (ix < 0) - ix = 0; + DIE(aTHX_ "panic: docatch: illegal ix=%ld", (long)ix); dounwind(ix); TOPBLOCK(cx); oldsave = PL_scopestack[PL_scopestack_ix]; @@ -3099,7 +3117,8 @@ PP(pp_goto) /* also pp_dump */ } } - if (do_dump) { + else { + assert(do_dump); #ifdef VMS if (!retop) retop = PL_main_start; #endif @@ -3112,13 +3131,15 @@ PP(pp_goto) /* also pp_dump */ PL_do_undump = FALSE; } + putback_return: + PL_stack_sp = sp; + _return: PERL_ASYNC_CHECK(); - RETURNOP(retop); + return retop; } PP(pp_exit) { - dVAR; dSP; I32 anum; @@ -3138,13 +3159,7 @@ PP(pp_exit) #endif } PL_exit_flags |= PERL_EXIT_EXPECTED; -#ifdef PERL_MAD - /* KLUDGE: disable exit 0 in BEGIN blocks when we're just compiling */ - if (anum || !(PL_minus_c && PL_madskills)) - my_exit(anum); -#else my_exit(anum); -#endif PUSHs(&PL_sv_undef); RETURN; } @@ -3193,7 +3208,6 @@ establish a local jmpenv to handle exception traps. STATIC OP * S_docatch(pTHX_ OP *o) { - dVAR; int ret; OP * const oldop = PL_op; dJMPENV; @@ -3220,12 +3234,12 @@ S_docatch(pTHX_ OP *o) PL_restartop = 0; goto redo_body; } - /* FALL THROUGH */ + /* FALLTHROUGH */ default: JMPENV_POP; PL_op = oldop; JMPENV_JUMP(ret); - assert(0); /* NOTREACHED */ + NOT_REACHED; /* NOTREACHED */ } JMPENV_POP; PL_op = oldop; @@ -3255,7 +3269,6 @@ Perl_find_runcv(pTHX_ U32 *db_seqp) CV * Perl_find_runcv_where(pTHX_ U8 cond, IV arg, U32 *db_seqp) { - dVAR; PERL_SI *si; int level = 0; @@ -3286,7 +3299,7 @@ Perl_find_runcv_where(pTHX_ U8 cond, IV arg, U32 *db_seqp) switch (cond) { case FIND_RUNCV_padid_eq: if (!CvPADLIST(cv) - || PadlistNAMES(CvPADLIST(cv)) != INT2PTR(PADNAMELIST *, arg)) + || CvPADLIST(cv)->xpadl_id != (U32)arg) continue; return cv; case FIND_RUNCV_level_eq: @@ -3324,7 +3337,7 @@ S_try_yyparse(pTHX_ int gramtype) default: JMPENV_POP; JMPENV_JUMP(ret); - assert(0); /* NOTREACHED */ + NOT_REACHED; /* NOTREACHED */ } JMPENV_POP; return ret; @@ -3348,7 +3361,7 @@ S_try_yyparse(pTHX_ int gramtype) STATIC bool S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh) { - dVAR; dSP; + dSP; OP * const saveop = PL_op; bool clear_hints = saveop->op_type != OP_ENTEREVAL; COP * const oldcurcop = PL_curcop; @@ -3375,12 +3388,11 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh) /* set up a scratch pad */ - CvPADLIST(evalcv) = pad_new(padnew_SAVE); + CvPADLIST_set(evalcv, pad_new(padnew_SAVE)); PL_op = NULL; /* avoid PL_op and PL_curpad referring to different CVs */ - if (!PL_madskills) - SAVEMORTALIZESV(evalcv); /* must remain until end of current statement */ + SAVEMORTALIZESV(evalcv); /* must remain until end of current statement */ /* make sure we compile in the right package */ @@ -3398,10 +3410,6 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh) PL_unitcheckav = newAV(); SAVEFREESV(PL_unitcheckav); -#ifdef PERL_MAD - SAVEBOOL(PL_madskills); - PL_madskills = 0; -#endif ENTER_with_name("evalcomp"); SAVESPTR(PL_compcv); @@ -3623,7 +3631,7 @@ S_doopen_pm(pTHX_ SV *name) Stat_t pmcstat; SvSetSV_nosteal(pmcsv,name); - sv_catpvn(pmcsv, "c", 1); + sv_catpvs(pmcsv, "c"); if (PerlLIO_stat(SvPV_nolen_const(pmcsv), &pmcstat) >= 0) return check_type_and_open(pmcsv); @@ -3660,9 +3668,12 @@ S_path_is_searchable(const char *name) return TRUE; } + +/* also used for: pp_dofile() */ + PP(pp_require) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; SV *sv; const char *name; @@ -3671,9 +3682,7 @@ PP(pp_require) STRLEN unixlen; #ifdef VMS int vms_unixname = 0; - char *unixnamebuf; char *unixdir; - char *unixdirbuf; #endif const char *tryname = NULL; SV *namesv = NULL; @@ -3684,12 +3693,12 @@ PP(pp_require) SV *filter_state = NULL; SV *filter_sub = NULL; SV *hook_sv = NULL; - SV *encoding; OP *op; int saved_errno; bool path_searchable; sv = POPs; + SvGETMAGIC(sv); if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) { sv = sv_2mortal(new_version(sv)); if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0)) @@ -3714,7 +3723,7 @@ PP(pp_require) first = SvIV(*av_fetch(lav,0,0)); if ( first > (int)PERL_REVISION /* probably 'use 6.0' */ || hv_exists(MUTABLE_HV(req), "qv", 2 ) /* qv style */ - || av_len(lav) > 1 /* FP with > 3 digits */ + || av_tindex(lav) > 1 /* FP with > 3 digits */ || strstr(SvPVX(pv),".0") /* FP with leading 0 */ ) { DIE(aTHX_ "Perl %"SVf" required--this is only " @@ -3727,7 +3736,7 @@ PP(pp_require) SV *hintsv; I32 second = 0; - if (av_len(lav)>=1) + if (av_tindex(lav)>=1) second = SvIV(*av_fetch(lav,1,0)); second /= second >= 600 ? 100 : 10; @@ -3747,9 +3756,12 @@ PP(pp_require) RETPUSHYES; } - name = SvPV_const(sv, len); + if (!SvOK(sv)) + DIE(aTHX_ "Missing or undefined argument to require"); + name = SvPV_nomg_const(sv, len); if (!(name && len > 0 && *name)) - DIE(aTHX_ "Null filename used"); + DIE(aTHX_ "Missing or undefined argument to require"); + if (!IS_SAFE_PATHNAME(name, len, "require")) { DIE(aTHX_ "Can't locate %s: %s", pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv), @@ -3768,8 +3780,9 @@ PP(pp_require) * name can be translated to UNIX. */ - if ((unixnamebuf = SvPVX(sv_2mortal(newSVpv("", VMS_MAXRSS-1)))) - && (unixname = tounixspec(name, unixnamebuf)) != NULL) { + if ((unixname = + tounixspec(name, SvPVX(sv_2mortal(newSVpv("", VMS_MAXRSS-1))))) + != NULL) { unixlen = strlen(unixname); vms_unixname = 1; } @@ -3815,17 +3828,17 @@ PP(pp_require) for (i = 0; i <= AvFILL(ar); i++) { SV * const dirsv = *av_fetch(ar, i, TRUE); - if (SvTIED_mg((const SV *)ar, PERL_MAGIC_tied)) - mg_get(dirsv); + SvGETMAGIC(dirsv); if (SvROK(dirsv)) { int count; SV **svp; SV *loader = dirsv; if (SvTYPE(SvRV(loader)) == SVt_PVAV - && !sv_isobject(loader)) + && !SvOBJECT(SvRV(loader))) { loader = *av_fetch(MUTABLE_AV(SvRV(loader)), 0, TRUE); + SvGETMAGIC(loader); } Perl_sv_setpvf(aTHX_ namesv, "/loader/0x%"UVxf"/%s", @@ -3846,6 +3859,11 @@ PP(pp_require) PUSHs(dirsv); PUSHs(nsv); PUTBACK; + if (SvGMAGICAL(loader)) { + SV *l = sv_newmortal(); + sv_setsv_nomg(l, loader); + loader = l; + } if (sv_isobject(loader)) count = call_method("INC", G_ARRAY); else @@ -3932,11 +3950,11 @@ PP(pp_require) filter_has_file = 0; filter_cache = NULL; if (filter_state) { - SvREFCNT_dec(filter_state); + SvREFCNT_dec_NN(filter_state); filter_state = NULL; } if (filter_sub) { - SvREFCNT_dec(filter_sub); + SvREFCNT_dec_NN(filter_sub); filter_sub = NULL; } } @@ -3946,7 +3964,7 @@ PP(pp_require) STRLEN dirlen; if (SvOK(dirsv)) { - dir = SvPV_const(dirsv, dirlen); + dir = SvPV_nomg_const(dirsv, dirlen); } else { dir = ""; dirlen = 0; @@ -3955,8 +3973,9 @@ PP(pp_require) if (!IS_SAFE_SYSCALL(dir, dirlen, "@INC entry", "require")) continue; #ifdef VMS - if (((unixdirbuf = SvPVX(sv_2mortal(newSVpv("", VMS_MAXRSS-1)))) == NULL) - || ((unixdir = tounixpath(dir, unixdirbuf)) == NULL)) + if ((unixdir = + tounixpath(dir, SvPVX(sv_2mortal(newSVpv("", VMS_MAXRSS-1))))) + == NULL) continue; sv_setpv(namesv, unixdir); sv_catpv(namesv, unixname); @@ -3988,6 +4007,9 @@ PP(pp_require) /* Avoid '//' */ if (!dirlen || *(tmp-1) != '/') { *tmp++ = '/'; + } else { + /* So SvCUR_set reports the correct length below */ + dirlen--; } /* name came from an SV, so it will have a '\0' at the @@ -4028,7 +4050,8 @@ PP(pp_require) if (PL_op->op_type == OP_REQUIRE) { if(saved_errno == EMFILE || saved_errno == EACCES) { /* diag_listed_as: Can't locate %s */ - DIE(aTHX_ "Can't locate %s: %s", name, Strerror(saved_errno)); + DIE(aTHX_ "Can't locate %s: %s: %s", + name, tryname, Strerror(saved_errno)); } else { if (namesv) { /* did we lookup @INC? */ AV * const ar = GvAVn(PL_incgv); @@ -4044,7 +4067,7 @@ PP(pp_require) sv_catpv(msg, " (you may need to install the "); for (c = name; c < e; c++) { if (*c == '/') { - sv_catpvn(msg, "::", 2); + sv_catpvs(msg, "::"); } else { sv_catpvn(msg, c, 1); @@ -4117,18 +4140,11 @@ PP(pp_require) PUTBACK; - /* Store and reset encoding. */ - encoding = PL_encoding; - PL_encoding = NULL; - if (doeval(gimme, NULL, PL_curcop->cop_seq, NULL)) op = DOCATCH(PL_eval_start); else op = PL_op->op_next; - /* Restore encoding. */ - PL_encoding = encoding; - LOADED_FILE_PROBE(unixname); return op; @@ -4140,7 +4156,6 @@ PP(pp_require) PP(pp_hintseval) { - dVAR; dSP; mXPUSHs(MUTABLE_SV(hv_copy_hints_hv(MUTABLE_HV(cSVOP_sv)))); RETURN; @@ -4149,7 +4164,7 @@ PP(pp_hintseval) PP(pp_entereval) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; SV *sv; const I32 gimme = GIMME_V; @@ -4277,7 +4292,7 @@ PP(pp_entereval) PP(pp_leaveeval) { - dVAR; dSP; + dSP; SV **newsp; PMOP *newpm; I32 gimme; @@ -4295,8 +4310,7 @@ PP(pp_leaveeval) retop = cx->blk_eval.retop; evalcv = cx->blk_eval.cv; - TAINT_NOT; - SP = adjust_stack_on_leave((gimme == G_VOID) ? SP : newsp, SP, newsp, + SP = leave_common((gimme == G_VOID) ? SP : newsp, SP, newsp, gimme, SVs_TEMP, FALSE); PL_curpm = newpm; /* Don't pop $1 et al till now */ @@ -4313,8 +4327,8 @@ PP(pp_leaveeval) SvPVX_const(namesv), SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv), G_DISCARD); - retop = Perl_die(aTHX_ "%"SVf" did not return a true value", - SVfARG(namesv)); + Perl_die(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv)); + NOT_REACHED; /* NOTREACHED */ /* die_unwind() did LEAVE, or we won't be here */ } else { @@ -4374,7 +4388,6 @@ Perl_create_eval_scope(pTHX_ U32 flags) PP(pp_entertry) { - dVAR; PERL_CONTEXT * const cx = create_eval_scope(0); cx->blk_eval.retop = cLOGOP->op_other->op_next; return DOCATCH(PL_op->op_next); @@ -4382,7 +4395,7 @@ PP(pp_entertry) PP(pp_leavetry) { - dVAR; dSP; + dSP; SV **newsp; PMOP *newpm; I32 gimme; @@ -4394,8 +4407,7 @@ PP(pp_leavetry) POPEVAL(cx); PERL_UNUSED_VAR(optype); - TAINT_NOT; - SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, + SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE); PL_curpm = newpm; /* Don't pop $1 et al till now */ @@ -4406,7 +4418,7 @@ PP(pp_leavetry) PP(pp_entergiven) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; const I32 gimme = GIMME_V; @@ -4431,7 +4443,7 @@ PP(pp_entergiven) PP(pp_leavegiven) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; I32 gimme; SV **newsp; @@ -4441,8 +4453,7 @@ PP(pp_leavegiven) POPBLOCK(cx,newpm); assert(CxTYPE(cx) == CXt_GIVEN); - TAINT_NOT; - SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, + SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE); PL_curpm = newpm; /* Don't pop $1 et al till now */ @@ -4454,7 +4465,6 @@ PP(pp_leavegiven) STATIC PMOP * S_make_matcher(pTHX_ REGEXP *re) { - dVAR; PMOP *matcher = (PMOP *) newPMOP(OP_MATCH, OPf_WANT_SCALAR | OPf_STACKED); PERL_ARGS_ASSERT_MAKE_MATCHER; @@ -4470,7 +4480,6 @@ S_make_matcher(pTHX_ REGEXP *re) STATIC bool S_matcher_matches_sv(pTHX_ PMOP *matcher, SV *sv) { - dVAR; dSP; PERL_ARGS_ASSERT_MATCHER_MATCHES_SV; @@ -4486,8 +4495,6 @@ S_matcher_matches_sv(pTHX_ PMOP *matcher, SV *sv) STATIC void S_destroy_matcher(pTHX_ PMOP *matcher) { - dVAR; - PERL_ARGS_ASSERT_DESTROY_MATCHER; PERL_UNUSED_ARG(matcher); @@ -4508,7 +4515,6 @@ PP(pp_smartmatch) STATIC OP * S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) { - dVAR; dSP; bool object_on_left = FALSE; @@ -4604,7 +4610,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) SSize_t i; bool andedresults = TRUE; AV *av = (AV*) SvRV(d); - const I32 len = av_len(av); + const I32 len = av_tindex(av); DEBUG_M(Perl_deb(aTHX_ " applying rule Array-CodeRef\n")); if (len == -1) RETPUSHYES; @@ -4663,28 +4669,28 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) /* Check that the key-sets are identical */ HE *he; HV *other_hv = MUTABLE_HV(SvRV(d)); - bool tied = FALSE; - bool other_tied = FALSE; + bool tied; + bool other_tied; U32 this_key_count = 0, other_key_count = 0; HV *hv = MUTABLE_HV(SvRV(e)); DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Hash\n")); /* Tied hashes don't know how many keys they have. */ - if (SvTIED_mg((SV*)hv, PERL_MAGIC_tied)) { - tied = TRUE; - } - else if (SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied)) { - HV * const temp = other_hv; - other_hv = hv; - hv = temp; - tied = TRUE; + tied = cBOOL(SvTIED_mg((SV*)hv, PERL_MAGIC_tied)); + other_tied = cBOOL(SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied)); + if (!tied ) { + if(other_tied) { + /* swap HV sides */ + HV * const temp = other_hv; + other_hv = hv; + hv = temp; + tied = TRUE; + other_tied = FALSE; + } + else if(HvUSEDKEYS((const HV *) hv) != HvUSEDKEYS(other_hv)) + RETPUSHNO; } - if (SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied)) - other_tied = TRUE; - - if (!tied && HvUSEDKEYS((const HV *) hv) != HvUSEDKEYS(other_hv)) - RETPUSHNO; /* The hashes have the same number of keys, so it suffices to check that one is a subset of the other. */ @@ -4716,7 +4722,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) } else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { AV * const other_av = MUTABLE_AV(SvRV(d)); - const SSize_t other_len = av_len(other_av) + 1; + const SSize_t other_len = av_tindex(other_av) + 1; SSize_t i; HV *hv = MUTABLE_HV(SvRV(e)); @@ -4768,7 +4774,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) } else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) { AV * const other_av = MUTABLE_AV(SvRV(e)); - const SSize_t other_len = av_len(other_av) + 1; + const SSize_t other_len = av_tindex(other_av) + 1; SSize_t i; DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Array\n")); @@ -4786,11 +4792,11 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { AV *other_av = MUTABLE_AV(SvRV(d)); DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Array\n")); - if (av_len(MUTABLE_AV(SvRV(e))) != av_len(other_av)) + if (av_tindex(MUTABLE_AV(SvRV(e))) != av_tindex(other_av)) RETPUSHNO; else { SSize_t i; - const SSize_t other_len = av_len(other_av); + const SSize_t other_len = av_tindex(other_av); if (NULL == seen_this) { seen_this = newHV(); @@ -4845,7 +4851,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) sm_regex_array: { PMOP * const matcher = make_matcher((REGEXP*) SvRV(d)); - const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e))); + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); SSize_t i; for(i = 0; i <= this_len; ++i) { @@ -4862,7 +4868,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) } else if (!SvOK(d)) { /* undef ~~ array */ - const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e))); + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); SSize_t i; DEBUG_M(Perl_deb(aTHX_ " applying rule Undef-Array\n")); @@ -4878,7 +4884,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) sm_any_array: { SSize_t i; - const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e))); + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Array\n")); for (i = 0; i <= this_len; ++i) { @@ -4980,7 +4986,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) PP(pp_enterwhen) { - dVAR; dSP; + dSP; PERL_CONTEXT *cx; const I32 gimme = GIMME_V; @@ -5004,7 +5010,7 @@ PP(pp_enterwhen) PP(pp_leavewhen) { - dVAR; dSP; + dSP; I32 cxix; PERL_CONTEXT *cx; I32 gimme; @@ -5020,8 +5026,7 @@ PP(pp_leavewhen) POPBLOCK(cx,newpm); assert(CxTYPE(cx) == CXt_WHEN); - TAINT_NOT; - SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, + SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE); PL_curpm = newpm; /* pop $1 et al */ @@ -5052,7 +5057,7 @@ PP(pp_leavewhen) PP(pp_continue) { - dVAR; dSP; + dSP; I32 cxix; PERL_CONTEXT *cx; I32 gimme; @@ -5080,7 +5085,6 @@ PP(pp_continue) PP(pp_break) { - dVAR; I32 cxix; PERL_CONTEXT *cx; @@ -5192,7 +5196,7 @@ S_doparseform(pTHX_ SV *sv) s++; } noblank = TRUE; - /* FALL THROUGH */ + /* FALLTHROUGH */ case ' ': case '\t': skipspaces++; continue; @@ -5383,7 +5387,6 @@ S_num_overflow(NV value, I32 fldsize, I32 frcsize) static I32 S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen) { - dVAR; SV * const datasv = FILTER_DATA(idx); const int filter_has_file = IoLINES(datasv); SV * const filter_state = MUTABLE_SV(IoTOP_GV(datasv));