X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/92adfbd49af0758bcc9a198cf2df2bd78c4176b9..c51f309cf368f501b8590fd49c5bad910c416040:/pp_hot.c diff --git a/pp_hot.c b/pp_hot.c index f28b042..0b03721 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -120,6 +120,12 @@ PP(pp_sassign) SV * const temp = left; left = right; right = temp; } + else if (PL_op->op_private & OPpASSIGN_STATE) { + if (SvPADSTALE(right)) + SvPADSTALE_off(right); + else + RETURN; /* ignore assignment */ + } if (PL_tainting && PL_tainted && !SvTAINTED(left)) TAINT_NOT; if (PL_op->op_private & OPpASSIGN_CV_TO_GV) { @@ -132,7 +138,7 @@ PP(pp_sassign) assert(SvROK(cv)); } - /* Can do the optimisation if right (LVAUE) is not a typeglob, + /* Can do the optimisation if right (LVALUE) is not a typeglob, left (RVALUE) is a reference to something, and we're in void context. */ if (!got_coderef && gv_type != SVt_PVGV && GIMME_V == G_VOID) { @@ -174,6 +180,10 @@ PP(pp_sassign) LEAVE; } + if (strEQ(GvNAME(right),"isa")) { + GvCVGEN(right) = 0; + ++PL_sub_generation; + } } SvSetMagicSV(right, left); SETs(right); @@ -208,7 +218,7 @@ PP(pp_concat) dPOPTOPssrl; bool lbyte; STRLEN rlen; - const char *rpv = 0; + const char *rpv = NULL; bool rbyte = FALSE; bool rcopied = FALSE; @@ -273,7 +283,8 @@ PP(pp_padsv) XPUSHs(TARG); if (PL_op->op_flags & OPf_MOD) { if (PL_op->op_private & OPpLVAL_INTRO) - SAVECLEARSV(PAD_SVl(PL_op->op_targ)); + if (!(PL_op->op_private & OPpPAD_STATE)) + SAVECLEARSV(PAD_SVl(PL_op->op_targ)); if (PL_op->op_private & OPpDEREF) { PUTBACK; vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF); @@ -350,21 +361,27 @@ PP(pp_eq) ivp = *--SP; } iv = SvIVX(ivp); - if (iv < 0) { + if (iv < 0) /* As uv is a UV, it's >0, so it cannot be == */ SETs(&PL_sv_no); - RETURN; - } - /* we know iv is >= 0 */ - SETs(boolSV((UV)iv == SvUVX(uvp))); + else + /* we know iv is >= 0 */ + SETs(boolSV((UV)iv == SvUVX(uvp))); RETURN; } } } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left == right)); +#else dPOPnv; SETs(boolSV(TOPn == value)); +#endif RETURN; } } @@ -404,7 +421,7 @@ PP(pp_defined) register SV* sv; bool defined; const int op_type = PL_op->op_type; - const int is_dor = (op_type == OP_DOR || op_type == OP_DORASSIGN); + const bool is_dor = (op_type == OP_DOR || op_type == OP_DORASSIGN); if (is_dor) { sv = TOPs; @@ -739,7 +756,11 @@ PP(pp_print) if (MARK <= SP) goto just_say_no; else { - if (PL_ors_sv && SvOK(PL_ors_sv)) + if (PL_op->op_type == OP_SAY) { + if (PerlIO_write(fp, "\n", 1) == 0 || PerlIO_error(fp)) + goto just_say_no; + } + else if (PL_ors_sv && SvOK(PL_ors_sv)) if (!do_print(PL_ors_sv, fp)) /* $\ */ goto just_say_no; @@ -1067,6 +1088,12 @@ PP(pp_aassign) } } } + if (PL_op->op_private & OPpASSIGN_STATE) { + if (SvPADSTALE(*firstlelem)) + SvPADSTALE_off(*firstlelem); + else + RETURN; /* ignore assignment */ + } relem = firstrelem; lelem = firstlelem; @@ -1277,6 +1304,7 @@ PP(pp_match) const I32 oldsave = PL_savestack_ix; I32 update_minmatch = 1; I32 had_zerolen = 0; + U32 gpos = 0; if (PL_op->op_flags & OPf_STACKED) TARG = POPs; @@ -1323,18 +1351,23 @@ PP(pp_match) if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) { MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global); if (mg && mg->mg_len >= 0) { - if (!(rx->reganch & ROPT_GPOS_SEEN)) + if (!(rx->extflags & RXf_GPOS_SEEN)) rx->endp[0] = rx->startp[0] = mg->mg_len; - else if (rx->reganch & ROPT_ANCH_GPOS) { + else if (rx->extflags & RXf_ANCH_GPOS) { r_flags |= REXEC_IGNOREPOS; rx->endp[0] = rx->startp[0] = mg->mg_len; - } - minmatch = (mg->mg_flags & MGf_MINMATCH); + } else if (rx->extflags & RXf_GPOS_FLOAT) + gpos = mg->mg_len; + else + rx->endp[0] = rx->startp[0] = mg->mg_len; + minmatch = (mg->mg_flags & MGf_MINMATCH) ? rx->gofs + 1 : 0; update_minmatch = 0; } } } - if ((!global && rx->nparens) + /* remove comment to get faster /g but possibly unsafe $1 vars after a + match. Test for the unsafe vars will fail as well*/ + if (( /* !global && */ rx->nparens) || SvTEMP(TARG) || PL_sawampersand || (pm->op_pmflags & PMf_EVAL)) r_flags |= REXEC_COPY_STR; if (SvSCREAM(TARG)) @@ -1342,29 +1375,29 @@ PP(pp_match) play_it_again: if (global && rx->startp[0] != -1) { - t = s = rx->endp[0] + truebase; - if ((s + rx->minlen) > strend) + t = s = rx->endp[0] + truebase - rx->gofs; + if ((s + rx->minlen) > strend || s < truebase) goto nope; if (update_minmatch++) minmatch = had_zerolen; } - if (rx->reganch & RE_USE_INTUIT && - DO_UTF8(TARG) == ((rx->reganch & ROPT_UTF8) != 0)) { + if (rx->extflags & RXf_USE_INTUIT && + DO_UTF8(TARG) == ((rx->extflags & RXf_UTF8) != 0)) { /* FIXME - can PL_bostr be made const char *? */ PL_bostr = (char *)truebase; - s = CALLREG_INTUIT_START(aTHX_ rx, TARG, (char *)s, (char *)strend, r_flags, NULL); + s = CALLREG_INTUIT_START(rx, TARG, (char *)s, (char *)strend, r_flags, NULL); if (!s) goto nope; - if ( (rx->reganch & ROPT_CHECK_ALL) + if ( (rx->extflags & RXf_CHECK_ALL) && !PL_sawampersand - && ((rx->reganch & ROPT_NOSCAN) - || !((rx->reganch & RE_INTUIT_TAIL) + && ((rx->extflags & RXf_NOSCAN) + || !((rx->extflags & RXf_INTUIT_TAIL) && (r_flags & REXEC_SCREAM))) && !SvROK(TARG)) /* Cannot trust since INTUIT cannot guess ^ */ goto yup; } - if (CALLREGEXEC(aTHX_ rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NULL, r_flags)) + if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, INT2PTR(void*, gpos), r_flags)) { PL_curpm = pm; if (dynpm->op_pmflags & PMf_ONCE) @@ -1405,19 +1438,23 @@ play_it_again: if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) mg = mg_find(TARG, PERL_MAGIC_regex_global); if (!mg) { - sv_magic(TARG, NULL, PERL_MAGIC_regex_global, NULL, 0); - mg = mg_find(TARG, PERL_MAGIC_regex_global); +#ifdef PERL_OLD_COPY_ON_WRITE + if (SvIsCOW(TARG)) + sv_force_normal_flags(TARG, 0); +#endif + mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global, + &PL_vtbl_mglob, NULL, 0); } if (rx->startp[0] != -1) { mg->mg_len = rx->endp[0]; - if (rx->startp[0] == rx->endp[0]) + if (rx->startp[0] + rx->gofs == (UV)rx->endp[0]) mg->mg_flags |= MGf_MINMATCH; else mg->mg_flags &= ~MGf_MINMATCH; } } had_zerolen = (rx->startp[0] != -1 - && rx->startp[0] == rx->endp[0]); + && rx->startp[0] + rx->gofs == (UV)rx->endp[0]); PUTBACK; /* EVAL blocks may use stack */ r_flags |= REXEC_IGNOREPOS | REXEC_NOT_FIRST; goto play_it_again; @@ -1435,12 +1472,16 @@ play_it_again: else mg = NULL; if (!mg) { - sv_magic(TARG, NULL, PERL_MAGIC_regex_global, NULL, 0); - mg = mg_find(TARG, PERL_MAGIC_regex_global); +#ifdef PERL_OLD_COPY_ON_WRITE + if (SvIsCOW(TARG)) + sv_force_normal_flags(TARG, 0); +#endif + mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global, + &PL_vtbl_mglob, NULL, 0); } if (rx->startp[0] != -1) { mg->mg_len = rx->endp[0]; - if (rx->startp[0] == rx->endp[0]) + if (rx->startp[0] + rx->gofs == (UV)rx->endp[0]) mg->mg_flags |= MGf_MINMATCH; else mg->mg_flags &= ~MGf_MINMATCH; @@ -1466,11 +1507,11 @@ yup: /* Confirmed by INTUIT */ rx->subbeg = (char *) truebase; rx->startp[0] = s - truebase; if (RX_MATCH_UTF8(rx)) { - char * const t = (char*)utf8_hop((U8*)s, rx->minlen); + char * const t = (char*)utf8_hop((U8*)s, rx->minlenret); rx->endp[0] = t - truebase; } else { - rx->endp[0] = s - truebase + rx->minlen; + rx->endp[0] = s - truebase + rx->minlenret; } rx->sublen = strend - truebase; goto gotcha; @@ -1500,11 +1541,11 @@ yup: /* Confirmed by INTUIT */ rx->sublen = strend - t; RX_MATCH_COPIED_on(rx); off = rx->startp[0] = s - t; - rx->endp[0] = off + rx->minlen; + rx->endp[0] = off + rx->minlenret; } else { /* startp/endp are used by @- @+. */ rx->startp[0] = s - truebase; - rx->endp[0] = s - truebase + rx->minlen; + rx->endp[0] = s - truebase + rx->minlenret; } rx->nparens = rx->lastparen = rx->lastcloseparen = 0; /* used by @-, @+, and $^N */ LEAVE_SCOPE(oldsave); @@ -1609,8 +1650,14 @@ Perl_do_readline(pTHX) have_fp: if (gimme == G_SCALAR) { sv = TARG; - if (SvROK(sv)) - sv_unref(sv); + if (type == OP_RCATLINE && SvGMAGICAL(sv)) + mg_get(sv); + if (SvROK(sv)) { + if (type == OP_RCATLINE) + SvPV_force_nolen(sv); + else + sv_unref(sv); + } else if (isGV_with_GP(sv)) { SvPV_force_nolen(sv); } @@ -1701,16 +1748,17 @@ Perl_do_readline(pTHX) continue; } } else if (SvUTF8(sv)) { /* OP_READLINE, OP_RCATLINE */ - const U8 * const s = (const U8*)SvPVX_const(sv) + offset; - const STRLEN len = SvCUR(sv) - offset; - const U8 *f; - - if (ckWARN(WARN_UTF8) && - !is_utf8_string_loc(s, len, &f)) - /* Emulate :encoding(utf8) warning in the same case. */ - Perl_warner(aTHX_ packWARN(WARN_UTF8), - "utf8 \"\\x%02X\" does not map to Unicode", - f < (U8*)SvEND(sv) ? *f : 0); + if (ckWARN(WARN_UTF8)) { + const U8 * const s = (const U8*)SvPVX_const(sv) + offset; + const STRLEN len = SvCUR(sv) - offset; + const U8 *f; + + if (!is_utf8_string_loc(s, len, &f)) + /* Emulate :encoding(utf8) warning in the same case. */ + Perl_warner(aTHX_ packWARN(WARN_UTF8), + "utf8 \"\\x%02X\" does not map to Unicode", + f < (U8*)SvEND(sv) ? *f : 0); + } } if (gimme == G_ARRAY) { if (SvLEN(sv) - SvCUR(sv) > 20) { @@ -1763,32 +1811,28 @@ PP(pp_helem) const U32 hash = (SvIsCOW_shared_hash(keysv)) ? SvSHARED_HASH(keysv) : 0; I32 preeminent = 0; - if (SvTYPE(hv) == SVt_PVHV) { - if (PL_op->op_private & OPpLVAL_INTRO) { - MAGIC *mg; - HV *stash; - /* does the element we're localizing already exist? */ - preeminent = - /* can we determine whether it exists? */ - ( !SvRMAGICAL(hv) - || mg_find((SV*)hv, PERL_MAGIC_env) - || ( (mg = mg_find((SV*)hv, PERL_MAGIC_tied)) - /* Try to preserve the existenceness of a tied hash - * element by using EXISTS and DELETE if possible. - * Fallback to FETCH and STORE otherwise */ - && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg)))) - && gv_fetchmethod_autoload(stash, "EXISTS", TRUE) - && gv_fetchmethod_autoload(stash, "DELETE", TRUE) - ) - ) ? hv_exists_ent(hv, keysv, 0) : 1; - - } - he = hv_fetch_ent(hv, keysv, lval && !defer, hash); - svp = he ? &HeVAL(he) : NULL; - } - else { + if (SvTYPE(hv) != SVt_PVHV) RETPUSHUNDEF; - } + + if (PL_op->op_private & OPpLVAL_INTRO) { + MAGIC *mg; + HV *stash; + /* does the element we're localizing already exist? */ + preeminent = /* can we determine whether it exists? */ + ( !SvRMAGICAL(hv) + || mg_find((SV*)hv, PERL_MAGIC_env) + || ( (mg = mg_find((SV*)hv, PERL_MAGIC_tied)) + /* Try to preserve the existenceness of a tied hash + * element by using EXISTS and DELETE if possible. + * Fallback to FETCH and STORE otherwise */ + && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg)))) + && gv_fetchmethod_autoload(stash, "EXISTS", TRUE) + && gv_fetchmethod_autoload(stash, "DELETE", TRUE) + ) + ) ? hv_exists_ent(hv, keysv, 0) : 1; + } + he = hv_fetch_ent(hv, keysv, lval && !defer, hash); + svp = he ? &HeVAL(he) : NULL; if (lval) { if (!svp || *svp == &PL_sv_undef) { SV* lv; @@ -1813,7 +1857,8 @@ PP(pp_helem) if (!preeminent) { STRLEN keylen; const char * const key = SvPV_const(keysv, keylen); - SAVEDELETE(hv, savepvn(key,keylen), keylen); + SAVEDELETE(hv, savepvn(key,keylen), + SvUTF8(keysv) ? -(I32)keylen : (I32)keylen); } else save_helem(hv, keysv, svp); } @@ -1912,7 +1957,9 @@ PP(pp_iter) /* string increment */ register SV* cur = cx->blk_loop.iterlval; STRLEN maxlen = 0; - const char *max = SvOK((SV*)av) ? SvPV_const((SV*)av, maxlen) : ""; + const char *max = + SvOK((SV*)av) ? + SvPV_const((SV*)av, maxlen) : (const char *)""; if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) { if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) { /* safe to reuse old SV */ @@ -2110,17 +2157,17 @@ PP(pp_subst) r_flags |= REXEC_SCREAM; orig = m = s; - if (rx->reganch & RE_USE_INTUIT) { + if (rx->extflags & RXf_USE_INTUIT) { PL_bostr = orig; - s = CALLREG_INTUIT_START(aTHX_ rx, TARG, s, strend, r_flags, NULL); + s = CALLREG_INTUIT_START(rx, TARG, s, strend, r_flags, NULL); if (!s) goto nope; /* How to do it in subst? */ -/* if ( (rx->reganch & ROPT_CHECK_ALL) +/* if ( (rx->extflags & RXf_CHECK_ALL) && !PL_sawampersand - && ((rx->reganch & ROPT_NOSCAN) - || !((rx->reganch & RE_INTUIT_TAIL) + && ((rx->extflags & RXf_NOSCAN) + || !((rx->extflags & RXf_INTUIT_TAIL) && (r_flags & REXEC_SCREAM)))) goto yup; */ @@ -2157,10 +2204,10 @@ PP(pp_subst) #ifdef PERL_OLD_COPY_ON_WRITE && !is_cow #endif - && (I32)clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR)) - && !(rx->reganch & ROPT_LOOKBEHIND_SEEN) + && (I32)clen <= rx->minlenret && (once || !(r_flags & REXEC_COPY_STR)) + && !(rx->extflags & RXf_LOOKBEHIND_SEEN) && (!doutf8 || SvUTF8(TARG))) { - if (!CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, + if (!CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL, r_flags | REXEC_CHECKED)) { SPAGAIN; @@ -2238,7 +2285,7 @@ PP(pp_subst) d += clen; } s = rx->endp[0] + orig; - } while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m, + } while (CALLREGEXEC(rx, s, strend, orig, s == m, TARG, NULL, /* don't match same null twice */ REXEC_NOT_FIRST|REXEC_IGNOREPOS)); @@ -2265,7 +2312,7 @@ PP(pp_subst) RETURN; } - if (CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, + if (CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL, r_flags | REXEC_CHECKED)) { if (force_on_match) { @@ -2278,13 +2325,13 @@ PP(pp_subst) #endif rxtainted |= RX_MATCH_TAINTED(rx); dstr = newSVpvn(m, s-m); + SAVEFREESV(dstr); if (DO_UTF8(TARG)) SvUTF8_on(dstr); PL_curpm = pm; if (!c) { register PERL_CONTEXT *cx; SPAGAIN; - (void)ReREFCNT_inc(rx); PUSHSUBST(cx); RETURNOP(cPMOP->op_pmreplroot); } @@ -2310,7 +2357,7 @@ PP(pp_subst) sv_catpvn(dstr, c, clen); if (once) break; - } while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m, + } while (CALLREGEXEC(rx, s, strend, orig, s == m, TARG, NULL, r_flags)); if (doutf8 && !DO_UTF8(TARG)) sv_catpvn_utf8_upgrade(dstr, s, strend - s, nsv); @@ -2335,7 +2382,6 @@ PP(pp_subst) SvLEN_set(TARG, SvLEN(dstr)); doutf8 |= DO_UTF8(dstr); SvPV_set(dstr, NULL); - sv_free(dstr); TAINT_IF(rxtainted & 1); SPAGAIN; @@ -2508,7 +2554,7 @@ PP(pp_leavesublv) EXTEND_MORTAL(SP - newsp); for (mark = newsp + 1; mark <= SP; mark++) { if (SvTEMP(*mark)) - /*EMPTY*/; + NOOP; else if (SvFLAGS(*mark) & (SVs_PADTMP | SVf_READONLY)) *mark = sv_mortalcopy(*mark); else { @@ -2636,45 +2682,6 @@ PP(pp_leavesublv) return cx->blk_sub.retop; } - -STATIC CV * -S_get_db_sub(pTHX_ SV **svp, CV *cv) -{ - dVAR; - SV * const dbsv = GvSVn(PL_DBsub); - - save_item(dbsv); - if (!PERLDB_SUB_NN) { - GV * const gv = CvGV(cv); - - if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) - || strEQ(GvNAME(gv), "END") - || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */ - !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) ))) { - /* Use GV from the stack as a fallback. */ - /* GV is potentially non-unique, or contain different CV. */ - SV * const tmp = newRV((SV*)cv); - sv_setsv(dbsv, tmp); - SvREFCNT_dec(tmp); - } - else { - gv_efullname3(dbsv, gv, NULL); - } - } - else { - const int type = SvTYPE(dbsv); - if (type < SVt_PVIV && type != SVt_IV) - sv_upgrade(dbsv, SVt_PVIV); - (void)SvIOK_on(dbsv); - SvIV_set(dbsv, PTR2IV(cv)); /* Do it the quickest way */ - } - - if (CvISXSUB(cv)) - PL_curcopdb = PL_curcop; - cv = GvCV(PL_DBsub); - return cv; -} - PP(pp_entersub) { dVAR; dSP; dPOPss; @@ -2769,7 +2776,7 @@ try_autoload: else { sub_name = sv_newmortal(); gv_efullname3(sub_name, gv, NULL); - DIE(aTHX_ "Undefined subroutine &%"SVf" called", sub_name); + DIE(aTHX_ "Undefined subroutine &%"SVf" called", (void*)sub_name); } } if (!cv) @@ -2782,7 +2789,11 @@ try_autoload: if (CvASSERTION(cv) && PL_DBassertion) sv_setiv(PL_DBassertion, 1); - cv = get_db_sub(&sv, cv); + Perl_get_db_sub(aTHX_ &sv, cv); + if (CvISXSUB(cv)) + PL_curcopdb = PL_curcop; + cv = GvCV(PL_DBsub); + if (!cv || (!CvXSUB(cv) && !CvSTART(cv))) DIE(aTHX_ "No DB::sub routine defined"); } @@ -2807,8 +2818,7 @@ try_autoload: } SAVECOMPPAD(); PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv)); - if (hasargs) - { + if (hasargs) { AV* const av = (AV*)PAD_SVl(0); if (AvREAL(av)) { /* @_ is normally not REAL--this should only ever @@ -2827,13 +2837,13 @@ try_autoload: SV **ary = AvALLOC(av); if (AvARRAY(av) != ary) { AvMAX(av) += AvARRAY(av) - AvALLOC(av); - SvPV_set(av, (char*)ary); + AvARRAY(av) = ary; } if (items > AvMAX(av) + 1) { AvMAX(av) = items - 1; Renew(ary,items,SV*); AvALLOC(av) = ary; - SvPV_set(av, (char*)ary); + AvARRAY(av) = ary; } } Copy(MARK,AvARRAY(av),items,SV*); @@ -2859,42 +2869,43 @@ try_autoload: RETURNOP(CvSTART(cv)); } else { - I32 markix = TOPMARK; + I32 markix = TOPMARK; - PUTBACK; + PUTBACK; - if (!hasargs) { - /* Need to copy @_ to stack. Alternative may be to - * switch stack to @_, and copy return values - * back. This would allow popping @_ in XSUB, e.g.. XXXX */ - AV * const av = GvAV(PL_defgv); - const I32 items = AvFILLp(av) + 1; /* @_ is not tieable */ - - if (items) { - /* Mark is at the end of the stack. */ - EXTEND(SP, items); - Copy(AvARRAY(av), SP + 1, items, SV*); - SP += items; - PUTBACK ; - } - } - /* We assume first XSUB in &DB::sub is the called one. */ - if (PL_curcopdb) { - SAVEVPTR(PL_curcop); - PL_curcop = PL_curcopdb; - PL_curcopdb = NULL; - } - /* Do we need to open block here? XXXX */ + if (!hasargs) { + /* Need to copy @_ to stack. Alternative may be to + * switch stack to @_, and copy return values + * back. This would allow popping @_ in XSUB, e.g.. XXXX */ + AV * const av = GvAV(PL_defgv); + const I32 items = AvFILLp(av) + 1; /* @_ is not tieable */ + + if (items) { + /* Mark is at the end of the stack. */ + EXTEND(SP, items); + Copy(AvARRAY(av), SP + 1, items, SV*); + SP += items; + PUTBACK ; + } + } + /* We assume first XSUB in &DB::sub is the called one. */ + if (PL_curcopdb) { + SAVEVPTR(PL_curcop); + PL_curcop = PL_curcopdb; + PL_curcopdb = NULL; + } + /* Do we need to open block here? XXXX */ + if (CvXSUB(cv)) /* XXX this is supposed to be true */ (void)(*CvXSUB(cv))(aTHX_ cv); - /* Enforce some sanity in scalar context. */ - if (gimme == G_SCALAR && ++markix != PL_stack_sp - PL_stack_base ) { - if (markix > PL_stack_sp - PL_stack_base) - *(PL_stack_base + markix) = &PL_sv_undef; - else - *(PL_stack_base + markix) = *PL_stack_sp; - PL_stack_sp = PL_stack_base + markix; - } + /* Enforce some sanity in scalar context. */ + if (gimme == G_SCALAR && ++markix != PL_stack_sp - PL_stack_base ) { + if (markix > PL_stack_sp - PL_stack_base) + *(PL_stack_base + markix) = &PL_sv_undef; + else + *(PL_stack_base + markix) = *PL_stack_sp; + PL_stack_sp = PL_stack_base + markix; + } LEAVE; return NORMAL; } @@ -2909,7 +2920,7 @@ Perl_sub_crush_depth(pTHX_ CV *cv) SV* const tmpstr = sv_newmortal(); gv_efullname3(tmpstr, CvGV(cv), NULL); Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on subroutine \"%"SVf"\"", - tmpstr); + (void*)tmpstr); } } @@ -2925,9 +2936,11 @@ PP(pp_aelem) SV *sv; if (SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC)) - Perl_warner(aTHX_ packWARN(WARN_MISC), "Use of reference \"%"SVf"\" as array index", elemsv); + Perl_warner(aTHX_ packWARN(WARN_MISC), + "Use of reference \"%"SVf"\" as array index", + (void*)elemsv); if (elem > 0) - elem -= PL_curcop->cop_arybase; + elem -= CopARYBASE_get(PL_curcop); if (SvTYPE(av) != SVt_PVAV) RETPUSHUNDEF; svp = av_fetch(av, elem, lval && !defer); @@ -3081,7 +3094,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp) if (!stash) packsv = sv; else { - SV* ref = newSViv(PTR2IV(stash)); + SV* const ref = newSViv(PTR2IV(stash)); hv_store(PL_stashcache, packname, packlen, ref, 0); } goto fetch;