X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=d55c4a8eb62e92f7d08e14131770090ed6c8d620;hb=73031816b5ef6a74869c06e84bb621841a623d0a;hp=173f81dd91b6f0b7436caa2744e8899285d9a7fa;hpb=f0ab9afb53ef594bb6fb8989153fbfba9762816f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index 173f81d..d55c4a8 100644 --- a/pp.c +++ b/pp.c @@ -416,7 +416,7 @@ PP(pp_prototype) char str[ MAX_ARGS_OP * 2 + 2 ]; /* One ';', one '\0' */ if (code == -KEY_chop || code == -KEY_chomp - || code == -KEY_exec || code == -KEY_system || code == -KEY_err) + || code == -KEY_exec || code == -KEY_system) goto set; if (code == -KEY_mkdir) { ret = sv_2mortal(newSVpvs("_;$")); @@ -828,6 +828,15 @@ PP(pp_undef) SvSetMagicSV(sv, &PL_sv_undef); else { GP *gp; + HV *stash; + + /* undef *Foo:: */ + if((stash = GvHV((GV*)sv)) && HvNAME_get(stash)) + mro_isa_changed_in(stash); + /* undef *Pkg::meth_name ... */ + else if(GvCVu((GV*)sv) && (stash = GvSTASH((GV*)sv)) && HvNAME_get(stash)) + mro_method_changed_in(stash); + gp_free((GV*)sv); Newxz(gp, 1, GP); GvGP(sv) = gp_ref(gp); @@ -1306,7 +1315,11 @@ PP(pp_divide) #endif /* PERL_TRY_UV_DIVIDE */ { dPOPPOPnnrl; +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + if (! Perl_isnan(right) && right == 0.0) +#else if (right == 0.0) +#endif DIE(aTHX_ "Illegal division by zero"); PUSHn( left / right ); RETURN; @@ -1471,7 +1484,7 @@ PP(pp_repeat) count = (IV)nv; } else - count = SvIVx(sv); + count = SvIV(sv); if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) { dMARK; static const char oom_list_extend[] = "Out of memory during list extend"; @@ -1537,7 +1550,7 @@ PP(pp_repeat) SvCUR_set(TARG, 0); else { const STRLEN max = (UV)count * len; - if (len > ((MEM_SIZE)~0)/count) + if (len > MEM_SIZE_MAX / count) Perl_croak(aTHX_ oom_string_extend); MEM_WRAP_CHECK_1(max, char, oom_string_extend); SvGROW(TARG, max + 1); @@ -2566,8 +2579,12 @@ PP(pp_i_divide) } } +#if defined(__GLIBC__) && IVSIZE == 8 STATIC PP(pp_i_modulo_0) +#else +PP(pp_i_modulo) +#endif { /* This is the vanilla old i_modulo. */ dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN); @@ -2587,6 +2604,7 @@ PP(pp_i_modulo_0) #if defined(__GLIBC__) && IVSIZE == 8 STATIC 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). @@ -2604,7 +2622,6 @@ PP(pp_i_modulo_1) RETURN; } } -#endif PP(pp_i_modulo) { @@ -2624,7 +2641,6 @@ PP(pp_i_modulo) * opcode dispatch table if that is the case, remembering to * also apply the workaround so that this first round works * right, too. See [perl #9402] for more information. */ -#if defined(__GLIBC__) && IVSIZE == 8 { IV l = 3; IV r = -10; @@ -2640,7 +2656,6 @@ PP(pp_i_modulo) right = PERL_ABS(right); } } -#endif /* avoid FPE_INTOVF on some platforms when left is IV_MIN */ if (right == -1) SETi( 0 ); @@ -2649,6 +2664,7 @@ PP(pp_i_modulo) RETURN; } } +#endif PP(pp_i_add) { @@ -3014,13 +3030,13 @@ PP(pp_substr) I32 pos; I32 rem; I32 fail; - const int num_args = PL_op->op_private & 7; - const I32 lvalue = num_args <= 3 && ( PL_op->op_flags & OPf_MOD || LVRET ); + const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET; const char *tmps; const I32 arybase = CopARYBASE_get(PL_curcop); SV *repl_sv = NULL; const char *repl = NULL; STRLEN repl_len; + const int num_args = PL_op->op_private & 7; bool repl_need_utf8_upgrade = FALSE; bool repl_is_utf8 = FALSE; @@ -3115,8 +3131,7 @@ PP(pp_substr) } } - if (GIMME_V != G_VOID && !lvalue) - sv_setpvn(TARG, tmps, rem); + sv_setpvn(TARG, tmps, rem); #ifdef USE_LOCALE_COLLATE sv_unmagic(TARG, PERL_MAGIC_collxfrm); #endif @@ -3355,7 +3370,7 @@ PP(pp_ord) XPUSHu(DO_UTF8(argsv) ? utf8n_to_uvchr(s, UTF8_MAXBYTES, 0, UTF8_ALLOW_ANYUV) : - (*s & 0xff)); + (UV)(*s & 0xff)); RETURN; } @@ -3507,7 +3522,7 @@ PP(pp_ucfirst) need = slen + 1; } - if (SvPADTMP(source) && !SvREADONLY(source) && inplace) { + if (SvPADTMP(source) && !SvREADONLY(source) && inplace && SvTEMP(source)) { /* We can convert in place. */ dest = source; @@ -3590,7 +3605,7 @@ PP(pp_uc) SvGETMAGIC(source); if (SvPADTMP(source) && !SvREADONLY(source) && !SvAMAGIC(source) - && !DO_UTF8(source)) { + && SvTEMP(source) && !DO_UTF8(source)) { /* We can convert in place. */ dest = source; @@ -3690,7 +3705,7 @@ PP(pp_lc) SvGETMAGIC(source); if (SvPADTMP(source) && !SvREADONLY(source) && !SvAMAGIC(source) - && !DO_UTF8(source)) { + && SvTEMP(source) && !DO_UTF8(source)) { /* We can convert in place. */ dest = source; @@ -3857,7 +3872,7 @@ PP(pp_aslice) register SV **svp; I32 max = -1; for (svp = MARK + 1; svp <= SP; svp++) { - const I32 elem = SvIVx(*svp); + const I32 elem = SvIV(*svp); if (elem > max) max = elem; } @@ -3866,7 +3881,7 @@ PP(pp_aslice) } while (++MARK <= SP) { register SV **svp; - I32 elem = SvIVx(*MARK); + I32 elem = SvIV(*MARK); if (elem > 0) elem -= arybase; @@ -4051,7 +4066,7 @@ PP(pp_hslice) } he = hv_fetch_ent(hv, keysv, lval, 0); - svp = he ? &HeVAL(he) : 0; + svp = he ? &HeVAL(he) : NULL; if (lval) { if (!svp || *svp == &PL_sv_undef) { @@ -4112,7 +4127,7 @@ PP(pp_lslice) register SV **lelem; if (GIMME != G_ARRAY) { - I32 ix = SvIVx(*lastlelem); + I32 ix = SvIV(*lastlelem); if (ix < 0) ix += max; else @@ -4131,7 +4146,7 @@ PP(pp_lslice) } for (lelem = firstlelem; lelem <= lastlelem; lelem++) { - I32 ix = SvIVx(*lelem); + I32 ix = SvIV(*lelem); if (ix < 0) ix += max; else @@ -4210,7 +4225,7 @@ PP(pp_splice) SP++; if (++MARK < SP) { - offset = i = SvIVx(*MARK); + offset = i = SvIV(*MARK); if (offset < 0) offset += AvFILLp(ary) + 1; else @@ -4405,12 +4420,17 @@ PP(pp_push) PUSHi( AvFILL(ary) + 1 ); } else { + PL_delaymagic = DM_DELAY; for (++MARK; MARK <= SP; MARK++) { SV * const sv = newSV(0); if (*MARK) sv_setsv(sv, *MARK); av_store(ary, AvFILLp(ary)+1, sv); } + if (PL_delaymagic & DM_ARRAY) + mg_set((SV*)ary); + + PL_delaymagic = 0; SP = ORIGMARK; PUSHi( AvFILLp(ary) + 1 ); } @@ -4568,18 +4588,20 @@ PP(pp_split) DIE(aTHX_ "panic: pp_split"); rx = PM_GETRE(pm); - TAINT_IF((pm->op_pmflags & PMf_LOCALE) && - (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE))); + TAINT_IF((rx->extflags & RXf_PMf_LOCALE) && + (rx->extflags & (RXf_WHITE | RXf_SKIPWHITE))); RX_MATCH_UTF8_set(rx, do_utf8); - if (pm->op_pmreplroot) { #ifdef USE_ITHREADS - ary = GvAVn((GV*)PAD_SVl(INT2PTR(PADOFFSET, pm->op_pmreplroot))); + if (pm->op_pmreplrootu.op_pmtargetoff) { + ary = GvAVn((GV*)PAD_SVl(pm->op_pmreplrootu.op_pmtargetoff)); + } #else - ary = GvAVn((GV*)pm->op_pmreplroot); -#endif + if (pm->op_pmreplrootu.op_pmtargetgv) { + ary = GvAVn(pm->op_pmreplrootu.op_pmtargetgv); } +#endif else if (gimme != G_ARRAY) ary = GvAVn(PL_defgv); else @@ -4609,12 +4631,12 @@ PP(pp_split) } base = SP - PL_stack_base; orig = s; - if (pm->op_pmflags & PMf_SKIPWHITE) { + if (rx->extflags & RXf_SKIPWHITE) { if (do_utf8) { while (*s == ' ' || is_utf8_space((U8*)s)) s += UTF8SKIP(s); } - else if (pm->op_pmflags & PMf_LOCALE) { + else if (rx->extflags & RXf_PMf_LOCALE) { while (isSPACE_LC(*s)) s++; } @@ -4623,13 +4645,13 @@ PP(pp_split) s++; } } - if (pm->op_pmflags & PMf_MULTILINE) { + if (rx->extflags & PMf_MULTILINE) { multiline = 1; } if (!limit) limit = maxiters + 2; - if (pm->op_pmflags & PMf_WHITE) { + if (rx->extflags & RXf_WHITE) { while (--limit) { m = s; /* this one uses 'm' and is a negative test */ @@ -4642,7 +4664,7 @@ PP(pp_split) else m += t; } - } else if (pm->op_pmflags & PMf_LOCALE) { + } else if (rx->extflags & RXf_PMf_LOCALE) { while (m < strend && !isSPACE_LC(*m)) ++m; } else { @@ -4669,7 +4691,7 @@ PP(pp_split) if (do_utf8) { while (s < strend && ( *s == ' ' || is_utf8_space((U8*)s) )) s += UTF8SKIP(s); - } else if (pm->op_pmflags & PMf_LOCALE) { + } else if (rx->extflags & RXf_PMf_LOCALE) { while (s < strend && isSPACE_LC(*s)) ++s; } else { @@ -4694,6 +4716,53 @@ PP(pp_split) s = m; } } + else if (rx->extflags & RXf_NULL && !(s >= strend)) { + /* + Pre-extend the stack, either the number of bytes or + characters in the string or a limited amount, triggered by: + + my ($x, $y) = split //, $str; + or + split //, $str, $i; + */ + const U32 items = limit - 1; + if (items < slen) + EXTEND(SP, items); + else + EXTEND(SP, slen); + + if (do_utf8) { + while (--limit) { + /* keep track of how many bytes we skip over */ + m = s; + s += UTF8SKIP(s); + dstr = newSVpvn(m, s-m); + + if (make_mortal) + sv_2mortal(dstr); + + (void)SvUTF8_on(dstr); + PUSHs(dstr); + + if (s >= strend) + break; + } + } else { + while (--limit) { + dstr = newSVpvn(s, 1); + + s++; + + if (make_mortal) + sv_2mortal(dstr); + + PUSHs(dstr); + + if (s >= strend) + break; + } + } + } else if (do_utf8 == ((rx->extflags & RXf_UTF8) != 0) && (rx->extflags & RXf_USE_INTUIT) && !rx->nparens && (rx->extflags & RXf_CHECK_ALL) @@ -4863,6 +4932,19 @@ PP(pp_split) RETURN; } +PP(pp_once) +{ + dSP; + SV *const sv = PAD_SVl(PL_op->op_targ); + + if (SvPADSTALE(sv)) { + /* First time. */ + SvPADSTALE_off(sv); + RETURNOP(cLOGOP->op_other); + } + RETURNOP(cLOGOP->op_next); +} + PP(pp_lock) { dVAR;