X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=304fced051a8fef05ebf87ca498584f0d1ced100;hb=6bc89f92370990b836308b02c6551b4e758e7401;hp=53ddb0ca4aee9abe222256c9831c46fe22b7acba;hpb=6f9b16a7d2fe9614c783e2d5785df2cd8d7921a0;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index 53ddb0c..304fced 100644 --- a/pp.c +++ b/pp.c @@ -1,7 +1,7 @@ /* pp.c * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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. @@ -47,6 +47,7 @@ extern Pid_t getpid (void); PP(pp_stub) { + dVAR; dSP; if (GIMME_V == G_SCALAR) XPUSHs(&PL_sv_undef); @@ -57,7 +58,7 @@ PP(pp_stub) PP(pp_padav) { - dSP; dTARGET; + dVAR; dSP; dTARGET; I32 gimme; if (PL_op->op_private & OPpLVAL_INTRO) SAVECLEARSV(PAD_SVl(PL_op->op_targ)); @@ -78,7 +79,7 @@ PP(pp_padav) if (SvMAGICAL(TARG)) { U32 i; for (i=0; i < (U32)maxarg; i++) { - SV ** const svp = av_fetch((AV*)TARG, i, FALSE); + SV * const * const svp = av_fetch((AV*)TARG, i, FALSE); SP[i+1] = (svp) ? *svp : &PL_sv_undef; } } @@ -98,7 +99,7 @@ PP(pp_padav) PP(pp_padhv) { - dSP; dTARGET; + dVAR; dSP; dTARGET; I32 gimme; XPUSHs(TARG); @@ -126,7 +127,7 @@ PP(pp_padhv) PP(pp_rv2gv) { - dSP; dTOPss; + dVAR; dSP; dTOPss; if (SvROK(sv)) { wasref: @@ -160,13 +161,13 @@ PP(pp_rv2gv) GV *gv; if (cUNOP->op_targ) { STRLEN len; - SV *namesv = PAD_SV(cUNOP->op_targ); - const char *name = SvPV(namesv, len); + SV * const namesv = PAD_SV(cUNOP->op_targ); + const char * const name = SvPV(namesv, len); gv = (GV*)NEWSV(0,0); gv_init(gv, CopSTASH(PL_curcop), name, len, 0); } else { - const char *name = CopSTASHPV(PL_curcop); + const char * const name = CopSTASHPV(PL_curcop); gv = newGVgen(name); } if (SvTYPE(sv) < SVt_RV) @@ -191,10 +192,10 @@ PP(pp_rv2gv) if ((PL_op->op_flags & OPf_SPECIAL) && !(PL_op->op_flags & OPf_MOD)) { - SV * const temp = (SV*)gv_fetchsv(sv, FALSE, SVt_PVGV); + SV * const temp = (SV*)gv_fetchsv(sv, 0, SVt_PVGV); if (!temp && (!is_gv_magical_sv(sv,0) - || !(sv = (SV*)gv_fetchsv(sv, TRUE, SVt_PVGV)))) { + || !(sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV)))) { RETSETUNDEF; } sv = temp; @@ -202,7 +203,14 @@ PP(pp_rv2gv) else { if (PL_op->op_private & HINT_STRICT_REFS) DIE(aTHX_ PL_no_symref_sv, sv, "a symbol"); - sv = (SV*)gv_fetchsv(sv, TRUE, SVt_PVGV); + if ((PL_op->op_private & (OPpLVAL_INTRO|OPpDONT_INIT_GV)) + == OPpDONT_INIT_GV) { + /* We are the target of a coderef assignment. Return + the scalar unchanged, and let pp_sasssign deal with + things. */ + RETURN; + } + sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV); } } } @@ -214,8 +222,8 @@ PP(pp_rv2gv) PP(pp_rv2sv) { - GV *gv = Nullgv; - dSP; dTOPss; + dVAR; dSP; dTOPss; + GV *gv = NULL; if (SvROK(sv)) { wasref: @@ -238,9 +246,14 @@ PP(pp_rv2sv) if (SvROK(sv)) goto wasref; } + if (PL_op->op_private & HINT_STRICT_REFS) { + if (SvOK(sv)) + DIE(aTHX_ PL_no_symref_sv, sv, "a SCALAR"); + else + DIE(aTHX_ PL_no_usym, "a SCALAR"); + } if (!SvOK(sv)) { - if (PL_op->op_flags & OPf_REF || - PL_op->op_private & HINT_STRICT_REFS) + if (PL_op->op_flags & OPf_REF) DIE(aTHX_ PL_no_usym, "a SCALAR"); if (ckWARN(WARN_UNINITIALIZED)) report_uninit(sv); @@ -249,18 +262,16 @@ PP(pp_rv2sv) if ((PL_op->op_flags & OPf_SPECIAL) && !(PL_op->op_flags & OPf_MOD)) { - gv = (GV*)gv_fetchsv(sv, FALSE, SVt_PV); + gv = (GV*)gv_fetchsv(sv, 0, SVt_PV); if (!gv && (!is_gv_magical_sv(sv, 0) - || !(gv = (GV*)gv_fetchsv(sv, TRUE, SVt_PV)))) + || !(gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV)))) { RETSETUNDEF; } } else { - if (PL_op->op_private & HINT_STRICT_REFS) - DIE(aTHX_ PL_no_symref_sv, sv, "a SCALAR"); - gv = (GV*)gv_fetchsv(sv, TRUE, SVt_PV); + gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV); } } sv = GvSVn(gv); @@ -283,13 +294,13 @@ PP(pp_rv2sv) PP(pp_av2arylen) { - dSP; + dVAR; dSP; AV * const av = (AV*)TOPs; SV ** const sv = Perl_av_arylen_p(aTHX_ (AV*)av); if (!*sv) { *sv = NEWSV(0,0); sv_upgrade(*sv, SVt_PVMG); - sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, Nullch, 0); + sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, NULL, 0); } SETs(*sv); RETURN; @@ -297,12 +308,12 @@ PP(pp_av2arylen) PP(pp_pos) { - dSP; dTARGET; dPOPss; + dVAR; dSP; dTARGET; dPOPss; if (PL_op->op_flags & OPf_MOD || LVRET) { if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); - sv_magic(TARG, Nullsv, PERL_MAGIC_pos, Nullch, 0); + sv_magic(TARG, NULL, PERL_MAGIC_pos, NULL, 0); } LvTYPE(TARG) = '.'; @@ -331,13 +342,18 @@ PP(pp_pos) PP(pp_rv2cv) { - dSP; + dVAR; dSP; GV *gv; HV *stash; - + const I32 flags = (PL_op->op_flags & OPf_SPECIAL) + ? 0 + : ((PL_op->op_private & (OPpLVAL_INTRO|OPpMAY_RETURN_CONSTANT)) == OPpMAY_RETURN_CONSTANT) + ? GV_ADD|GV_NOEXPAND + : GV_ADD; /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */ /* (But not in defined().) */ - CV *cv = sv_2cv(TOPs, &stash, &gv, !(PL_op->op_flags & OPf_SPECIAL)); + + CV *cv = sv_2cv(TOPs, &stash, &gv, flags); if (cv) { if (CvCLONE(cv)) cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); @@ -348,6 +364,9 @@ PP(pp_rv2cv) DIE(aTHX_ "Can't modify non-lvalue subroutine call"); } } + else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) { + cv = (CV*)gv; + } else cv = (CV*)&PL_sv_undef; SETs((SV*)cv); @@ -356,15 +375,14 @@ PP(pp_rv2cv) PP(pp_prototype) { - dSP; + dVAR; dSP; CV *cv; HV *stash; GV *gv; - SV *ret; + SV *ret = &PL_sv_undef; - ret = &PL_sv_undef; if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) { - const char *s = SvPVX_const(TOPs); + const char * const s = SvPVX_const(TOPs); if (strnEQ(s, "CORE::", 6)) { const int code = keyword(s + 6, SvCUR(TOPs) - 6); if (code < 0) { /* Overridable. */ @@ -413,7 +431,7 @@ PP(pp_prototype) } } } - cv = sv_2cv(TOPs, &stash, &gv, FALSE); + cv = sv_2cv(TOPs, &stash, &gv, 0); if (cv && SvPOK(cv)) ret = sv_2mortal(newSVpvn(SvPVX_const(cv), SvCUR(cv))); set: @@ -423,7 +441,7 @@ PP(pp_prototype) PP(pp_anoncode) { - dSP; + dVAR; dSP; CV* cv = (CV*)PAD_SV(PL_op->op_targ); if (CvCLONE(cv)) cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); @@ -434,14 +452,14 @@ PP(pp_anoncode) PP(pp_srefgen) { - dSP; + dVAR; dSP; *SP = refto(*SP); RETURN; } PP(pp_refgen) { - dSP; dMARK; + dVAR; dSP; dMARK; if (GIMME != G_ARRAY) { if (++MARK <= SP) *MARK = *SP; @@ -460,6 +478,7 @@ PP(pp_refgen) STATIC SV* S_refto(pTHX_ SV *sv) { + dVAR; SV* rv; if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') { @@ -491,7 +510,7 @@ S_refto(pTHX_ SV *sv) PP(pp_ref) { - dSP; dTARGET; + dVAR; dSP; dTARGET; const char *pv; SV * const sv = POPs; @@ -508,7 +527,7 @@ PP(pp_ref) PP(pp_bless) { - dSP; + dVAR; dSP; HV *stash; if (MAXARG == 1) @@ -533,14 +552,14 @@ PP(pp_bless) PP(pp_gelem) { - dSP; + dVAR; dSP; SV *sv = POPs; const char * const elem = SvPV_nolen_const(sv); GV * const gv = (GV*)POPs; - SV * tmpRef = Nullsv; + SV * tmpRef = NULL; - sv = Nullsv; + sv = NULL; if (elem) { /* elem will always be NUL terminated. */ const char * const second_letter = elem + 1; @@ -581,8 +600,9 @@ PP(pp_gelem) break; case 'P': if (strEQ(second_letter, "ACKAGE")) { - const HEK *hek = HvNAME_HEK(GvSTASH(gv)); - sv = hek ? newSVhek(hek) : newSVpvn("__ANON__", 8); + const HV * const stash = GvSTASH(gv); + const HEK * const hek = stash ? HvNAME_HEK(stash) : NULL; + sv = hek ? newSVhek(hek) : newSVpvs("__ANON__"); } break; case 'S': @@ -605,7 +625,7 @@ PP(pp_gelem) PP(pp_study) { - dSP; dPOPss; + dVAR; dSP; dPOPss; register unsigned char *s; register I32 pos; register I32 ch; @@ -662,13 +682,13 @@ PP(pp_study) SvSCREAM_on(sv); /* piggyback on m//g magic */ - sv_magic(sv, Nullsv, PERL_MAGIC_regex_global, Nullch, 0); + sv_magic(sv, NULL, PERL_MAGIC_regex_global, NULL, 0); RETPUSHYES; } PP(pp_trans) { - dSP; dTARG; + dVAR; dSP; dTARG; SV *sv; if (PL_op->op_flags & OPf_STACKED) @@ -688,7 +708,7 @@ PP(pp_trans) PP(pp_schop) { - dSP; dTARGET; + dVAR; dSP; dTARGET; do_chop(TARG, TOPs); SETTARG; RETURN; @@ -696,7 +716,7 @@ PP(pp_schop) PP(pp_chop) { - dSP; dMARK; dTARGET; dORIGMARK; + dVAR; dSP; dMARK; dTARGET; dORIGMARK; while (MARK < SP) do_chop(TARG, *++MARK); SP = ORIGMARK; @@ -706,14 +726,14 @@ PP(pp_chop) PP(pp_schomp) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SETi(do_chomp(TOPs)); RETURN; } PP(pp_chomp) { - dSP; dMARK; dTARGET; + dVAR; dSP; dMARK; dTARGET; register I32 count = 0; while (SP > MARK) @@ -724,7 +744,7 @@ PP(pp_chomp) PP(pp_undef) { - dSP; + dVAR; dSP; SV *sv; if (!PL_op->op_private) { @@ -755,7 +775,7 @@ PP(pp_undef) case SVt_PVFM: { /* let user-undef'd sub keep its identity */ - GV* gv = CvGV((CV*)sv); + GV* const gv = CvGV((CV*)sv); cv_undef((CV*)sv); CvGV((CV*)sv) = gv; } @@ -777,7 +797,7 @@ PP(pp_undef) default: if (SvTYPE(sv) >= SVt_PV && SvPVX_const(sv) && SvLEN(sv)) { SvPV_free(sv); - SvPV_set(sv, Nullch); + SvPV_set(sv, NULL); SvLEN_set(sv, 0); } SvOK_off(sv); @@ -789,7 +809,7 @@ PP(pp_undef) PP(pp_predec) { - dSP; + dVAR; dSP; if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV) DIE(aTHX_ PL_no_modify); if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) @@ -806,7 +826,7 @@ PP(pp_predec) PP(pp_postinc) { - dSP; dTARGET; + dVAR; dSP; dTARGET; if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV) DIE(aTHX_ PL_no_modify); sv_setsv(TARG, TOPs); @@ -828,7 +848,7 @@ PP(pp_postinc) PP(pp_postdec) { - dSP; dTARGET; + dVAR; dSP; dTARGET; if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV) DIE(aTHX_ PL_no_modify); sv_setsv(TARG, TOPs); @@ -849,7 +869,7 @@ PP(pp_postdec) PP(pp_pow) { - dSP; dATARGET; + dVAR; dSP; dATARGET; #ifdef PERL_PRESERVE_IVUV bool is_int = 0; #endif @@ -978,7 +998,7 @@ PP(pp_pow) PP(pp_multiply) { - dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); #ifdef PERL_PRESERVE_IVUV SvIV_please(TOPs); if (SvIOK(TOPs)) { @@ -1031,7 +1051,7 @@ PP(pp_multiply) } else if (!ahigh && !bhigh) { /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001 so the unsigned multiply cannot overflow. */ - UV product = alow * blow; + const UV product = alow * blow; if (auvok == buvok) { /* -ve * -ve or +ve * +ve gives a +ve result. */ SP--; @@ -1096,7 +1116,7 @@ PP(pp_multiply) PP(pp_divide) { - dSP; dATARGET; tryAMAGICbin(div,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(div,opASSIGN); /* Only try to do UV divide first if ((SLOPPYDIVIDE is true) or (PERL_PRESERVE_IVUV is true and one or both SV is a UV too large @@ -1211,7 +1231,7 @@ PP(pp_divide) PP(pp_modulo) { - dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN); { UV left = 0; UV right = 0; @@ -1260,7 +1280,7 @@ PP(pp_modulo) if (!left_neg) { left = SvUVX(POPs); } else { - IV aiv = SvIVX(POPs); + const IV aiv = SvIVX(POPs); if (aiv >= 0) { left = aiv; left_neg = FALSE; /* effectively it's a UV now */ @@ -1339,7 +1359,7 @@ PP(pp_modulo) PP(pp_repeat) { - dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN); { register IV count; dPOPss; @@ -1352,7 +1372,7 @@ PP(pp_repeat) else count = uv; } else { - IV iv = SvIV(sv); + const IV iv = SvIV(sv); if (iv < 0) count = 0; else @@ -1370,12 +1390,10 @@ PP(pp_repeat) count = SvIVx(sv); if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) { dMARK; - I32 items = SP - MARK; - I32 max; - static const char oom_list_extend[] = - "Out of memory during list extend"; + static const char oom_list_extend[] = "Out of memory during list extend"; + const I32 items = SP - MARK; + const I32 max = items * count; - max = items * count; MEM_WRAP_CHECK_1(max, SV*, oom_list_extend); /* Did the max computation overflow? */ if (items > 0 && max > 0 && (max < items || max < count)) @@ -1421,7 +1439,7 @@ PP(pp_repeat) SP -= items; } else { /* Note: mark already snarfed by pp_list */ - SV *tmpstr = POPs; + SV * const tmpstr = POPs; STRLEN len; bool isutf; static const char oom_string_extend[] = @@ -1434,7 +1452,7 @@ PP(pp_repeat) if (count < 1) SvCUR_set(TARG, 0); else { - STRLEN max = (UV)count * len; + const STRLEN max = (UV)count * len; if (len > ((MEM_SIZE)~0)/count) Perl_croak(aTHX_ oom_string_extend); MEM_WRAP_CHECK_1(max, char, oom_string_extend); @@ -1466,7 +1484,7 @@ PP(pp_repeat) PP(pp_subtract) { - dSP; dATARGET; bool useleft; tryAMAGICbin(subtr,opASSIGN); + dVAR; dSP; dATARGET; bool useleft; tryAMAGICbin(subtr,opASSIGN); useleft = USE_LEFT(TOPm1s); #ifdef PERL_PRESERVE_IVUV /* See comments in pp_add (in pp_hot.c) about Overflow, and how @@ -1583,15 +1601,15 @@ PP(pp_subtract) PP(pp_left_shift) { - dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN); { const IV shift = POPi; if (PL_op->op_private & HINT_INTEGER) { - IV i = TOPi; + const IV i = TOPi; SETi(i << shift); } else { - UV u = TOPu; + const UV u = TOPu; SETu(u << shift); } RETURN; @@ -1600,15 +1618,15 @@ PP(pp_left_shift) PP(pp_right_shift) { - dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN); { const IV shift = POPi; if (PL_op->op_private & HINT_INTEGER) { - IV i = TOPi; + const IV i = TOPi; SETi(i >> shift); } else { - UV u = TOPu; + const UV u = TOPu; SETu(u >> shift); } RETURN; @@ -1617,7 +1635,7 @@ PP(pp_right_shift) PP(pp_lt) { - dSP; tryAMAGICbinSET(lt,0); + dVAR; dSP; tryAMAGICbinSET(lt,0); #ifdef PERL_PRESERVE_IVUV SvIV_please(TOPs); if (SvIOK(TOPs)) { @@ -1692,7 +1710,7 @@ PP(pp_lt) PP(pp_gt) { - dSP; tryAMAGICbinSET(gt,0); + dVAR; dSP; tryAMAGICbinSET(gt,0); #ifdef PERL_PRESERVE_IVUV SvIV_please(TOPs); if (SvIOK(TOPs)) { @@ -1768,7 +1786,7 @@ PP(pp_gt) PP(pp_le) { - dSP; tryAMAGICbinSET(le,0); + dVAR; dSP; tryAMAGICbinSET(le,0); #ifdef PERL_PRESERVE_IVUV SvIV_please(TOPs); if (SvIOK(TOPs)) { @@ -1844,7 +1862,7 @@ PP(pp_le) PP(pp_ge) { - dSP; tryAMAGICbinSET(ge,0); + dVAR; dSP; tryAMAGICbinSET(ge,0); #ifdef PERL_PRESERVE_IVUV SvIV_please(TOPs); if (SvIOK(TOPs)) { @@ -1920,7 +1938,7 @@ PP(pp_ge) PP(pp_ne) { - dSP; tryAMAGICbinSET(ne,0); + dVAR; dSP; tryAMAGICbinSET(ne,0); #ifndef NV_PRESERVES_UV if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) { SP--; @@ -1933,8 +1951,8 @@ PP(pp_ne) if (SvIOK(TOPs)) { SvIV_please(TOPm1s); if (SvIOK(TOPm1s)) { - bool auvok = SvUOK(TOPm1s); - bool buvok = SvUOK(TOPs); + const bool auvok = SvUOK(TOPm1s); + const bool buvok = SvUOK(TOPs); if (auvok == buvok) { /* ## IV == IV or UV == UV ## */ /* Casting IV to UV before comparison isn't going to matter @@ -1989,11 +2007,11 @@ PP(pp_ne) PP(pp_ncmp) { - dSP; dTARGET; tryAMAGICbin(ncmp,0); + dVAR; dSP; dTARGET; tryAMAGICbin(ncmp,0); #ifndef NV_PRESERVES_UV if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) { - UV right = PTR2UV(SvRV(POPs)); - UV left = PTR2UV(SvRV(TOPs)); + const UV right = PTR2UV(SvRV(POPs)); + const UV left = PTR2UV(SvRV(TOPs)); SETi((left > right) - (left < right)); RETURN; } @@ -2091,61 +2109,47 @@ PP(pp_ncmp) } } -PP(pp_slt) +PP(pp_sle) { - dSP; tryAMAGICbinSET_var(slt_amg,0); - { - dPOPTOPssrl; - const int cmp = (IN_LOCALE_RUNTIME - ? sv_cmp_locale(left, right) - : sv_cmp(left, right)); - SETs(boolSV(cmp < 0)); - RETURN; - } -} + dVAR; dSP; -PP(pp_sgt) -{ - dSP; tryAMAGICbinSET_var(sgt_amg,0); - { - dPOPTOPssrl; - const int cmp = (IN_LOCALE_RUNTIME - ? sv_cmp_locale(left, right) - : sv_cmp(left, right)); - SETs(boolSV(cmp > 0)); - RETURN; - } -} + int amg_type = sle_amg; + int multiplier = 1; + int rhs = 1; -PP(pp_sle) -{ - dSP; tryAMAGICbinSET_var(sle_amg,0); - { - dPOPTOPssrl; - const int cmp = (IN_LOCALE_RUNTIME - ? sv_cmp_locale(left, right) - : sv_cmp(left, right)); - SETs(boolSV(cmp <= 0)); - RETURN; + switch (PL_op->op_type) { + case OP_SLT: + amg_type = slt_amg; + /* cmp < 0 */ + rhs = 0; + break; + case OP_SGT: + amg_type = sgt_amg; + /* cmp > 0 */ + multiplier = -1; + rhs = 0; + break; + case OP_SGE: + amg_type = sge_amg; + /* cmp >= 0 */ + multiplier = -1; + break; } -} -PP(pp_sge) -{ - dSP; tryAMAGICbinSET_var(sge_amg,0); + tryAMAGICbinSET_var(amg_type,0); { dPOPTOPssrl; const int cmp = (IN_LOCALE_RUNTIME ? sv_cmp_locale(left, right) : sv_cmp(left, right)); - SETs(boolSV(cmp >= 0)); + SETs(boolSV(cmp * multiplier < rhs)); RETURN; } } PP(pp_seq) { - dSP; tryAMAGICbinSET(seq,0); + dVAR; dSP; tryAMAGICbinSET(seq,0); { dPOPTOPssrl; SETs(boolSV(sv_eq(left, right))); @@ -2155,7 +2159,7 @@ PP(pp_seq) PP(pp_sne) { - dSP; tryAMAGICbinSET(sne,0); + dVAR; dSP; tryAMAGICbinSET(sne,0); { dPOPTOPssrl; SETs(boolSV(!sv_eq(left, right))); @@ -2165,7 +2169,7 @@ PP(pp_sne) PP(pp_scmp) { - dSP; dTARGET; tryAMAGICbin(scmp,0); + dVAR; dSP; dTARGET; tryAMAGICbin(scmp,0); { dPOPTOPssrl; const int cmp = (IN_LOCALE_RUNTIME @@ -2178,7 +2182,7 @@ PP(pp_scmp) PP(pp_bit_and) { - dSP; dATARGET; tryAMAGICbin(band,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(band,opASSIGN); { dPOPTOPssrl; SvGETMAGIC(left); @@ -2203,7 +2207,7 @@ PP(pp_bit_and) PP(pp_bit_xor) { - dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN); { dPOPTOPssrl; SvGETMAGIC(left); @@ -2228,7 +2232,7 @@ PP(pp_bit_xor) PP(pp_bit_or) { - dSP; dATARGET; tryAMAGICbin(bor,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(bor,opASSIGN); { dPOPTOPssrl; SvGETMAGIC(left); @@ -2253,7 +2257,7 @@ PP(pp_bit_or) PP(pp_negate) { - dSP; dTARGET; tryAMAGICun(neg); + dVAR; dSP; dTARGET; tryAMAGICun(neg); { dTOPss; const int flags = SvFLAGS(sv); @@ -2287,7 +2291,7 @@ PP(pp_negate) SETn(-SvNV(sv)); else if (SvPOKp(sv)) { STRLEN len; - const char *s = SvPV_const(sv, len); + const char * const s = SvPV_const(sv, len); if (isIDFIRST(*s)) { sv_setpvn(TARG, "-", 1); sv_catsv(TARG, sv); @@ -2323,14 +2327,14 @@ PP(pp_negate) PP(pp_not) { - dSP; tryAMAGICunSET(not); + dVAR; dSP; tryAMAGICunSET(not); *PL_stack_sp = boolSV(!SvTRUE(*PL_stack_sp)); return NORMAL; } PP(pp_complement) { - dSP; dTARGET; tryAMAGICun(compl); + dVAR; dSP; dTARGET; tryAMAGICun(compl); { dTOPss; SvGETMAGIC(sv); @@ -2427,7 +2431,7 @@ PP(pp_complement) PP(pp_i_multiply) { - dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); { dPOPTOPiirl; SETi( left * right ); @@ -2437,7 +2441,7 @@ PP(pp_i_multiply) PP(pp_i_divide) { - dSP; dATARGET; tryAMAGICbin(div,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(div,opASSIGN); { dPOPiv; if (value == 0) @@ -2469,7 +2473,7 @@ PP(pp_i_modulo_1) /* This is the i_modulo with the workaround for the _moddi3 bug * in (at least) glibc 2.2.5 (the PERL_ABS() the workaround). * See below for pp_i_modulo. */ - dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN); + dVAR; dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN); { dPOPTOPiirl; if (!right) @@ -2522,7 +2526,7 @@ PP(pp_i_modulo) PP(pp_i_add) { - dSP; dATARGET; tryAMAGICbin(add,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(add,opASSIGN); { dPOPTOPiirl_ul; SETi( left + right ); @@ -2532,7 +2536,7 @@ PP(pp_i_add) PP(pp_i_subtract) { - dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); + dVAR; dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); { dPOPTOPiirl_ul; SETi( left - right ); @@ -2542,7 +2546,7 @@ PP(pp_i_subtract) PP(pp_i_lt) { - dSP; tryAMAGICbinSET(lt,0); + dVAR; dSP; tryAMAGICbinSET(lt,0); { dPOPTOPiirl; SETs(boolSV(left < right)); @@ -2552,7 +2556,7 @@ PP(pp_i_lt) PP(pp_i_gt) { - dSP; tryAMAGICbinSET(gt,0); + dVAR; dSP; tryAMAGICbinSET(gt,0); { dPOPTOPiirl; SETs(boolSV(left > right)); @@ -2562,7 +2566,7 @@ PP(pp_i_gt) PP(pp_i_le) { - dSP; tryAMAGICbinSET(le,0); + dVAR; dSP; tryAMAGICbinSET(le,0); { dPOPTOPiirl; SETs(boolSV(left <= right)); @@ -2572,7 +2576,7 @@ PP(pp_i_le) PP(pp_i_ge) { - dSP; tryAMAGICbinSET(ge,0); + dVAR; dSP; tryAMAGICbinSET(ge,0); { dPOPTOPiirl; SETs(boolSV(left >= right)); @@ -2582,7 +2586,7 @@ PP(pp_i_ge) PP(pp_i_eq) { - dSP; tryAMAGICbinSET(eq,0); + dVAR; dSP; tryAMAGICbinSET(eq,0); { dPOPTOPiirl; SETs(boolSV(left == right)); @@ -2592,7 +2596,7 @@ PP(pp_i_eq) PP(pp_i_ne) { - dSP; tryAMAGICbinSET(ne,0); + dVAR; dSP; tryAMAGICbinSET(ne,0); { dPOPTOPiirl; SETs(boolSV(left != right)); @@ -2602,7 +2606,7 @@ PP(pp_i_ne) PP(pp_i_ncmp) { - dSP; dTARGET; tryAMAGICbin(ncmp,0); + dVAR; dSP; dTARGET; tryAMAGICbin(ncmp,0); { dPOPTOPiirl; I32 value; @@ -2620,7 +2624,7 @@ PP(pp_i_ncmp) PP(pp_i_negate) { - dSP; dTARGET; tryAMAGICun(neg); + dVAR; dSP; dTARGET; tryAMAGICun(neg); SETi(-TOPi); RETURN; } @@ -2629,7 +2633,7 @@ PP(pp_i_negate) PP(pp_atan2) { - dSP; dTARGET; tryAMAGICbin(atan2,0); + dVAR; dSP; dTARGET; tryAMAGICbin(atan2,0); { dPOPTOPnnrl; SETn(Perl_atan2(left, right)); @@ -2639,7 +2643,7 @@ PP(pp_atan2) PP(pp_sin) { - dSP; dTARGET; tryAMAGICun(sin); + dVAR; dSP; dTARGET; tryAMAGICun(sin); { const NV value = POPn; XPUSHn(Perl_sin(value)); @@ -2649,7 +2653,7 @@ PP(pp_sin) PP(pp_cos) { - dSP; dTARGET; tryAMAGICun(cos); + dVAR; dSP; dTARGET; tryAMAGICun(cos); { const NV value = POPn; XPUSHn(Perl_cos(value)); @@ -2674,7 +2678,7 @@ extern double drand48 (void); PP(pp_rand) { - dSP; dTARGET; + dVAR; dSP; dTARGET; NV value; if (MAXARG < 1) value = 1.0; @@ -2693,12 +2697,8 @@ PP(pp_rand) PP(pp_srand) { - dSP; - UV anum; - if (MAXARG < 1) - anum = seed(); - else - anum = POPu; + dVAR; dSP; + const UV anum = (MAXARG < 1) ? seed() : POPu; (void)seedDrand01((Rand_seed_t)anum); PL_srand_called = TRUE; EXTEND(SP, 1); @@ -2707,7 +2707,7 @@ PP(pp_srand) PP(pp_exp) { - dSP; dTARGET; tryAMAGICun(exp); + dVAR; dSP; dTARGET; tryAMAGICun(exp); { NV value; value = POPn; @@ -2719,7 +2719,7 @@ PP(pp_exp) PP(pp_log) { - dSP; dTARGET; tryAMAGICun(log); + dVAR; dSP; dTARGET; tryAMAGICun(log); { const NV value = POPn; if (value <= 0.0) { @@ -2733,7 +2733,7 @@ PP(pp_log) PP(pp_sqrt) { - dSP; dTARGET; tryAMAGICun(sqrt); + dVAR; dSP; dTARGET; tryAMAGICun(sqrt); { const NV value = POPn; if (value < 0.0) { @@ -2747,7 +2747,7 @@ PP(pp_sqrt) PP(pp_int) { - dSP; dTARGET; tryAMAGICun(int); + dVAR; dSP; dTARGET; tryAMAGICun(int); { const IV iv = TOPi; /* attempt to convert to IV if possible. */ /* XXX it's arguable that compiler casting to IV might be subtly @@ -2786,7 +2786,7 @@ PP(pp_int) PP(pp_abs) { - dSP; dTARGET; tryAMAGICun(abs); + dVAR; dSP; dTARGET; tryAMAGICun(abs); { /* This will cache the NV value if string isn't actually integer */ const IV iv = TOPi; @@ -2824,7 +2824,7 @@ PP(pp_abs) PP(pp_hex) { - dSP; dTARGET; + dVAR; dSP; dTARGET; const char *tmps; I32 flags = PERL_SCAN_ALLOW_UNDERSCORES; STRLEN len; @@ -2854,7 +2854,7 @@ PP(pp_hex) PP(pp_oct) { - dSP; dTARGET; + dVAR; dSP; dTARGET; const char *tmps; I32 flags = PERL_SCAN_ALLOW_UNDERSCORES; STRLEN len; @@ -2896,8 +2896,8 @@ PP(pp_oct) PP(pp_length) { - dSP; dTARGET; - SV *sv = TOPs; + dVAR; dSP; dTARGET; + SV * const sv = TOPs; if (DO_UTF8(sv)) SETi(sv_len_utf8(sv)); @@ -2908,7 +2908,7 @@ PP(pp_length) PP(pp_substr) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SV *sv; I32 len = 0; STRLEN curlen; @@ -2920,7 +2920,7 @@ PP(pp_substr) const char *tmps; const I32 arybase = PL_curcop->cop_arybase; SV *repl_sv = NULL; - const char *repl = 0; + const char *repl = NULL; STRLEN repl_len; const int num_args = PL_op->op_private & 7; bool repl_need_utf8_upgrade = FALSE; @@ -3054,7 +3054,7 @@ PP(pp_substr) if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); - sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0); + sv_magic(TARG, NULL, PERL_MAGIC_substr, NULL, 0); } else SvOK_off(TARG); @@ -3076,7 +3076,7 @@ PP(pp_substr) PP(pp_vec) { - dSP; dTARGET; + dVAR; dSP; dTARGET; register const IV size = POPi; register const IV offset = POPi; register SV * const src = POPs; @@ -3088,7 +3088,7 @@ PP(pp_vec) TARG = sv_newmortal(); if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); - sv_magic(TARG, Nullsv, PERL_MAGIC_vec, Nullch, 0); + sv_magic(TARG, NULL, PERL_MAGIC_vec, NULL, 0); } LvTYPE(TARG) = 'v'; if (LvTARG(TARG) != src) { @@ -3107,10 +3107,10 @@ PP(pp_vec) PP(pp_index) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SV *big; SV *little; - SV *temp = Nullsv; + SV *temp = NULL; I32 offset; I32 retval; const char *tmps; @@ -3170,10 +3170,10 @@ PP(pp_index) PP(pp_rindex) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SV *big; SV *little; - SV *temp = Nullsv; + SV *temp = NULL; STRLEN blen; STRLEN llen; I32 offset; @@ -3239,11 +3239,9 @@ PP(pp_rindex) PP(pp_sprintf) { - dSP; dMARK; dORIGMARK; dTARGET; + dVAR; dSP; dMARK; dORIGMARK; dTARGET; do_sprintf(TARG, SP-MARK, MARK+1); TAINT_IF(SvTAINTED(TARG)); - if (DO_UTF8(*(MARK+1))) - SvUTF8_on(TARG); SP = ORIGMARK; PUSHTARG; RETURN; @@ -3251,7 +3249,7 @@ PP(pp_sprintf) PP(pp_ord) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SV *argsv = POPs; STRLEN len; const U8 *s = (U8*)SvPV_const(argsv, len); @@ -3272,7 +3270,7 @@ PP(pp_ord) PP(pp_chr) { - dSP; dTARGET; + dVAR; dSP; dTARGET; char *tmps; UV value; @@ -3329,7 +3327,7 @@ PP(pp_chr) PP(pp_crypt) { #ifdef HAS_CRYPT - dSP; dTARGET; + dVAR; dSP; dTARGET; dPOPTOPssrl; STRLEN len; const char *tmps = SvPV_const(left, len); @@ -3377,10 +3375,12 @@ PP(pp_crypt) PP(pp_ucfirst) { + dVAR; dSP; SV *sv = TOPs; const U8 *s; STRLEN slen; + const int op_type = PL_op->op_type; SvGETMAGIC(sv); if (DO_UTF8(sv) && @@ -3391,17 +3391,21 @@ PP(pp_ucfirst) STRLEN tculen; utf8_to_uvchr(s, &ulen); - toTITLE_utf8(s, tmpbuf, &tculen); + if (op_type == OP_UCFIRST) { + toTITLE_utf8(s, tmpbuf, &tculen); + } else { + toLOWER_utf8(s, tmpbuf, &tculen); + } if (!SvPADTMP(sv) || SvREADONLY(sv) || ulen != tculen) { dTARGET; /* slen is the byte length of the whole SV. * ulen is the byte length of the original Unicode character * stored as UTF-8 at s. - * tculen is the byte length of the freshly titlecased - * Unicode character stored as UTF-8 at tmpbuf. - * We first set the result to be the titlecased character, - * and then append the rest of the SV data. */ + * tculen is the byte length of the freshly titlecased (or + * lowercased) Unicode character stored as UTF-8 at tmpbuf. + * We first set the result to be the titlecased (/lowercased) + * character, and then append the rest of the SV data. */ sv_setpvn(TARG, (char*)tmpbuf, tculen); if (slen > ulen) sv_catpvn(TARG, (char*)(s + ulen), slen - ulen); @@ -3427,65 +3431,11 @@ PP(pp_ucfirst) if (IN_LOCALE_RUNTIME) { TAINT; SvTAINTED_on(sv); - *s1 = toUPPER_LC(*s1); - } - else - *s1 = toUPPER(*s1); - } - } - SvSETMAGIC(sv); - RETURN; -} - -PP(pp_lcfirst) -{ - dSP; - SV *sv = TOPs; - const U8 *s; - STRLEN slen; - - SvGETMAGIC(sv); - if (DO_UTF8(sv) && - (s = (const U8*)SvPV_nomg_const(sv, slen)) && slen && - UTF8_IS_START(*s)) { - STRLEN ulen; - STRLEN lculen; - U8 tmpbuf[UTF8_MAXBYTES_CASE+1]; - - utf8_to_uvchr(s, &ulen); - toLOWER_utf8(s, tmpbuf, &lculen); - - if (!SvPADTMP(sv) || SvREADONLY(sv) || ulen != lculen) { - dTARGET; - sv_setpvn(TARG, (char*)tmpbuf, lculen); - if (slen > ulen) - sv_catpvn(TARG, (char*)(s + ulen), slen - ulen); - SvUTF8_on(TARG); - SETs(TARG); - } - else { - s = (U8*)SvPV_force_nomg(sv, slen); - Copy(tmpbuf, s, ulen, U8); - } - } - else { - U8 *s1; - if (!SvPADTMP(sv) || SvREADONLY(sv)) { - dTARGET; - SvUTF8_off(TARG); /* decontaminate */ - sv_setsv_nomg(TARG, sv); - sv = TARG; - SETs(sv); - } - s1 = (U8*)SvPV_force_nomg(sv, slen); - if (*s1) { - if (IN_LOCALE_RUNTIME) { - TAINT; - SvTAINTED_on(sv); - *s1 = toLOWER_LC(*s1); + *s1 = (op_type == OP_UCFIRST) + ? toUPPER_LC(*s1) : toLOWER_LC(*s1); } else - *s1 = toLOWER(*s1); + *s1 = (op_type == OP_UCFIRST) ? toUPPER(*s1) : toLOWER(*s1); } } SvSETMAGIC(sv); @@ -3494,6 +3444,7 @@ PP(pp_lcfirst) PP(pp_uc) { + dVAR; dSP; SV *sv = TOPs; STRLEN len; @@ -3528,7 +3479,7 @@ PP(pp_uc) if (ulen > u && (SvLEN(TARG) < (min += ulen - u))) { /* If the eventually required minimum size outgrows * the available space, we need to grow. */ - UV o = d - (U8*)SvPVX_const(TARG); + const UV o = d - (U8*)SvPVX_const(TARG); /* If someone uppercases one million U+03B0s we * SvGROW() one million times. Or we could try @@ -3578,6 +3529,7 @@ PP(pp_uc) PP(pp_lc) { + dVAR; dSP; SV *sv = TOPs; STRLEN len; @@ -3631,7 +3583,7 @@ PP(pp_lc) if (ulen > u && (SvLEN(TARG) < (min += ulen - u))) { /* If the eventually required minimum size outgrows * the available space, we need to grow. */ - UV o = d - (U8*)SvPVX_const(TARG); + const UV o = d - (U8*)SvPVX_const(TARG); /* If someone lowercases one million U+0130s we * SvGROW() one million times. Or we could try @@ -3682,7 +3634,7 @@ PP(pp_lc) PP(pp_quotemeta) { - dSP; dTARGET; + dVAR; dSP; dTARGET; SV * const sv = TOPs; STRLEN len; register const char *s = SvPV_const(sv,len); @@ -3735,7 +3687,7 @@ PP(pp_quotemeta) PP(pp_aslice) { - dSP; dMARK; dORIGMARK; + dVAR; dSP; dMARK; dORIGMARK; register AV* const av = (AV*)POPs; register const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET); @@ -3780,6 +3732,7 @@ PP(pp_aslice) PP(pp_each) { + dVAR; dSP; HV * const hash = (HV*)POPs; HE *entry; @@ -3811,6 +3764,7 @@ PP(pp_each) PP(pp_delete) { + dVAR; dSP; const I32 gimme = GIMME_V; const I32 discard = (gimme == G_VOID) ? G_DISCARD : 0; @@ -3870,14 +3824,15 @@ PP(pp_delete) PP(pp_exists) { + dVAR; dSP; SV *tmpsv; HV *hv; if (PL_op->op_private & OPpEXISTS_SUB) { GV *gv; - SV *sv = POPs; - CV * const cv = sv_2cv(sv, &hv, &gv, FALSE); + SV * const sv = POPs; + CV * const cv = sv_2cv(sv, &hv, &gv, 0); if (cv) RETPUSHYES; if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv)) @@ -3904,7 +3859,7 @@ PP(pp_exists) PP(pp_hslice) { - dSP; dMARK; dORIGMARK; + dVAR; dSP; dMARK; dORIGMARK; register HV * const hv = (HV*)POPs; register const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET); const bool localizing = PL_op->op_private & OPpLVAL_INTRO; @@ -3966,7 +3921,7 @@ PP(pp_hslice) PP(pp_list) { - dSP; dMARK; + dVAR; dSP; dMARK; if (GIMME != G_ARRAY) { if (++MARK <= SP) *MARK = *SP; /* unwanted list, return last item */ @@ -3979,6 +3934,7 @@ PP(pp_list) PP(pp_lslice) { + dVAR; dSP; SV ** const lastrelem = PL_stack_sp; SV ** const lastlelem = PL_stack_base + POPMARK; @@ -4032,7 +3988,7 @@ PP(pp_lslice) PP(pp_anonlist) { - dSP; dMARK; dORIGMARK; + dVAR; dSP; dMARK; dORIGMARK; const I32 items = SP - MARK; SV * const av = sv_2mortal((SV*)av_make(items, MARK+1)); SP = ORIGMARK; /* av_make() might realloc stack_sp */ @@ -4042,7 +3998,7 @@ PP(pp_anonlist) PP(pp_anonhash) { - dSP; dMARK; dORIGMARK; + dVAR; dSP; dMARK; dORIGMARK; HV* const hv = (HV*)sv_2mortal((SV*)newHV()); while (MARK < SP) { @@ -4071,7 +4027,7 @@ PP(pp_splice) I32 newlen; I32 after; I32 diff; - SV **tmparyval = 0; + SV **tmparyval = NULL; const MAGIC * const mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied); if (mg) { @@ -4298,6 +4254,7 @@ PP(pp_push) PP(pp_pop) { + dVAR; dSP; AV * const av = (AV*)POPs; SV * const sv = av_pop(av); @@ -4309,6 +4266,7 @@ PP(pp_pop) PP(pp_shift) { + dVAR; dSP; AV * const av = (AV*)POPs; SV * const sv = av_shift(av); @@ -4351,7 +4309,7 @@ PP(pp_unshift) PP(pp_reverse) { - dSP; dMARK; + dVAR; dSP; dMARK; SV ** const oldsp = SP; if (GIMME == G_ARRAY) { @@ -4472,7 +4430,7 @@ PP(pp_split) else if (gimme != G_ARRAY) ary = GvAVn(PL_defgv); else - ary = Nullav; + ary = NULL; if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) { realarray = 1; PUTBACK; @@ -4725,6 +4683,7 @@ PP(pp_split) PP(pp_lock) { + dVAR; dSP; dTOPss; SV *retsv = sv; @@ -4740,6 +4699,7 @@ PP(pp_lock) PP(unimplemented_op) { + dVAR; DIE(aTHX_ "panic: unimplemented op %s (#%d) called", OP_NAME(PL_op), PL_op->op_type); }