X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/82229f9f47d9a169b59715582fb5a09b5a4ac0ff..196344c20348c6f1effb9b3dabcee6350d47fbff:/sv.c diff --git a/sv.c b/sv.c index ac41af2..f56fc16 100644 --- a/sv.c +++ b/sv.c @@ -245,7 +245,7 @@ Public API: if ((sv)->sv_debug_file) PerlMemShared_free((sv)->sv_debug_file); \ } STMT_END # define DEBUG_SV_SERIAL(sv) \ - DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) del_SV\n", \ + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) del_SV\n", \ PTR2UV(sv), (long)(sv)->sv_debug_serial)) #else # define FREE_SV_DEBUG_FILE(sv) @@ -340,7 +340,7 @@ S_new_SV(pTHX_ const char *file, int line, const char *func) sv->sv_debug_serial = PL_sv_serial++; MEM_LOG_NEW_SV(sv, file, line, func); - DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) new_SV (from %s:%d [%s])\n", + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) new_SV (from %s:%d [%s])\n", PTR2UV(sv), (long)sv->sv_debug_serial, file, line, func)); return sv; @@ -392,7 +392,7 @@ S_del_sv(pTHX_ SV *p) } if (!ok) { Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), - "Attempt to free non-arena SV: 0x%"UVxf + "Attempt to free non-arena SV: 0x%" UVxf pTHX__FORMAT, PTR2UV(p) pTHX__VALUE); return; } @@ -654,7 +654,7 @@ do_clean_all(pTHX_ SV *const sv) /* don't clean pid table and strtab */ return; } - DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%"UVxf"\n", PTR2UV(sv)) )); + DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%" UVxf "\n", PTR2UV(sv)) )); SvFLAGS(sv) |= SVf_BREAK; SvREFCNT_dec_NN(sv); } @@ -1111,7 +1111,7 @@ Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size, Newx(adesc->arena, good_arena_size, char); adesc->size = good_arena_size; adesc->utype = sv_type; - DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %"UVuf"\n", + DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %" UVuf "\n", curr, (void*)adesc->arena, (UV)good_arena_size)); start = (char *) adesc->arena; @@ -1205,7 +1205,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type) const struct body_details *new_type_details; const struct body_details *old_type_details = bodies_by_type + old_type; - SV *referant = NULL; + SV *referent = NULL; PERL_ARGS_ASSERT_SV_UPGRADE; @@ -1270,7 +1270,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type) break; case SVt_IV: if (SvROK(sv)) { - referant = SvRV(sv); + referent = SvRV(sv); old_type_details = &fake_rv; if (new_type == SVt_NV) new_type = SVt_PVNV; @@ -1465,9 +1465,9 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type) if (UNLIKELY(new_type == SVt_REGEXP)) sv->sv_u.svu_rx = (regexp *)new_body; else if (old_type < SVt_PV) { - /* referant will be NULL unless the old type was SVt_IV emulating + /* referent will be NULL unless the old type was SVt_IV emulating SVt_RV */ - sv->sv_u.svu_rv = referant; + sv->sv_u.svu_rv = referent; } break; default: @@ -1525,6 +1525,11 @@ Perl_sv_backoff(SV *const sv) return; } + +/* forward declaration */ +static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags); + + /* =for apidoc sv_grow @@ -1535,7 +1540,6 @@ Use the C wrapper instead. =cut */ -static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags); char * Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen) @@ -1567,15 +1571,11 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen) * to store the COW count. So in general, allocate one more byte than * asked for, to make it likely this byte is always spare: and thus * make more strings COW-able. - * If the new size is a big power of two, don't bother: we assume the - * caller wanted a nice 2^N sized block and will be annoyed at getting - * 2^N+1. + * * Only increment if the allocation isn't MEM_SIZE_MAX, * otherwise it will wrap to 0. */ - if ( (newlen < 0x1000 || (newlen & (newlen - 1))) - && newlen != MEM_SIZE_MAX - ) + if ( newlen != MEM_SIZE_MAX ) newlen++; #endif @@ -1604,7 +1604,7 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen) else { s = (char*)safemalloc(newlen); if (SvPVX_const(sv) && SvCUR(sv)) { - Move(SvPVX_const(sv), s, (newlen < SvCUR(sv)) ? newlen : SvCUR(sv), char); + Move(SvPVX_const(sv), s, SvCUR(sv), char); } } SvPV_set(sv, s); @@ -1655,6 +1655,7 @@ Perl_sv_setiv(pTHX_ SV *const sv, const IV i) /* diag_listed_as: Can't coerce %s to %s in %s */ Perl_croak(aTHX_ "Can't coerce %s to integer in %s", sv_reftype(sv,0), OP_DESC(PL_op)); + NOT_REACHED; /* NOTREACHED */ break; default: NOOP; } @@ -1767,6 +1768,7 @@ Perl_sv_setnv(pTHX_ SV *const sv, const NV num) /* diag_listed_as: Can't coerce %s to %s in %s */ Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0), OP_DESC(PL_op)); + NOT_REACHED; /* NOTREACHED */ break; default: NOOP; } @@ -2042,7 +2044,7 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv PERL_ARGS_ASSERT_SV_2IUV_NON_PRESERVE; PERL_UNUSED_CONTEXT; - DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_2iuv_non '%s', IV=0x%"UVxf" NV=%"NVgf" inttype=%"UVXf"\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv), (UV)numtype)); + DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_2iuv_non '%s', IV=0x%" UVxf " NV=%" NVgf " inttype=%" UVXf "\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv), (UV)numtype)); if (SvNVX(sv) < (NV)IV_MIN) { (void)SvIOKp_on(sv); (void)SvNOK_on(sv); @@ -2169,7 +2171,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) /* scalar has trailing garbage, eg "42a" */ } DEBUG_c(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" iv(%"NVgf" => %"IVdf") (precise)\n", + "0x%" UVxf " iv(%" NVgf " => %" IVdf ") (precise)\n", PTR2UV(sv), SvNVX(sv), SvIVX(sv))); @@ -2180,7 +2182,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) that PV->IV would be better than PV->NV->IV flags already correct - don't set public IOK. */ DEBUG_c(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" iv(%"NVgf" => %"IVdf") (imprecise)\n", + "0x%" UVxf " iv(%" NVgf " => %" IVdf ") (imprecise)\n", PTR2UV(sv), SvNVX(sv), SvIVX(sv))); @@ -2211,7 +2213,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) SvIOK_on(sv); SvIsUV_on(sv); DEBUG_c(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" 2iv(%"UVuf" => %"IVdf") (as unsigned)\n", + "0x%" UVxf " 2iv(%" UVuf " => %" IVdf ") (as unsigned)\n", PTR2UV(sv), SvUVX(sv), SvUVX(sv))); @@ -2219,7 +2221,24 @@ S_sv_2iuv_common(pTHX_ SV *const sv) } else if (SvPOKp(sv)) { UV value; - const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), &value); + int numtype; + const char *s = SvPVX_const(sv); + const STRLEN cur = SvCUR(sv); + + /* short-cut for a single digit string like "1" */ + + if (cur == 1) { + char c = *s; + if (isDIGIT(c)) { + if (SvTYPE(sv) < SVt_PVIV) + sv_upgrade(sv, SVt_PVIV); + (void)SvIOK_on(sv); + SvIV_set(sv, (IV)(c - '0')); + return FALSE; + } + } + + numtype = grok_number(s, cur, &value); /* We want to avoid a possible problem when we cache an IV/ a UV which may be later translated to an NV, and the resulting NV is not the same as the direct translation of the initial string @@ -2300,7 +2319,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) if (! numtype && ckWARN(WARN_NUMERIC)) not_a_number(sv); - DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2iv(%" NVgf ")\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2iv(%" NVgf ")\n", PTR2UV(sv), SvNVX(sv))); #ifdef NV_PRESERVES_UV @@ -2359,7 +2378,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) this NV is in the preserved range, therefore: */ if (!(U_V(SvNVX(sv) > 0 ? SvNVX(sv) : -SvNVX(sv)) < (UV)IV_MAX)) { - Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX); + Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%" NVgf " U_V is 0x%" UVxf ", IV_MAX is 0x%" UVxf "\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX); } } else { /* IN_UV NOT_INT @@ -2436,8 +2455,8 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags) } if (SvVALID(sv) || isREGEXP(sv)) { - /* FBMs use the space for SvIVX and SvNVX for other purposes, and use - the same flag bit as SVf_IVisUV, so must not let them cache IVs. + /* FBMs use the space for SvIVX and SvNVX for other purposes, so + must not let them cache IVs. In practice they are extremely unlikely to actually get anywhere accessible by user Perl code - the only way that I'm aware of is when a constant subroutine which is used as the second argument to index. @@ -2492,7 +2511,7 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags) return 0; } - DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2iv(%"IVdf")\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2iv(%" IVdf ")\n", PTR2UV(sv),SvIVX(sv))); return SvIsUV(sv) ? (IV)SvUVX(sv) : SvIVX(sv); } @@ -2575,7 +2594,7 @@ Perl_sv_2uv_flags(pTHX_ SV *const sv, const I32 flags) return 0; } - DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2uv(%"UVuf")\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2uv(%" UVuf ")\n", PTR2UV(sv),SvUVX(sv))); return SvIsUV(sv) ? SvUVX(sv) : (UV)SvIVX(sv); } @@ -2656,7 +2675,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags) DEBUG_c({ STORE_NUMERIC_LOCAL_SET_STANDARD(); PerlIO_printf(Perl_debug_log, - "0x%"UVxf" num(%" NVgf ")\n", + "0x%" UVxf " num(%" NVgf ")\n", PTR2UV(sv), SvNVX(sv)); RESTORE_NUMERIC_LOCAL(); }); @@ -2796,7 +2815,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags) } DEBUG_c({ STORE_NUMERIC_LOCAL_SET_STANDARD(); - PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2nv(%" NVgf ")\n", + PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2nv(%" NVgf ")\n", PTR2UV(sv), SvNVX(sv)); RESTORE_NUMERIC_LOCAL(); }); @@ -2902,8 +2921,8 @@ S_infnan_2pv(NV nv, char* buffer, size_t maxlen, char plus) { return 0; } assert((s == buffer + 3) || (s == buffer + 4)); - *s++ = 0; - return s - buffer - 1; /* -1: excluding the zero byte */ + *s = 0; + return s - buffer; } /* @@ -3166,6 +3185,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) assert(SvPOK(buffer)); if (SvUTF8(buffer)) SvUTF8_on(sv); + else + SvUTF8_off(sv); if (lp) *lp = SvCUR(buffer); return SvPVX(buffer); @@ -3193,7 +3214,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) *lp = len; SvCUR_set(sv, len); } - DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2pv(%s)\n", PTR2UV(sv),SvPVX_const(sv))); if (flags & SV_CONST_RETURN) return (char *)SvPVX_const(sv); @@ -3749,11 +3770,11 @@ Perl_sv_utf8_encode(pTHX_ SV *const sv) /* =for apidoc sv_utf8_decode -If the PV of the SV is an octet sequence in UTF-8 +If the PV of the SV is an octet sequence in Perl's extended UTF-8 and contains a multiple-byte character, the C flag is turned on so that it looks like a character. If the PV contains only single-byte characters, the C flag stays off. -Scans PV for validity and returns false if the PV is invalid UTF-8. +Scans PV for validity and returns FALSE if the PV is invalid UTF-8. =cut */ @@ -3765,7 +3786,6 @@ Perl_sv_utf8_decode(pTHX_ SV *const sv) if (SvPOKp(sv)) { const U8 *start, *c; - const U8 *e; /* The octets may have got themselves encoded - get them back as * bytes @@ -3779,13 +3799,8 @@ Perl_sv_utf8_decode(pTHX_ SV *const sv) c = start = (const U8 *) SvPVX_const(sv); if (!is_utf8_string(c, SvCUR(sv))) return FALSE; - e = (const U8 *) SvEND(sv); - while (c < e) { - const U8 ch = *c++; - if (!UTF8_IS_INVARIANT(ch)) { - SvUTF8_on(sv); - break; - } + if (! is_utf8_invariant_string(c, SvCUR(sv))) { + SvUTF8_on(sv); } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { /* XXX Is this dead code? XS_utf8_decode calls SvSETMAGIC @@ -4073,11 +4088,11 @@ Perl_gv_setref(pTHX_ SV *const dstr, SV *const sstr) sv_2mortal( stash ? Perl_newSVpvf(aTHX_ - "%"HEKf"::%"HEKf, + "%" HEKf "::%" HEKf, HEKfARG(HvNAME_HEK(stash)), HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr)))) : Perl_newSVpvf(aTHX_ - "%"HEKf, + "%" HEKf, HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr)))) ), cv, @@ -4273,12 +4288,17 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) * special-casing */ U32 sflags; U32 new_dflags; + SV *old_rv = NULL; /* minimal subset of SV_CHECK_THINKFIRST_COW_DROP(dstr) */ if (SvREADONLY(dstr)) Perl_croak_no_modify(); - if (SvROK(dstr)) - sv_unref_flags(dstr, 0); + if (SvROK(dstr)) { + if (SvWEAKREF(dstr)) + sv_unref_flags(dstr, 0); + else + old_rv = SvRV(dstr); + } assert(!SvGMAGICAL(sstr)); assert(!SvGMAGICAL(dstr)); @@ -4308,6 +4328,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) new_dflags = dtype; /* turn off everything except the type */ } SvFLAGS(dstr) = new_dflags; + SvREFCNT_dec(old_rv); return; } @@ -4734,8 +4755,6 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) } if (sflags & SVp_IOK) { SvIV_set(dstr, SvIVX(sstr)); - /* Must do this otherwise some other overloaded use of 0x80000000 - gets confused. I guess SVpbm_VALID */ if (sflags & SVf_IVisUV) SvIsUV_on(dstr); } @@ -4771,6 +4790,69 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) SvTAINT(dstr); } + +/* +=for apidoc sv_set_undef + +Equivalent to C, but more efficient. +Doesn't handle set magic. + +The perl equivalent is C<$sv = undef;>. Note that it doesn't free any string +buffer, unlike C. + +Introduced in perl 5.25.12. + +=cut +*/ + +void +Perl_sv_set_undef(pTHX_ SV *sv) +{ + U32 type = SvTYPE(sv); + + PERL_ARGS_ASSERT_SV_SET_UNDEF; + + /* shortcut, NULL, IV, RV */ + + if (type <= SVt_IV) { + assert(!SvGMAGICAL(sv)); + if (SvREADONLY(sv)) { + /* does undeffing PL_sv_undef count as modifying a read-only + * variable? Some XS code does this */ + if (sv == &PL_sv_undef) + return; + Perl_croak_no_modify(); + } + + if (SvROK(sv)) { + if (SvWEAKREF(sv)) + sv_unref_flags(sv, 0); + else { + SV *rv = SvRV(sv); + SvFLAGS(sv) = type; /* quickly turn off all flags */ + SvREFCNT_dec_NN(rv); + return; + } + } + SvFLAGS(sv) = type; /* quickly turn off all flags */ + return; + } + + if (SvIS_FREED(sv)) + Perl_croak(aTHX_ "panic: attempt to undefine a freed scalar %p", + (void *)sv); + + SV_CHECK_THINKFIRST_COW_DROP(sv); + + if (isGV_with_GP(sv)) + Perl_ck_warner(aTHX_ packWARN(WARN_MISC), + "Undefined value assigned to typeglob"); + else + SvOK_off(sv); +} + + + /* =for apidoc sv_setsv_mg @@ -4864,6 +4946,35 @@ Perl_sv_setsv_cow(pTHX_ SV *dstr, SV *sstr) #endif /* +=for apidoc sv_setpv_bufsize + +Sets the SV to be a string of cur bytes length, with at least +len bytes available. Ensures that there is a null byte at SvEND. +Returns a char * pointer to the SvPV buffer. + +=cut +*/ + +char * +Perl_sv_setpv_bufsize(pTHX_ SV *const sv, const STRLEN cur, const STRLEN len) +{ + char *pv; + + PERL_ARGS_ASSERT_SV_SETPV_BUFSIZE; + + SV_CHECK_THINKFIRST_COW_DROP(sv); + SvUPGRADE(sv, SVt_PV); + pv = SvGROW(sv, len + 1); + SvCUR_set(sv, cur); + *(SvEND(sv))= '\0'; + (void)SvPOK_only_UTF8(sv); /* validate pointer */ + + SvTAINT(sv); + if (SvTYPE(sv) == SVt_PVCV) CvAUTOLOAD_off(sv); + return pv; +} + +/* =for apidoc sv_setpvn Copies a string (possibly containing embedded C characters) into an SV. @@ -4882,6 +4993,8 @@ Perl_sv_setpvn(pTHX_ SV *const sv, const char *const ptr, const STRLEN len) PERL_ARGS_ASSERT_SV_SETPVN; SV_CHECK_THINKFIRST_COW_DROP(sv); + if (isGV_with_GP(sv)) + Perl_croak_no_modify(); if (!ptr) { (void)SvOK_off(sv); return; @@ -5102,28 +5215,6 @@ Perl_sv_usepvn_flags(pTHX_ SV *const sv, char *ptr, const STRLEN len, const U32 SvSETMAGIC(sv); } -/* -=for apidoc sv_force_normal_flags - -Undo various types of fakery on an SV, where fakery means -"more than" a string: if the PV is a shared string, make -a private copy; if we're a ref, stop refing; if we're a glob, downgrade to -an C; if we're a copy-on-write scalar, this is the on-write time when -we do the copy, and is also used locally; if this is a -vstring, drop the vstring magic. If C is set -then a copy-on-write scalar drops its PV buffer (if any) and becomes -C rather than making a copy. (Used where this -scalar is about to be set to some other value.) In addition, -the C parameter gets passed to C -when unreffing. C calls this function -with flags set to 0. - -This function is expected to be used to signal to perl that this SV is -about to be written to, and any extra book-keeping needs to be taken care -of. Hence, it croaks on read-only values. - -=cut -*/ static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags) @@ -5203,6 +5294,30 @@ S_sv_uncow(pTHX_ SV * const sv, const U32 flags) } } + +/* +=for apidoc sv_force_normal_flags + +Undo various types of fakery on an SV, where fakery means +"more than" a string: if the PV is a shared string, make +a private copy; if we're a ref, stop refing; if we're a glob, downgrade to +an C; if we're a copy-on-write scalar, this is the on-write time when +we do the copy, and is also used locally; if this is a +vstring, drop the vstring magic. If C is set +then a copy-on-write scalar drops its PV buffer (if any) and becomes +C rather than making a copy. (Used where this +scalar is about to be set to some other value.) In addition, +the C parameter gets passed to C +when unreffing. C calls this function +with flags set to 0. + +This function is expected to be used to signal to perl that this SV is +about to be written to, and any extra book-keeping needs to be taken care +of. Hence, it croaks on read-only values. + +=cut +*/ + void Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags) { @@ -5413,7 +5528,7 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c sv_utf8_upgrade_flags_grow(dsv, 0, slen + 1); dlen = SvCUR(dsv); } - else SvGROW(dsv, dlen + slen + 1); + else SvGROW(dsv, dlen + slen + 3); if (sstr == dstr) sstr = SvPVX_const(dsv); Move(sstr, SvPVX(dsv) + dlen, slen, char); @@ -5429,7 +5544,7 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c bytes *and* utf8, which would indicate a bug elsewhere. */ assert(sstr != dstr); - SvGROW(dsv, dlen + slen * 2 + 1); + SvGROW(dsv, dlen + slen * 2 + 3); d = (U8 *)SvPVX(dsv) + dlen; while (sstr < send) { @@ -5621,7 +5736,9 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, */ if (!obj || obj == sv || how == PERL_MAGIC_arylen || - how == PERL_MAGIC_symtab || + how == PERL_MAGIC_regdata || + how == PERL_MAGIC_regdatum || + how == PERL_MAGIC_symtab || (SvTYPE(obj) == SVt_PVGV && (GvSV(obj) == sv || GvHV(obj) == (const HV *)sv || GvAV(obj) == (const AV *)sv || GvCV(obj) == (const CV *)sv @@ -6189,7 +6306,7 @@ Perl_sv_kill_backrefs(pTHX_ SV *const sv, AV *const av) } else { Perl_croak(aTHX_ - "panic: magic_killbackrefs (flags=%"UVxf")", + "panic: magic_killbackrefs (flags=%" UVxf ")", (UV)SvFLAGS(referrer)); } @@ -6221,7 +6338,7 @@ C that applies to C. */ void -Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *const little, const STRLEN littlelen, const U32 flags) +Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *little, const STRLEN littlelen, const U32 flags) { char *big; char *mid; @@ -6234,6 +6351,16 @@ Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN l SvPV_force_flags(bigstr, curlen, flags); (void)SvPOK_only_UTF8(bigstr); + + if (little >= SvPVX(bigstr) && + little < SvPVX(bigstr) + (SvLEN(bigstr) ? SvLEN(bigstr) : SvCUR(bigstr))) { + /* little is a pointer to within bigstr, since we can reallocate bigstr, + or little...little+littlelen might overlap offset...offset+len we make a copy + */ + little = savepvn(little, littlelen); + SAVEFREEPV(little); + } + if (offset + len > curlen) { SvGROW(bigstr, offset+len+1); Zero(SvPVX(bigstr)+curlen, offset+len-curlen, char); @@ -6523,7 +6650,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) { if (PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ - "sv_clear clearing PL_stashcache for '%"HEKf + "sv_clear clearing PL_stashcache for '%" HEKf "'\n", HEKfARG(hek))); (void)hv_deletehek(PL_stashcache, @@ -6590,7 +6717,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) /* If we're in a stash, we don't own a reference to it. * However it does have a back reference to us, which * needs to be cleared. */ - if (!SvVALID(sv) && (stash = GvSTASH(sv))) + if ((stash = GvSTASH(sv))) sv_del_backref(MUTABLE_SV(stash), sv); } /* FIXME. There are probably more unreferenced pointers to SVs @@ -6747,7 +6874,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) #ifdef DEBUGGING if (SvTEMP(sv)) { Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING), - "Attempt to free temp prematurely: SV 0x%"UVxf + "Attempt to free temp prematurely: SV 0x%" UVxf pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE); continue; } @@ -6872,7 +6999,7 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) { if (check_refcnt && SvREFCNT(sv)) { if (PL_in_clean_objs) Perl_croak(aTHX_ - "DESTROY created new reference to dead object '%"HEKf"'", + "DESTROY created new reference to dead object '%" HEKf "'", HEKfARG(HvNAME_HEK(stash))); /* DESTROY gave object new lease on life */ return FALSE; @@ -6943,7 +7070,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc) #ifdef DEBUGGING if (SvTEMP(sv)) { Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING), - "Attempt to free temp prematurely: SV 0x%"UVxf + "Attempt to free temp prematurely: SV 0x%" UVxf pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE); return; } @@ -6990,7 +7117,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc) #endif /* This may not return: */ Perl_warner(aTHX_ packWARN(WARN_INTERNAL), - "Attempt to free unreferenced scalar: SV 0x%"UVxf + "Attempt to free unreferenced scalar: SV 0x%" UVxf pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE); #endif } @@ -7579,8 +7706,8 @@ Perl_sv_pos_b2u_flags(pTHX_ SV *const sv, STRLEN const offset, U32 flags) s = (const U8*)SvPV_flags(sv, blen, flags); if (blen < offset) - Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%"UVuf - ", byte=%"UVuf, (UV)blen, (UV)offset); + Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%" UVuf + ", byte=%" UVuf, (UV)blen, (UV)offset); send = s + offset; @@ -7697,7 +7824,7 @@ S_assert_uft8_cache_coherent(pTHX_ const char *const func, STRLEN from_cache, while printing error messages. */ SAVEI8(PL_utf8cache); PL_utf8cache = 0; - Perl_croak(aTHX_ "panic: %s cache %"UVuf" real %"UVuf" for %"SVf, + Perl_croak(aTHX_ "panic: %s cache %" UVuf " real %" UVuf " for %" SVf, func, (UV) from_cache, (UV) real, SVfARG(sv)); } @@ -8540,10 +8667,10 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) /* some trace debug output */ DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: entering, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt)); + "Screamer: entering, ptr=%" UVuf ", cnt=%ld\n",PTR2UV(ptr),(long)cnt)); DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%"IVdf", base=%" - UVuf"\n", + "Screamer: entering: PerlIO * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" + UVuf "\n", PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0))); @@ -8553,13 +8680,27 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) if (cnt > 0) { /* if there is a separator */ if (rslen) { - /* loop until we hit the end of the read-ahead buffer */ - while (cnt > 0) { /* this | eat */ - /* scan forward copying and searching for rslast as we go */ - cnt--; - if ((*bp++ = *ptr++) == rslast) /* really | dust */ - goto thats_all_folks; /* screams | sed :-) */ - } + /* find next rslast */ + STDCHAR *p; + + /* shortcut common case of blank line */ + cnt--; + if ((*bp++ = *ptr++) == rslast) + goto thats_all_folks; + + p = (STDCHAR *)memchr(ptr, rslast, cnt); + if (p) { + SSize_t got = p - ptr + 1; + Copy(ptr, bp, got, STDCHAR); + ptr += got; + bp += got; + cnt -= got; + goto thats_all_folks; + } + Copy(ptr, bp, cnt, STDCHAR); + ptr += cnt; + bp += cnt; + cnt = 0; } else { /* no separator, slurp the full buffer */ @@ -8589,12 +8730,12 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) /* we need to refill the read-ahead buffer if possible */ DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: going to getc, ptr=%"UVuf", cnt=%"IVdf"\n", + "Screamer: going to getc, ptr=%" UVuf ", cnt=%" IVdf "\n", PTR2UV(ptr),(IV)cnt)); PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* deregisterize cnt and ptr */ DEBUG_Pv(PerlIO_printf(Perl_debug_log, - "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf"\n", + "Screamer: pre: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf "\n", PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); @@ -8610,7 +8751,7 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) i = PerlIO_getc(fp); /* get more characters */ DEBUG_Pv(PerlIO_printf(Perl_debug_log, - "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf"\n", + "Screamer: post: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf "\n", PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); @@ -8618,7 +8759,7 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) cnt = PerlIO_get_cnt(fp); ptr = (STDCHAR*)PerlIO_get_ptr(fp); /* reregisterize cnt and ptr */ DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: after getc, ptr=%"UVuf", cnt=%"IVdf"\n", + "Screamer: after getc, ptr=%" UVuf ", cnt=%" IVdf "\n", PTR2UV(ptr),(IV)cnt)); if (i == EOF) /* all done for ever? */ @@ -8648,10 +8789,10 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) if (shortbuffered) cnt += shortbuffered; DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: quitting, ptr=%"UVuf", cnt=%"IVdf"\n",PTR2UV(ptr),(IV)cnt)); + "Screamer: quitting, ptr=%" UVuf ", cnt=%" IVdf "\n",PTR2UV(ptr),(IV)cnt)); PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* put these back or we're in trouble */ DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%"IVdf", base=%"UVuf + "Screamer: end: FILE * thinks ptr=%" UVuf ", cnt=%" IVdf ", base=%" UVuf "\n", PTR2UV(PerlIO_get_ptr(fp)), (IV)PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); @@ -8870,7 +9011,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) /* I don't think we can get here. Maybe I should assert this And if we do get here I suspect that sv_setnv will croak. NWC Fall through. */ - DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_inc punt failed to convert '%s' to IOK or NOKp, UV=0x%"UVxf" NV=%"NVgf"\n", + DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_inc punt failed to convert '%s' to IOK or NOKp, UV=0x%" UVxf " NV=%" NVgf "\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv))); } #endif /* PERL_PRESERVE_IVUV */ @@ -9048,7 +9189,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv) /* I don't think we can get here. Maybe I should assert this And if we do get here I suspect that sv_setnv will croak. NWC Fall through. */ - DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_dec punt failed to convert '%s' to IOK or NOKp, UV=0x%"UVxf" NV=%"NVgf"\n", + DEBUG_c(PerlIO_printf(Perl_debug_log,"sv_dec punt failed to convert '%s' to IOK or NOKp, UV=0x%" UVxf " NV=%" NVgf "\n", SvPVX_const(sv), SvIVX(sv), SvNVX(sv))); } } @@ -9204,7 +9345,14 @@ SV is set to 1. If C is zero, Perl will compute the length using C, (which means if you use this option, that C can't have embedded C characters and has to have a terminating C byte). -For efficiency, consider using C instead. +This function can cause reliability issues if you are likely to pass in +empty strings that are not null terminated, because it will run +strlen on the string and potentially run past valid memory. + +Using L is a safer alternative for non C terminated strings. +For string literals use L instead. This function will work fine for +C terminated strings, but if you want to avoid the if statement on whether +to call C use C instead (calling C yourself). =cut */ @@ -9742,7 +9890,7 @@ Perl_sv_2io(pTHX_ SV *const sv) gv = MUTABLE_GV(sv); io = GvIO(gv); if (!io) - Perl_croak(aTHX_ "Bad filehandle: %"HEKf, + Perl_croak(aTHX_ "Bad filehandle: %" HEKf, HEKfARG(GvNAME_HEK(gv))); break; } @@ -9765,7 +9913,7 @@ Perl_sv_2io(pTHX_ SV *const sv) newsv = sv_newmortal(); sv_setsv_nomg(newsv, sv); } - Perl_croak(aTHX_ "Bad filehandle: %"SVf, SVfARG(newsv)); + Perl_croak(aTHX_ "Bad filehandle: %" SVf, SVfARG(newsv)); } break; } @@ -9947,7 +10095,7 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) if (!SvPOK(sv)) { SvPOK_on(sv); /* validate pointer */ SvTAINT(sv); - DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%" UVxf " 2pv(%s)\n", PTR2UV(sv),SvPVX_const(sv))); } } @@ -10081,7 +10229,7 @@ Perl_sv_ref(pTHX_ SV *dst, const SV *const sv, const int ob) if (ob && SvOBJECT(sv)) { HvNAME_get(SvSTASH(sv)) ? sv_sethek(dst, HvNAME_HEK(SvSTASH(sv))) - : sv_setpvn(dst, "__ANON__", 8); + : sv_setpvs(dst, "__ANON__"); } else { const char * reftype = sv_reftype(sv, 0); @@ -10230,7 +10378,7 @@ Perl_sv_setref_pv(pTHX_ SV *const rv, const char *const classname, void *const p PERL_ARGS_ASSERT_SV_SETREF_PV; if (!pv) { - sv_setsv(rv, &PL_sv_undef); + sv_set_undef(rv); SvSETMAGIC(rv); } else @@ -10811,7 +10959,7 @@ Perl_sv_vsetpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, { PERL_ARGS_ASSERT_SV_VSETPVFN; - sv_setpvs(sv, ""); + SvPVCLEAR(sv); sv_vcatpvfn_flags(sv, pat, patlen, args, svargs, svmax, maybe_tainted, 0); } @@ -10978,8 +11126,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, * are being extracted from (either directly from the long double in-memory * presentation, or from the uquad computed via frexp+ldexp). frexp also * is used to update the exponent. The subnormal is set to true - * for IEEE 754 subnormals/denormals. The vhex is the pointer to - * the beginning of the output buffer (of VHEX_SIZE). + * for IEEE 754 subnormals/denormals (including the x86 80-bit format). + * The vhex is the pointer to the beginning of the output buffer of VHEX_SIZE. * * The tricky part is that S_hextract() needs to be called twice: * the first time with vend as NULL, and the second time with vend as @@ -11030,9 +11178,10 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, for (ix = a; ix >= b; ix--) { HEXTRACT_BYTE(ix); } #define HEXTRACT_BYTES_BE(a, b) \ for (ix = a; ix <= b; ix++) { HEXTRACT_BYTE(ix); } +#define HEXTRACT_GET_SUBNORMAL(nv) *subnormal = Perl_fp_class_denorm(nv) #define HEXTRACT_IMPLICIT_BIT(nv) \ STMT_START { \ - if (!(*subnormal = (HEXTRACT_EXPONENT_BITS() == 0))) { \ + if (!*subnormal) { \ if (vend) *v++ = ((nv) == 0.0) ? 0 : 1; else v++; \ } \ } STMT_END @@ -11070,7 +11219,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, /* The bytes 13..0 are the mantissa/fraction, * the 15,14 are the sign+exponent. */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() (nvp[14] | (nvp[15] & 0x7F) << 8) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); # undef HEXTRACT_HAS_TOP_NYBBLE HEXTRACT_BYTES_LE(13, 0); @@ -11080,7 +11229,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, /* The bytes 2..15 are the mantissa/fraction, * the 0,1 are the sign+exponent. */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() ((nvp[0] & 0x7F) << 8 | nvp[1]) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); # undef HEXTRACT_HAS_TOP_NYBBLE HEXTRACT_BYTES_BE(2, 15); @@ -11089,10 +11238,12 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, * significand, 15 bits of exponent, 1 bit of sign. No implicit bit. * NVSIZE can be either 12 (ILP32, Solaris x86) or 16 (LP64, Linux * and OS X), meaning that 2 or 6 bytes are empty padding. */ - /* The bytes 7..0 are the mantissa/fraction */ + /* The bytes 0..1 are the sign+exponent, + * the bytes 2..9 are the mantissa/fraction. */ const U8* nvp = (const U8*)(&nv); # undef HEXTRACT_HAS_IMPLICIT_BIT # undef HEXTRACT_HAS_TOP_NYBBLE + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_BYTES_LE(7, 0); # elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN /* Does this format ever happen? (Wikipedia says the Motorola @@ -11102,6 +11253,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, const U8* nvp = (const U8*)(&nv); # undef HEXTRACT_HAS_IMPLICIT_BIT # undef HEXTRACT_HAS_TOP_NYBBLE + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_BYTES_BE(0, 7); # else # define HEXTRACT_FALLBACK @@ -11137,21 +11289,21 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, # ifdef HEXTRACT_LITTLE_ENDIAN /* 0 1 2 3 4 5 6 7 (MSB = 7, LSB = 0, 6+7 = exponent+sign) */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() (nvp[6] | (nvp[7] & 0x7F) << 4) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); HEXTRACT_TOP_NYBBLE(6); HEXTRACT_BYTES_LE(5, 0); # elif defined(HEXTRACT_BIG_ENDIAN) /* 7 6 5 4 3 2 1 0 (MSB = 7, LSB = 0, 6+7 = exponent+sign) */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() (nvp[1] | (nvp[0] & 0x7F) << 4) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); HEXTRACT_TOP_NYBBLE(1); HEXTRACT_BYTES_BE(2, 7); # elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE /* 4 5 6 7 0 1 2 3 (MSB = 7, LSB = 0, 6:7 = nybble:exponent:sign) */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() (nvp[2] | (nvp[3] & 0x7F) << 4) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); HEXTRACT_TOP_NYBBLE(2); /* 6 */ HEXTRACT_BYTE(1); /* 5 */ @@ -11163,7 +11315,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, # elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE /* 3 2 1 0 7 6 5 4 (MSB = 7, LSB = 0, 7:6 = sign:exponent:nybble) */ const U8* nvp = (const U8*)(&nv); -# define HEXTRACT_EXPONENT_BITS() (nvp[5] | (nvp[4] & 0x7F) << 4) + HEXTRACT_GET_SUBNORMAL(nv); HEXTRACT_IMPLICIT_BIT(nv); HEXTRACT_TOP_NYBBLE(5); /* 6 */ HEXTRACT_BYTE(6); /* 5 */ @@ -11180,6 +11332,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, # endif #endif /* #if defined(USE_LONG_DOUBLE) && (NVSIZE > DOUBLESIZE) #else */ # ifdef HEXTRACT_FALLBACK + HEXTRACT_GET_SUBNORMAL(nv); # undef HEXTRACT_HAS_TOP_NYBBLE /* Meaningless, but consistent. */ /* The fallback is used for the double-double format, and * for unknown long double formats, and for unknown double @@ -11291,6 +11444,12 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal, } STMT_END void + + +/* This function assumes that pat has the same utf8-ness as sv. + * It's the caller's responsibility to ensure that this is so. + */ + Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, va_list *const args, SV **const svargs, const I32 svmax, bool *const maybe_tainted, const U32 flags) @@ -11474,9 +11633,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p # define FV_ISFINITE(x) Perl_isfinite((NV)(x)) #endif NV nv; - STRLEN have; - STRLEN need; - STRLEN gap; + STRLEN float_need; /* what PL_efloatsize needs to become */ const char *dotstr = "."; STRLEN dotstrlen = 1; I32 efix = 0; /* explicit format parameter index */ @@ -11749,7 +11906,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p * vectorize happen normally */ if (sv_isobject(vecsv) && sv_derived_from(vecsv, "version")) { - if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) { + if ( hv_existss(MUTABLE_HV(SvRV(vecsv)), "alpha") ) { Perl_ck_warner_d(aTHX_ packWARN(WARN_PRINTF), "vector argument not supported with alpha versions"); goto vdblank; @@ -11873,7 +12030,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p if (vectorize) goto unknown; if (infnan) - Perl_croak(aTHX_ "Cannot printf %"NVgf" with '%c'", + Perl_croak(aTHX_ "Cannot printf %" NVgf " with '%c'", /* no va_arg() case */ SvNV_nomg(argsv), (int)c); uv = (args) ? va_arg(*args, int) : SvIV_nomg(argsv); @@ -12254,14 +12411,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p NV_TO_FV(nv, fv); } - need = 0; + float_need = 0; /* frexp() (or frexpl) has some unspecified behaviour for * nan/inf/-inf, so let's avoid calling that on non-finites. */ if (isALPHA_FOLD_NE(c, 'e') && FV_ISFINITE(fv)) { i = PERL_INT_MIN; (void)Perl_frexp((NV)fv, &i); if (i == PERL_INT_MIN) - Perl_die(aTHX_ "panic: frexp: %"FV_GF, fv); + Perl_die(aTHX_ "panic: frexp: %" FV_GF, fv); /* Do not set hexfp earlier since we want to printf * Inf/NaN for Inf/NaN, not their hexfp. */ hexfp = isALPHA_FOLD_EQ(c, 'a'); @@ -12272,7 +12429,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p * exponent. Secondly, for the reasonably common * long doubles case, the "80-bit extended", two * or six bytes of the NV are unused. */ - need += + float_need += (fv < 0) ? 1 : 0 + /* possible unary minus */ 2 + /* "0x" */ 1 + /* the very unlikely carry */ @@ -12291,24 +12448,30 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p * See the definition of DOUBLEDOUBLE_MAXBITS. * * Need 2 hexdigits for each byte. */ - need += (DOUBLEDOUBLE_MAXBITS/8 + 1) * 2; + float_need += (DOUBLEDOUBLE_MAXBITS/8 + 1) * 2; /* the size for the exponent already added */ #endif #ifdef USE_LOCALE_NUMERIC STORE_LC_NUMERIC_SET_TO_NEEDED(); if (PL_numeric_radix_sv && IN_LC(LC_NUMERIC)) - need += SvLEN(PL_numeric_radix_sv); + float_need += SvLEN(PL_numeric_radix_sv); RESTORE_LC_NUMERIC(); #endif } else if (i > 0) { - need = BIT_DIGITS(i); + float_need = BIT_DIGITS(i); } /* if i < 0, the number of digits is hard to predict. */ } - need += has_precis ? precis : 6; /* known default */ - if (need < width) - need = width; + { + STRLEN pr = has_precis ? precis : 6; /* known default */ + if (float_need >= ((STRLEN)~0) - pr) + croak_memory_wrap(); + float_need += pr; + } + + if (float_need < width) + float_need = width; #ifdef HAS_LDBL_SPRINTF_BUG /* This is to try to fix a bug with irix/nonstop-ux/powerux and @@ -12342,7 +12505,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p if ((intsize == 'q') && (c == 'f') && ((fv < MY_DBL_MAX_BUG) && (fv > -MY_DBL_MAX_BUG)) && - (need < DBL_DIG)) { + (float_need < DBL_DIG)) { /* it's going to be short enough that * long double precision is not needed */ @@ -12376,10 +12539,12 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p #endif /* HAS_LDBL_SPRINTF_BUG */ - need += 20; /* fudge factor */ - if (PL_efloatsize < need) { + if (float_need >= ((STRLEN)~0) - 40) + croak_memory_wrap(); + float_need += 40; /* fudge factor */ + if (PL_efloatsize < float_need) { Safefree(PL_efloatbuf); - PL_efloatsize = need + 20; /* more fudge */ + PL_efloatsize = float_need; Newx(PL_efloatbuf, PL_efloatsize, char); PL_efloatbuf[0] = '\0'; } @@ -12421,6 +12586,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p int exponent = 0; /* exponent of the floating point input */ bool hexradix = FALSE; /* should we output the radix */ bool subnormal = FALSE; /* IEEE 754 subnormal/denormal */ + bool negative = FALSE; /* XXX: NaN, Inf -- though they are printed as "NaN" and "Inf". * @@ -12436,21 +12602,30 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p #if NVSIZE > DOUBLESIZE # ifdef HEXTRACT_HAS_IMPLICIT_BIT /* In this case there is an implicit bit, - * and therefore the exponent is shifted by one, - * unless this is a subnormal/denormal. */ - if (!subnormal) { - exponent--; - } + * and therefore the exponent is shifted by one. */ + exponent--; # else - /* In this case there is no implicit bit, - * and the exponent is shifted by the first xdigit. */ - exponent -= 4; +# ifdef NV_X86_80_BIT + if (subnormal) { + /* The subnormals of the x86-80 have a base exponent of -16382, + * (while the physical exponent bits are zero) but the frexp() + * returned the scientific-style floating exponent. We want + * to map the last one as: + * -16831..-16384 -> -16382 (the last normal is 0x1p-16382) + * -16835..-16388 -> -16384 + * since we want to keep the first hexdigit + * as one of the [8421]. */ + exponent = -4 * ( (exponent + 1) / -4) - 2; + } else { + exponent -= 4; + } +# endif + /* TBD: other non-implicit-bit platforms than the x86-80. */ # endif #endif - if (fv < 0 - || Perl_signbit(nv) - ) + negative = fv < 0 || Perl_signbit(nv); + if (negative) *p++ = '-'; else if (plus) *p++ = plus; @@ -12486,10 +12661,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p #endif if (subnormal) { +#ifndef NV_X86_80_BIT if (vfnz[0] > 1) { - /* We need to right shift the hex nybbles so - * that the output of the subnormal starts - * from the first true bit. */ + /* IEEE 754 subnormals (but not the x86 80-bit): + * we want "normalize" the subnormal, + * so we need to right shift the hex nybbles + * so that the output of the subnormal starts + * from the first true bit. (Another, equally + * valid, policy would be to dump the subnormal + * nybbles as-is, to display the "physical" layout.) */ int i, n; U8 *vshr; /* Find the ceil(log2(v[0])) of @@ -12505,6 +12685,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p vlnz++; } } +#endif v0 = vfnz; } else { v0 = vhex; @@ -12512,41 +12693,54 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p if (has_precis) { U8* ve = (subnormal ? vlnz + 1 : vend); - SSize_t vn = ve - (subnormal ? vfnz : vhex); + SSize_t vn = ve - v0; if ((SSize_t)(precis + 1) < vn) { - bool round; - - v = v0 + precis + 1; - /* Round away from zero: if the tail - * beyond the precis xdigits is equal to - * or greater than 0x8000... */ - round = *v > 0x8; - if (!round && *v == 0x8) { - for (v++; v < ve; v++) { - if (*v) { - round = TRUE; - break; - } + bool overflow = FALSE; + if (v0[precis + 1] < 0x8) { + /* Round down, nothing to do. */ + } else if (v0[precis + 1] > 0x8) { + /* Round up. */ + v0[precis]++; + overflow = v0[precis] > 0xF; + v0[precis] &= 0xF; + } else { /* v0[precis] == 0x8 */ + /* Half-point: round towards the one + * with the even least-significant digit: + * 08 -> 0 88 -> 8 + * 18 -> 2 98 -> a + * 28 -> 2 a8 -> a + * 38 -> 4 b8 -> c + * 48 -> 4 c8 -> c + * 58 -> 6 d8 -> e + * 68 -> 6 e8 -> e + * 78 -> 8 f8 -> 10 */ + if ((v0[precis] & 0x1)) { + v0[precis]++; } + overflow = v0[precis] > 0xF; + v0[precis] &= 0xF; } - if (round) { - for (v = v0 + precis; v >= v0; v--) { - if (*v < 0xF) { - (*v)++; + + if (overflow) { + for (v = v0 + precis - 1; v >= v0; v--) { + (*v)++; + overflow = *v > 0xF; + (*v) &= 0xF; + if (!overflow) { break; } - *v = 0; - if (v == v0) { - /* If the carry goes all the way to - * the front, we need to output - * a single '1'. This goes against - * the "xdigit and then radix" - * but since this is "cannot happen" - * category, that is probably good. */ - *p++ = xdig[1]; - } + } + if (v == v0 - 1 && overflow) { + /* If the overflow goes all the + * way to the front, we need to + * insert 0x1 in front, and adjust + * the exponent. */ + Move(v0, v0 + 1, vn, char); + *v0 = 0x1; + exponent += 4; } } + /* The new effective "last non zero". */ vlnz = v0 + precis; } @@ -12617,12 +12811,18 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p memset(PL_efloatbuf + elen, ' ', width - elen); } else if (fill == '0') { - /* Insert the zeros between the "0x" and - * the digits, otherwise we end up with - * "0000xHHH..." */ + /* Insert the zeros after the "0x" and the + * the potential sign, but before the digits, + * otherwise we end up with "0000xH.HHH...", + * when we want "0x000H.HHH..." */ STRLEN nzero = width - elen; char* zerox = PL_efloatbuf + 2; - Move(zerox, zerox + nzero, elen - 2, char); + STRLEN nmove = elen - 2; + if (negative || plus) { + zerox++; + nmove--; + } + Move(zerox, zerox + nzero, nmove, char); memset(zerox, fill, nzero); } else { @@ -12713,8 +12913,11 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", ptr); elen = quadmath_snprintf(PL_efloatbuf, PL_efloatsize, qfmt, nv); - if ((IV)elen == -1) + if ((IV)elen == -1) { + if (qfmt != ptr) + SAVEFREEPV(qfmt); Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", qfmt); + } if (qfmt != ptr) Safefree(qfmt); } @@ -12796,29 +12999,20 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p sv_catpvn_nomg(msg, f, 1); } else { Perl_sv_catpvf(aTHX_ msg, - "\\%03"UVof, (UV)*f & 0xFF); + "\\%03" UVof, (UV)*f & 0xFF); } } sv_catpvs(msg, "\""); } else { sv_catpvs(msg, "end of string"); } - Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%"SVf, SVfARG(msg)); /* yes, this is reentrant */ + Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%" SVf, SVfARG(msg)); /* yes, this is reentrant */ } - /* output mangled stuff ... */ - if (c == '\0') - --q; - eptr = p; - elen = q - p; - - /* ... right here, because formatting flags should not apply */ - SvGROW(sv, SvCUR(sv) + elen + 1); - p = SvEND(sv); - Copy(eptr, p, elen, char); - p += elen; - *p = '\0'; - SvCUR_set(sv, p - SvPVX_const(sv)); + /* mangled format: output the '%', then continue from the + * character following that */ + sv_catpvn_nomg(sv, p, 1); + q = p + 1; svix = osvix; continue; /* not "break" */ } @@ -12842,60 +13036,89 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } } - /* signed value that's wrapped? */ - assert(elen <= ((~(STRLEN)0) >> 1)); - have = esignlen + zeros + elen; - if (have < zeros) - croak_memory_wrap(); - - need = (have > width ? have : width); - gap = need - have; - - if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1)) - croak_memory_wrap(); - SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1); - p = SvEND(sv); - if (esignlen && fill == '0') { - int i; - for (i = 0; i < (int)esignlen; i++) - *p++ = esignbuf[i]; - } - if (gap && !left) { - memset(p, fill, gap); - p += gap; - } - if (esignlen && fill != '0') { - int i; - for (i = 0; i < (int)esignlen; i++) - *p++ = esignbuf[i]; - } - if (zeros) { - int i; - for (i = zeros; i; i--) - *p++ = '0'; - } - if (elen) { - Copy(eptr, p, elen, char); - p += elen; - } - if (gap && left) { - memset(p, ' ', gap); - p += gap; - } - if (vectorize) { - if (veclen) { - Copy(dotstr, p, dotstrlen, char); - p += dotstrlen; - } - else - vectorize = FALSE; /* done iterating over vecstr */ - } - if (is_utf8) - has_utf8 = TRUE; - if (has_utf8) - SvUTF8_on(sv); - *p = '\0'; - SvCUR_set(sv, p - SvPVX_const(sv)); + + /* append esignbuf, filler, zeros, eptr and dotstr to sv */ + + { + STRLEN need, have, gap; + + /* signed value that's wrapped? */ + assert(elen <= ((~(STRLEN)0) >> 1)); + + /* Most of these length vars can range to any value if + * supplied with a hostile format and/or args. So check every + * addition for possible overflow. In reality some of these + * values are interdependent so these checks are slightly + * redundant. But its easier to be certain this way. + */ + + have = elen; + + if (have >= (((STRLEN)~0) - zeros)) + croak_memory_wrap(); + have += zeros; + + if (have >= (((STRLEN)~0) - esignlen)) + croak_memory_wrap(); + have += esignlen; + + need = (have > width ? have : width); + gap = need - have; + + if (need >= (((STRLEN)~0) - dotstrlen)) + croak_memory_wrap(); + need += dotstrlen; + + if (need >= (((STRLEN)~0) - (SvCUR(sv) + 1))) + croak_memory_wrap(); + need += (SvCUR(sv) + 1); + + SvGROW(sv, need); + + p = SvEND(sv); + if (esignlen && fill == '0') { + int i; + for (i = 0; i < (int)esignlen; i++) + *p++ = esignbuf[i]; + } + if (gap && !left) { + memset(p, fill, gap); + p += gap; + } + if (esignlen && fill != '0') { + int i; + for (i = 0; i < (int)esignlen; i++) + *p++ = esignbuf[i]; + } + if (zeros) { + int i; + for (i = zeros; i; i--) + *p++ = '0'; + } + if (elen) { + Copy(eptr, p, elen, char); + p += elen; + } + if (gap && left) { + memset(p, ' ', gap); + p += gap; + } + if (vectorize) { + if (veclen) { + Copy(dotstr, p, dotstrlen, char); + p += dotstrlen; + } + else + vectorize = FALSE; /* done iterating over vecstr */ + } + if (is_utf8) + has_utf8 = TRUE; + if (has_utf8) + SvUTF8_on(sv); + *p = '\0'; + SvCUR_set(sv, p - SvPVX_const(sv)); + } + if (vectorize) { esignlen = 0; goto vector; @@ -12990,7 +13213,7 @@ Perl_parser_dup(pTHX_ const yy_parser *const proto, CLONE_PARAMS *const param) parser->old_parser = NULL; parser->stack = NULL; parser->ps = NULL; - parser->stack_size = 0; + parser->stack_max1 = 0; /* XXX parser->stack->state = 0; */ /* XXX eventually, just Copy() most of the parser struct ? */ @@ -13033,6 +13256,7 @@ Perl_parser_dup(pTHX_ const yy_parser *const proto, CLONE_PARAMS *const param) parser->sig_elems = proto->sig_elems; parser->sig_optelems= proto->sig_optelems; parser->sig_slurpy = proto->sig_slurpy; + parser->recheck_utf8_validity = proto->recheck_utf8_validity; parser->linestr = sv_dup_inc(proto->linestr, param); { @@ -13296,7 +13520,10 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) ? SvREFCNT_inc(av_dup_inc((const AV *) nmg->mg_obj, param)) : sv_dup_inc(nmg->mg_obj, param) - : sv_dup(nmg->mg_obj, param); + : (nmg->mg_type == PERL_MAGIC_regdatum || + nmg->mg_type == PERL_MAGIC_regdata) + ? nmg->mg_obj + : sv_dup(nmg->mg_obj, param); if (nmg->mg_ptr && nmg->mg_type != PERL_MAGIC_regex_global) { if (nmg->mg_len > 0) { @@ -13691,6 +13918,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) switch (sv_type) { default: Perl_croak(aTHX_ "Bizarre SvTYPE [%" IVdf "]", (IV)SvTYPE(sstr)); + NOT_REACHED; /* NOTREACHED */ break; case SVt_PVGV: @@ -14069,7 +14297,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) case CXt_EVAL: ncx->blk_eval.old_namesv = sv_dup_inc(ncx->blk_eval.old_namesv, param); - /* XXX should this sv_dup_inc? Or only if SvSCREAM ???? */ + /* XXX should this sv_dup_inc? Or only if CxEVAL_TXT_REFCNTED ???? */ ncx->blk_eval.cur_text = sv_dup(ncx->blk_eval.cur_text, param); ncx->blk_eval.cv = cv_dup(ncx->blk_eval.cv, param); /* XXX what do do with cur_top_env ???? */ @@ -14498,7 +14726,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) break; default: Perl_croak(aTHX_ - "panic: ss_dup inconsistency (%"IVdf")", (IV) type); + "panic: ss_dup inconsistency (%" IVdf ")", (IV) type); } } @@ -14761,8 +14989,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_forkprocess = proto_perl->Iforkprocess; /* internal state */ - PL_maxo = proto_perl->Imaxo; - PL_main_start = proto_perl->Imain_start; PL_eval_root = proto_perl->Ieval_root; PL_eval_start = proto_perl->Ieval_start; @@ -14889,7 +15115,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_Xpv = (XPV*)NULL; my_perl->Ina = proto_perl->Ina; - PL_statbuf = proto_perl->Istatbuf; PL_statcache = proto_perl->Istatcache; #ifndef NO_TAINT_SUPPORT @@ -14996,9 +15221,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, /* magical thingies */ - sv_setpvs(PERL_DEBUG_PAD(0), ""); /* For regex debugging. */ - sv_setpvs(PERL_DEBUG_PAD(1), ""); /* ext/re needs these */ - sv_setpvs(PERL_DEBUG_PAD(2), ""); /* even without DEBUGGING. */ + SvPVCLEAR(PERL_DEBUG_PAD(0)); /* For regex debugging. */ + SvPVCLEAR(PERL_DEBUG_PAD(1)); /* ext/re needs these */ + SvPVCLEAR(PERL_DEBUG_PAD(2)); /* even without DEBUGGING. */ /* Clone the regex array */ @@ -15170,6 +15395,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_GCB_invlist = sv_dup_inc(proto_perl->IGCB_invlist, param); PL_SB_invlist = sv_dup_inc(proto_perl->ISB_invlist, param); PL_WB_invlist = sv_dup_inc(proto_perl->IWB_invlist, param); + PL_seen_deprecated_macro = hv_dup_inc(proto_perl->Iseen_deprecated_macro, param); PL_utf8_mark = sv_dup_inc(proto_perl->Iutf8_mark, param); PL_utf8_toupper = sv_dup_inc(proto_perl->Iutf8_toupper, param); PL_utf8_totitle = sv_dup_inc(proto_perl->Iutf8_totitle, param); @@ -15276,7 +15502,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_watchok = PL_watchaddr ? * PL_watchaddr : NULL; if (PL_debug && PL_watchaddr) { PerlIO_printf(Perl_debug_log, - "WATCHING: %"UVxf" cloned as %"UVxf" with value %"UVxf"\n", + "WATCHING: %" UVxf " cloned as %" UVxf " with value %" UVxf "\n", PTR2UV(proto_perl->Iwatchaddr), PTR2UV(PL_watchaddr), PTR2UV(PL_watchok)); } @@ -15724,7 +15950,7 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ, } else if (subscript_type == FUV_SUBSCRIPT_ARRAY) { *SvPVX(name) = '$'; - Perl_sv_catpvf(aTHX_ name, "[%"IVdf"]", (IV)aindex); + Perl_sv_catpvf(aTHX_ name, "[%" IVdf "]", (IV)aindex); } else if (subscript_type == FUV_SUBSCRIPT_WITHIN) { /* We know that name has no magic, so can use 0 instead of SV_GMAGIC */ @@ -15774,6 +16000,11 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, switch (obase->op_type) { + case OP_UNDEF: + /* undef should care if its args are undef - any warnings + * will be from tied/magic vars */ + break; + case OP_RV2AV: case OP_RV2HV: case OP_PADAV: @@ -16226,6 +16457,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, */ break; } + match = 1; goto do_op; /* ops where $_ may be an implicit arg */ @@ -16319,7 +16551,6 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, case OP_ALARM: case OP_SEMGET: case OP_GETLOGIN: - case OP_UNDEF: case OP_SUBSTR: case OP_AEACH: case OP_EACH: