X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=b2aa8e6677d9a02950cce53d922812e34597c128;hb=8c7d55fc02cca4e0edf1324c36f667376289f8d2;hp=4b021c0d6d52ba42207e67c7b45738be866e84fc;hpb=8727f688bf9bab57862da9dd9073020b13c82940;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index 4b021c0..b2aa8e6 100644 --- a/pp.c +++ b/pp.c @@ -222,6 +222,50 @@ PP(pp_rv2gv) RETURN; } +/* Helper function for pp_rv2sv and pp_rv2av */ +GV * +Perl_softref2xv(pTHX_ SV *const sv, const char *const what, const U32 type, + SV ***spp) +{ + dVAR; + GV *gv; + + if (PL_op->op_private & HINT_STRICT_REFS) { + if (SvOK(sv)) + Perl_die(aTHX_ PL_no_symref_sv, sv, what); + else + Perl_die(aTHX_ PL_no_usym, what); + } + if (!SvOK(sv)) { + if (PL_op->op_flags & OPf_REF) + Perl_die(aTHX_ PL_no_usym, what); + if (ckWARN(WARN_UNINITIALIZED)) + report_uninit(sv); + if (type != SVt_PV && GIMME_V == G_ARRAY) { + (*spp)--; + return NULL; + } + **spp = &PL_sv_undef; + return NULL; + } + if ((PL_op->op_flags & OPf_SPECIAL) && + !(PL_op->op_flags & OPf_MOD)) + { + gv = gv_fetchsv(sv, 0, type); + if (!gv + && (!is_gv_magical_sv(sv,0) + || !(gv = gv_fetchsv(sv, GV_ADD, type)))) + { + **spp = &PL_sv_undef; + return NULL; + } + } + else { + gv = gv_fetchsv(sv, GV_ADD, type); + } + return gv; +} + PP(pp_rv2sv) { dVAR; dSP; dTOPss; @@ -251,33 +295,9 @@ 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) - DIE(aTHX_ PL_no_usym, "a SCALAR"); - if (ckWARN(WARN_UNINITIALIZED)) - report_uninit(sv); - RETSETUNDEF; - } - if ((PL_op->op_flags & OPf_SPECIAL) && - !(PL_op->op_flags & OPf_MOD)) - { - gv = (GV*)gv_fetchsv(sv, 0, SVt_PV); - if (!gv - && (!is_gv_magical_sv(sv, 0) - || !(gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV)))) - { - RETSETUNDEF; - } - } - else { - gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV); - } + gv = Perl_softref2xv(aTHX_ sv, "a SCALAR", SVt_PV, &sp); + if (!gv) + RETURN; } sv = GvSVn(gv); } @@ -303,8 +323,7 @@ PP(pp_av2arylen) AV * const av = (AV*)TOPs; SV ** const sv = Perl_av_arylen_p(aTHX_ (AV*)av); if (!*sv) { - *sv = newSV(0); - sv_upgrade(*sv, SVt_PVMG); + *sv = newSV_type(SVt_PVMG); sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, NULL, 0); } SETs(*sv); @@ -558,7 +577,7 @@ PP(pp_bless) if (len == 0 && ckWARN(WARN_MISC)) Perl_warner(aTHX_ packWARN(WARN_MISC), "Explicit blessing to '' (assuming package main)"); - stash = gv_stashpvn(ptr, len, TRUE); + stash = gv_stashpvn(ptr, len, GV_ADD); } (void)sv_bless(TOPs, stash); @@ -1518,7 +1537,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); @@ -4590,7 +4609,11 @@ PP(pp_split) base = SP - PL_stack_base; orig = s; if (pm->op_pmflags & PMf_SKIPWHITE) { - if (pm->op_pmflags & PMf_LOCALE) { + if (do_utf8) { + while (*s == ' ' || is_utf8_space((U8*)s)) + s += UTF8SKIP(s); + } + else if (pm->op_pmflags & PMf_LOCALE) { while (isSPACE_LC(*s)) s++; } @@ -4606,22 +4629,18 @@ PP(pp_split) if (!limit) limit = maxiters + 2; if (pm->op_pmflags & PMf_WHITE) { - if (do_utf8 && !PL_utf8_space) { - /* force PL_utf8_space to be loaded */ - bool ok; - ENTER; - ok = is_utf8_space((const U8*)" "); - assert(ok); - LEAVE; - } while (--limit) { m = s; /* this one uses 'm' and is a negative test */ if (do_utf8) { - STRLEN uskip; - while (m < strend && - !( *m == ' ' || swash_fetch(PL_utf8_space,(U8*)m, do_utf8) )) - m += UTF8SKIP(m); + while (m < strend && !( *m == ' ' || is_utf8_space((U8*)m) )) { + const int t = UTF8SKIP(m); + /* is_utf8_space returns FALSE for malform utf8 */ + if (strend - m < t) + m = strend; + else + m += t; + } } else if (pm->op_pmflags & PMf_LOCALE) { while (m < strend && !isSPACE_LC(*m)) ++m; @@ -4639,11 +4658,15 @@ PP(pp_split) (void)SvUTF8_on(dstr); XPUSHs(dstr); - s = m + 1; + /* skip the whitespace found last */ + if (do_utf8) + s = m + UTF8SKIP(m); + else + s = m + 1; + /* this one uses 's' and is a positive test */ if (do_utf8) { - while (s < strend && - ( *s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8) )) + while (s < strend && ( *s == ' ' || is_utf8_space((U8*)s) )) s += UTF8SKIP(s); } else if (pm->op_pmflags & PMf_LOCALE) { while (s < strend && isSPACE_LC(*s)) @@ -4738,7 +4761,7 @@ PP(pp_split) s = orig + (m - s); strend = s + (strend - m); } - m = rx->startp[0] + orig; + m = rx->offs[0].start + orig; dstr = newSVpvn(s, m-s); if (make_mortal) sv_2mortal(dstr); @@ -4748,8 +4771,8 @@ PP(pp_split) if (rx->nparens) { I32 i; for (i = 1; i <= (I32)rx->nparens; i++) { - s = rx->startp[i] + orig; - m = rx->endp[i] + orig; + s = rx->offs[i].start + orig; + m = rx->offs[i].end + orig; /* japhy (07/27/01) -- the (m && s) test doesn't catch parens that didn't match -- they should be set to @@ -4766,7 +4789,7 @@ PP(pp_split) XPUSHs(dstr); } } - s = rx->endp[0] + orig; + s = rx->offs[0].end + orig; } }