X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=b394426cbf81db07f0612299c0476b3aceb478da;hb=77bb9b23081b62119e8fbe9f5655b8802e4537ae;hp=089d523966cbd4e619f20d0d1d894b11a68b7648;hpb=8ebc5c0145d2e3559bce3073437e6d027dcdffcc;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index 089d523..b394426 100644 --- a/pp.c +++ b/pp.c @@ -519,8 +519,10 @@ PP(pp_undef) dSP; SV *sv; - if (!op->op_private) + if (!op->op_private) { + EXTEND(SP, 1); RETPUSHUNDEF; + } sv = POPs; if (!sv) @@ -544,13 +546,11 @@ PP(pp_undef) break; case SVt_PVCV: cv_undef((CV*)sv); - sub_generation++; break; case SVt_PVGV: - if (SvFAKE(sv)) { - sv_setsv(sv, &sv_undef); - break; - } + if (SvFAKE(sv)) + sv_setsv(sv, &sv_undef); + break; default: if (SvPOK(sv) && SvLEN(sv)) { (void)SvOOK_off(sv); @@ -568,6 +568,8 @@ PP(pp_undef) PP(pp_predec) { dSP; + if (SvREADONLY(TOPs)) + croak(no_modify); if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && SvIVX(TOPs) != IV_MIN) { @@ -583,6 +585,8 @@ PP(pp_predec) PP(pp_postinc) { dSP; dTARGET; + if (SvREADONLY(TOPs)) + croak(no_modify); sv_setsv(TARG, TOPs); if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && SvIVX(TOPs) != IV_MAX) @@ -602,6 +606,8 @@ PP(pp_postinc) PP(pp_postdec) { dSP; dTARGET; + if(SvREADONLY(TOPs)) + croak(no_modify); sv_setsv(TARG, TOPs); if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && SvIVX(TOPs) != IV_MIN) @@ -851,12 +857,16 @@ PP(pp_ncmp) dPOPTOPnnrl; I32 value; - if (left > right) - value = 1; - else if (left < right) + if (left < right) value = -1; - else + else if (left == right) value = 0; + else if (left > right) + value = 1; + else { + SETs(&sv_undef); + RETURN; + } SETi(value); RETURN; } @@ -977,11 +987,11 @@ PP(pp_bit_xor) dPOPTOPssrl; if (SvNIOKp(left) || SvNIOKp(right)) { if (op->op_private & HINT_INTEGER) { - IBW value = SvIV(left) ^ SvIV(right); + IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right); SETi( value ); } else { - UBW value = SvUV(left) ^ SvUV(right); + UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right); SETu( value ); } } @@ -1128,6 +1138,8 @@ PP(pp_i_modulo) dSP; dATARGET; tryAMAGICbin(mod,opASSIGN); { dPOPTOPiirl; + if (!right) + DIE("Illegal modulus zero"); SETi( left % right ); RETURN; } @@ -1385,15 +1397,28 @@ PP(pp_sqrt) PP(pp_int) { dSP; dTARGET; - double value; - value = POPn; - if (value >= 0.0) - (void)modf(value, &value); - else { - (void)modf(-value, &value); - value = -value; + { + double value = TOPn; + IV iv; + + if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs)) { + iv = SvIVX(TOPs); + SETi(iv); + } + else { + if (value >= 0.0) + (void)modf(value, &value); + else { + (void)modf(-value, &value); + value = -value; + } + iv = I_V(value); + if (iv == value) + SETi(iv); + else + SETn(value); + } } - XPUSHn(value); RETURN; } @@ -1401,15 +1426,22 @@ PP(pp_abs) { dSP; dTARGET; tryAMAGICun(abs); { - double value; - value = POPn; - - if (value < 0.0) - value = -value; - - XPUSHn(value); - RETURN; + double value = TOPn; + IV iv; + + if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs) && + (iv = SvIVX(TOPs)) != IV_MIN) { + if (iv < 0) + iv = -iv; + SETi(iv); + } + else { + if (value < 0.0) + value = -value; + SETn(value); + } } + RETURN; } PP(pp_hex) @@ -2110,10 +2142,11 @@ PP(pp_lslice) PP(pp_anonlist) { - dSP; dMARK; + dSP; dMARK; dORIGMARK; I32 items = SP - MARK; - SP = MARK; - XPUSHs((SV*)sv_2mortal((SV*)av_make(items, MARK+1))); + SV *av = sv_2mortal((SV*)av_make(items, MARK+1)); + SP = ORIGMARK; /* av_make() might realloc stack_sp */ + XPUSHs(av); RETURN; } @@ -3696,7 +3729,8 @@ PP(pp_split) STRLEN len; register char *s = SvPV(sv, len); char *strend = s + len; - register PMOP *pm = (PMOP*)POPs; + register PMOP *pm; + register REGEXP *rx; register SV *dstr; register char *m; I32 iters = 0; @@ -3707,12 +3741,17 @@ PP(pp_split) I32 realarray = 0; I32 base; AV *oldstack = curstack; - register REGEXP *rx = pm->op_pmregexp; I32 gimme = GIMME; I32 oldsave = savestack_ix; +#ifdef DEBUGGING + Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*); +#else + pm = (PMOP*)POPs; +#endif if (!pm || !s) DIE("panic: do_split"); + rx = pm->op_pmregexp; TAINT_IF((pm->op_pmflags & PMf_LOCALE) && (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE))); @@ -3792,7 +3831,7 @@ PP(pp_split) s = m; } } - else if (pm->op_pmshort) { + else if (pm->op_pmshort && !rx->nparens) { i = SvCUR(pm->op_pmshort); if (i == 1) { i = *SvPVX(pm->op_pmshort);