X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/586fc6a31347339bf2b16e391b44aa458f723283..9fc05455cdaab916bba78bf0aec9b491fbb3e5dd:/sv.c diff --git a/sv.c b/sv.c index d10e5a5..8ef01c9 100644 --- a/sv.c +++ b/sv.c @@ -41,8 +41,6 @@ # include #endif -#define FCALL *f - #ifdef __Lynx__ /* Missing proto on LynxOS */ char *gconvert(double, int, int, char *); @@ -419,7 +417,7 @@ S_visit(pTHX_ SVFUNC_t f, const U32 flags, const U32 mask) && (sv->sv_flags & mask) == flags && SvREFCNT(sv)) { - (FCALL)(aTHX_ sv); + (*f)(aTHX_ sv); ++visited; } } @@ -881,11 +879,6 @@ static const struct body_details bodies_by_type[] = { /* HEs use this offset for their arena. */ { 0, 0, 0, SVt_NULL, FALSE, NONV, NOARENA, 0 }, - /* The bind placeholder pretends to be an RV for now. - Also it's marked as "can't upgrade" to stop anyone using it before it's - implemented. */ - { 0, 0, 0, SVt_DUMMY, TRUE, NONV, NOARENA, 0 }, - /* IVs are in the head, so the allocation size is 0. */ { 0, sizeof(IV), /* This is used to copy out the IV body. */ @@ -903,6 +896,12 @@ static const struct body_details bodies_by_type[] = { SVt_PV, FALSE, NONV, HASARENA, FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) }, + { sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur), + copy_length(XINVLIST, is_offset) - STRUCT_OFFSET(XPV, xpv_cur), + + STRUCT_OFFSET(XPV, xpv_cur), + SVt_INVLIST, TRUE, NONV, HASARENA, + FIT_ARENA(0, sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur)) }, + { sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur), copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur), + STRUCT_OFFSET(XPV, xpv_cur), @@ -921,7 +920,7 @@ static const struct body_details bodies_by_type[] = { { sizeof(regexp), sizeof(regexp), 0, - SVt_REGEXP, FALSE, NONV, HASARENA, + SVt_REGEXP, TRUE, NONV, HASARENA, FIT_ARENA(0, sizeof(regexp)) }, @@ -1340,6 +1339,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type) case SVt_PVGV: case SVt_PVCV: case SVt_PVLV: + case SVt_INVLIST: case SVt_REGEXP: case SVt_PVMG: case SVt_PVNV: @@ -1468,6 +1468,8 @@ 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) { @@ -1475,13 +1477,6 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen) PERL_ARGS_ASSERT_SV_GROW; -#ifdef HAS_64K_LIMIT - if (newlen >= 0x10000) { - PerlIO_printf(Perl_debug_log, - "Allocation too large: %"UVxf"\n", (UV)newlen); - my_exit(1); - } -#endif /* HAS_64K_LIMIT */ if (SvROK(sv)) sv_unref(sv); if (SvTYPE(sv) < SVt_PV) { @@ -1493,14 +1488,10 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen) s = SvPVX_mutable(sv); if (newlen > SvLEN(sv)) newlen += 10 * (newlen - SvCUR(sv)); /* avoid copy each time */ -#ifdef HAS_64K_LIMIT - if (newlen >= 0x10000) - newlen = 0xFFFF; -#endif } else { - if (SvIsCOW(sv)) sv_force_normal(sv); + if (SvIsCOW(sv)) S_sv_uncow(aTHX_ sv, 0); s = SvPVX_mutable(sv); } @@ -1720,26 +1711,24 @@ Perl_sv_setnv_mg(pTHX_ SV *const sv, const NV num) SvSETMAGIC(sv); } -/* Print an "isn't numeric" warning, using a cleaned-up, - * printable version of the offending string +/* Return a cleaned-up, printable version of sv, for non-numeric, or + * not incrementable warning display. + * Originally part of S_not_a_number(). + * The return value may be != tmpbuf. */ -STATIC void -S_not_a_number(pTHX_ SV *const sv) -{ - dVAR; - SV *dsv; - char tmpbuf[64]; - const char *pv; +STATIC const char * +S_sv_display(pTHX_ SV *const sv, char *tmpbuf, STRLEN tmpbuf_size) { + const char *pv; - PERL_ARGS_ASSERT_NOT_A_NUMBER; + PERL_ARGS_ASSERT_SV_DISPLAY; if (DO_UTF8(sv)) { - dsv = newSVpvs_flags("", SVs_TEMP); + SV *dsv = newSVpvs_flags("", SVs_TEMP); pv = sv_uni_display(dsv, sv, 10, UNI_DISPLAY_ISPRINT); } else { char *d = tmpbuf; - const char * const limit = tmpbuf + sizeof(tmpbuf) - 8; + const char * const limit = tmpbuf + tmpbuf_size - 8; /* each *s can expand to 4 chars + "...\0", i.e. need room for 8 chars */ @@ -1747,10 +1736,12 @@ S_not_a_number(pTHX_ SV *const sv) const char * const end = s + SvCUR(sv); for ( ; s < end && d < limit; s++ ) { int ch = *s & 0xFF; - if (ch & 128 && !isPRINT_LC(ch)) { + if (! isASCII(ch) && !isPRINT_LC(ch)) { *d++ = 'M'; *d++ = '-'; - ch &= 127; + + /* Map to ASCII "equivalent" of Latin1 */ + ch = LATIN1_TO_NATIVE(NATIVE_TO_LATIN1(ch) & 127); } if (ch == '\n') { *d++ = '\\'; @@ -1788,6 +1779,24 @@ S_not_a_number(pTHX_ SV *const sv) pv = tmpbuf; } + return pv; +} + +/* Print an "isn't numeric" warning, using a cleaned-up, + * printable version of the offending string + */ + +STATIC void +S_not_a_number(pTHX_ SV *const sv) +{ + dVAR; + char tmpbuf[64]; + const char *pv; + + PERL_ARGS_ASSERT_NOT_A_NUMBER; + + pv = sv_display(sv, tmpbuf, sizeof(tmpbuf)); + if (PL_op) Perl_warner(aTHX_ packWARN(WARN_NUMERIC), /* diag_listed_as: Argument "%s" isn't numeric%s */ @@ -1799,6 +1808,20 @@ S_not_a_number(pTHX_ SV *const sv) "Argument \"%s\" isn't numeric", pv); } +STATIC void +S_not_incrementable(pTHX_ SV *const sv) { + dVAR; + char tmpbuf[64]; + const char *pv; + + PERL_ARGS_ASSERT_NOT_INCREMENTABLE; + + pv = sv_display(sv, tmpbuf, sizeof(tmpbuf)); + + Perl_warner(aTHX_ packWARN(WARN_NUMERIC), + "Argument \"%s\" treated as 0 in increment (++)", pv); +} + /* =for apidoc looks_like_number @@ -2240,10 +2263,8 @@ S_sv_2iuv_common(pTHX_ SV *const sv) if (isGV_with_GP(sv)) return glob_2number(MUTABLE_GV(sv)); - if (!SvPADTMP(sv)) { - if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) + if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) report_uninit(sv); - } if (SvTYPE(sv) < SVt_IV) /* Typically the caller expects that sv_any is not NULL now. */ sv_upgrade(sv, SVt_IV); @@ -2271,6 +2292,9 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags) if (!sv) return 0; + assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV + && SvTYPE(sv) != SVt_PVFM); + if (SvGMAGICAL(sv) && (flags & SV_GMAGIC)) mg_get(sv); @@ -2445,6 +2469,8 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags) dVAR; if (!sv) return 0.0; + assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV + && SvTYPE(sv) != SVt_PVFM); if (SvGMAGICAL(sv) || 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 NVs. @@ -2642,7 +2668,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags) return 0.0; } - if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED)) + if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) report_uninit(sv); assert (SvTYPE(sv) >= SVt_NV); /* Typically the caller expects that sv_any is not NULL now. */ @@ -2750,6 +2776,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) *lp = 0; return (char *)""; } + assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV + && SvTYPE(sv) != SVt_PVFM); if (SvGMAGICAL(sv) && (flags & SV_GMAGIC)) mg_get(sv); if (SvROK(sv)) { @@ -2903,6 +2931,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) Move(ptr, s, len, char); s += len; *s = '\0'; + SvPOK_on(sv); } else if (SvNOK(sv)) { if (SvTYPE(sv) < SVt_PVNV) @@ -2916,14 +2945,46 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) /* The +20 is pure guesswork. Configure test needed. --jhi */ s = SvGROW_mutable(sv, NV_DIG + 20); /* some Xenix systems wipe out errno here */ - Gconvert(SvNVX(sv), NV_DIG, 0, s); + +#ifndef USE_LOCALE_NUMERIC + Gconvert(SvNVX(sv), NV_DIG, 0, s); + SvPOK_on(sv); +#else + /* Gconvert always uses the current locale. That's the right thing + * to do if we're supposed to be using locales. But otherwise, we + * want the result to be based on the C locale, so we need to + * change to the C locale during the Gconvert and then change back. + * But if we're already in the C locale (PL_numeric_standard is + * TRUE in that case), no need to do any changing */ + if (PL_numeric_standard || IN_SOME_LOCALE_FORM_RUNTIME) { + Gconvert(SvNVX(sv), NV_DIG, 0, s); + + /* If the radix character is UTF-8, and actually is in the + * output, turn on the UTF-8 flag for the scalar */ + if (! PL_numeric_standard + && PL_numeric_radix_sv && SvUTF8(PL_numeric_radix_sv) + && instr(s, SvPVX_const(PL_numeric_radix_sv))) + { + SvUTF8_on(sv); + } + } + else { + char *loc = savepv(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + Gconvert(SvNVX(sv), NV_DIG, 0, s); + setlocale(LC_NUMERIC, loc); + Safefree(loc); + + } + + /* We don't call SvPOK_on(), because it may come to pass that the + * locale changes so that the stringification we just did is no + * longer correct. We will have to re-stringify every time it is + * needed */ +#endif RESTORE_ERRNO; while (*s) s++; } -#ifdef hcx - if (s[-1] == '.') - *--s = '\0'; -#endif } else if (isGV_with_GP(sv)) { GV *const gv = MUTABLE_GV(sv); @@ -2947,7 +3008,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) *lp = 0; if (flags & SV_UNDEF_RETURNS_NULL) return NULL; - if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED)) + if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) report_uninit(sv); /* Typically the caller expects that sv_any is not NULL now. */ if (!SvREADONLY(sv) && SvTYPE(sv) < SVt_PV) @@ -2961,7 +3022,6 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) *lp = len; SvCUR_set(sv, len); } - SvPOK_on(sv); DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n", PTR2UV(sv),SvPVX_const(sv))); if (flags & SV_CONST_RETURN) @@ -3037,13 +3097,13 @@ Perl_sv_2pvbyte(pTHX_ SV *sv, STRLEN *const lp) { PERL_ARGS_ASSERT_SV_2PVBYTE; + SvGETMAGIC(sv); if (((SvREADONLY(sv) || SvFAKE(sv)) && !SvIsCOW(sv)) || isGV_with_GP(sv) || SvROK(sv)) { SV *sv2 = sv_newmortal(); - sv_copypv(sv2,sv); + sv_copypv_nomg(sv2,sv); sv = sv2; } - else SvGETMAGIC(sv); sv_utf8_downgrade(sv,0); return lp ? SvPV_nomg(sv,*lp) : SvPV_nomg_nolen(sv); } @@ -3092,12 +3152,13 @@ contain SV_GMAGIC, then it does an mg_get() first. */ bool -Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags) +Perl_sv_2bool_flags(pTHX_ SV *sv, I32 flags) { dVAR; PERL_ARGS_ASSERT_SV_2BOOL_FLAGS; + restart: if(flags & SV_GMAGIC) SvGETMAGIC(sv); if (!SvOK(sv)) @@ -3105,11 +3166,36 @@ Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags) if (SvROK(sv)) { if (SvAMAGIC(sv)) { SV * const tmpsv = AMG_CALLunary(sv, bool__amg); - if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv)))) - return cBOOL(SvTRUE(tmpsv)); + if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv)))) { + bool svb; + sv = tmpsv; + if(SvGMAGICAL(sv)) { + flags = SV_GMAGIC; + goto restart; /* call sv_2bool */ + } + /* expanded SvTRUE_common(sv, (flags = 0, goto restart)) */ + else if(!SvOK(sv)) { + svb = 0; + } + else if(SvPOK(sv)) { + svb = SvPVXtrue(sv); + } + else if((SvFLAGS(sv) & (SVf_IOK|SVf_NOK))) { + svb = (SvIOK(sv) && SvIVX(sv) != 0) + || (SvNOK(sv) && SvNVX(sv) != 0.0); + } + else { + flags = 0; + goto restart; /* call sv_2bool_nomg */ + } + return cBOOL(svb); + } } return SvRV(sv) != 0; } + if (isREGEXP(sv)) + return + RX_WRAPLEN(sv) > 1 || (RX_WRAPLEN(sv) && *RX_WRAPPED(sv) != '0'); return SvTRUE_common(sv, isGV_with_GP(sv) ? 1 : 0); } @@ -3206,7 +3292,7 @@ Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV *const sv, const I32 flags, STRLEN extr } if (SvIsCOW(sv)) { - sv_force_normal_flags(sv, 0); + S_sv_uncow(aTHX_ sv, 0); } if (PL_encoding && !(flags & SV_UTF8_NO_ENCODING)) { @@ -3236,7 +3322,7 @@ Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV *const sv, const I32 flags, STRLEN extr while (t < e) { const U8 ch = *t++; - if (NATIVE_IS_INVARIANT(ch)) continue; + if (NATIVE_BYTE_IS_INVARIANT(ch)) continue; t--; /* t already incremented; re-point to first variant */ two_byte_count = 1; @@ -3344,13 +3430,8 @@ must_be_utf8: } while (t < e) { - const UV uv = NATIVE8_TO_UNI(*t++); - if (UNI_IS_INVARIANT(uv)) - *d++ = (U8)UNI_TO_NATIVE(uv); - else { - *d++ = (U8)UTF8_EIGHT_BIT_HI(uv); - *d++ = (U8)UTF8_EIGHT_BIT_LO(uv); - } + append_utf8_from_native_byte(*t, &d); + t++; } *d = '\0'; SvPV_free(sv); /* No longer using pre-existing string */ @@ -3376,7 +3457,7 @@ must_be_utf8: while (d < e) { const U8 chr = *d++; - if (! NATIVE_IS_INVARIANT(chr)) two_byte_count++; + if (! NATIVE_BYTE_IS_INVARIANT(chr)) two_byte_count++; } /* The string will expand by just the number of bytes that @@ -3396,34 +3477,26 @@ must_be_utf8: e--; while (e >= t) { - const U8 ch = NATIVE8_TO_UNI(*e--); - if (UNI_IS_INVARIANT(ch)) { - *d-- = UNI_TO_NATIVE(ch); + if (NATIVE_BYTE_IS_INVARIANT(*e)) { + *d-- = *e; } else { - *d-- = (U8)UTF8_EIGHT_BIT_LO(ch); - *d-- = (U8)UTF8_EIGHT_BIT_HI(ch); + *d-- = UTF8_EIGHT_BIT_LO(*e); + *d-- = UTF8_EIGHT_BIT_HI(*e); } + e--; } } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { /* Update pos. We do it at the end rather than during * the upgrade, to avoid slowing down the common case - * (upgrade without pos) */ + * (upgrade without pos). + * pos can be stored as either bytes or characters. Since + * this was previously a byte string we can just turn off + * the bytes flag. */ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global); if (mg) { - I32 pos = mg->mg_len; - if (pos > 0 && (U32)pos > invariant_head) { - U8 *d = (U8*) SvPVX(sv) + invariant_head; - STRLEN n = (U32)pos - invariant_head; - while (n > 0) { - if (UTF8_IS_START(*d)) - d++; - d++; - n--; - } - mg->mg_len = d - (U8*)SvPVX(sv); - } + mg->mg_flags &= ~MGf_BYTES; } if ((mg = mg_find(sv, PERL_MAGIC_utf8))) magic_setutf8(sv,mg); /* clear UTF8 cache */ @@ -3465,18 +3538,15 @@ Perl_sv_utf8_downgrade(pTHX_ SV *const sv, const bool fail_ok) int mg_flags = SV_GMAGIC; if (SvIsCOW(sv)) { - sv_force_normal_flags(sv, 0); + S_sv_uncow(aTHX_ sv, 0); } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { /* update pos */ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global); - if (mg) { - I32 pos = mg->mg_len; - if (pos > 0) { - sv_pos_b2u(sv, &pos); + if (mg && mg->mg_len > 0 && mg->mg_flags & MGf_BYTES) { + mg->mg_len = sv_pos_b2u_flags(sv, mg->mg_len, + SV_GMAGIC|SV_CONST_RETURN); mg_flags = 0; /* sv_pos_b2u does get magic */ - mg->mg_len = pos; - } } if ((mg = mg_find(sv, PERL_MAGIC_utf8))) magic_setutf8(sv,mg); /* clear UTF8 cache */ @@ -3565,6 +3635,9 @@ Perl_sv_utf8_decode(pTHX_ SV *const sv) } } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { + /* XXX Is this dead code? XS_utf8_decode calls SvSETMAGIC + after this, clearing pos. Does anything on CPAN + need this? */ /* adjust pos to the start of a UTF8 char sequence */ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global); if (mg) { @@ -4091,7 +4164,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) } break; - /* case SVt_DUMMY: */ + case SVt_INVLIST: case SVt_PVLV: case SVt_PVGV: case SVt_PVMG: @@ -4293,7 +4366,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) ? (!((sflags & CAN_COW_MASK) == CAN_COW_FLAGS # ifdef PERL_OLD_COPY_ON_WRITE && (SvFLAGS(dstr) & CAN_COW_MASK) == CAN_COW_FLAGS - && SvTYPE(sstr) >= SVt_PVIV + && SvTYPE(sstr) >= SVt_PVIV && len # else && !(SvFLAGS(dstr) & SVf_BREAK) && !(sflags & SVf_IsCOW) @@ -4671,7 +4744,7 @@ Perl_sv_sethek(pTHX_ SV *const sv, const HEK *const hek) { SV_CHECK_THINKFIRST_COW_DROP(sv); SvUPGRADE(sv, SVt_PV); - Safefree(SvPVX(sv)); + SvPV_free(sv); SvPV_set(sv,(char *)HEK_KEY(share_hek_hek(hek))); SvCUR_set(sv, HEK_LEN(hek)); SvLEN_set(sv, 0); @@ -4826,19 +4899,14 @@ with flags set to 0. =cut */ -void -Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags) +static void +S_sv_uncow(pTHX_ SV * const sv, const U32 flags) { dVAR; - PERL_ARGS_ASSERT_SV_FORCE_NORMAL_FLAGS; - + assert(SvIsCOW(sv)); + { #ifdef PERL_ANY_COW - if (SvREADONLY(sv)) { - if (IN_PERL_RUNTIME) - Perl_croak_no_modify(); - } - else if (SvIsCOW(sv)) { const char * const pvx = SvPVX_const(sv); const STRLEN len = SvLEN(sv); const STRLEN cur = SvCUR(sv); @@ -4891,14 +4959,7 @@ Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags) sv_dump(sv); } } - } #else - if (SvREADONLY(sv)) { - if (IN_PERL_RUNTIME) - Perl_croak_no_modify(); - } - else - if (SvIsCOW(sv)) { const char * const pvx = SvPVX_const(sv); const STRLEN len = SvCUR(sv); SvIsCOW_off(sv); @@ -4913,8 +4974,19 @@ Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags) *SvEND(sv) = '\0'; } unshare_hek(SvSHARED_HEK_FROM_PV(pvx)); - } #endif + } +} + +void +Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags) +{ + PERL_ARGS_ASSERT_SV_FORCE_NORMAL_FLAGS; + + if (SvREADONLY(sv)) + Perl_croak_no_modify(); + else if (SvIsCOW(sv)) + S_sv_uncow(aTHX_ sv, flags); if (SvROK(sv)) sv_unref_flags(sv, flags); else if (SvFAKE(sv) && isGV_with_GP(sv)) @@ -5049,8 +5121,14 @@ Perl_sv_chop(pTHX_ SV *const sv, const char *const ptr) evacp = p - evacn; #endif + /* This sets 'delta' to the accumulated value of all deltas so far */ delta += old_delta; assert(delta); + + /* If 'delta' fits in a byte, store it just prior to the new beginning of + * the string; otherwise store a 0 byte there and store 'delta' just prior + * to that, using as many bytes as a STRLEN occupies. Thus it overwrites a + * portion of the chopped part of the string */ if (delta < 0x100) { *--p = (U8) delta; } else { @@ -5125,13 +5203,8 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c d = (U8 *)SvPVX(dsv) + dlen; while (sstr < send) { - const UV uv = NATIVE_TO_ASCII((U8)*sstr++); - if (UNI_IS_INVARIANT(uv)) - *d++ = (U8)UTF_TO_NATIVE(uv); - else { - *d++ = (U8)UTF8_EIGHT_BIT_HI(uv); - *d++ = (U8)UTF8_EIGHT_BIT_LO(uv); - } + append_utf8_from_native_byte(*sstr, &d); + sstr++; } SvCUR_set(dsv, d-(const U8 *)SvPVX(dsv)); } @@ -5307,6 +5380,8 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, PERL_ARGS_ASSERT_SV_MAGICEXT; + if (SvTYPE(sv)==SVt_PVAV) { assert (!AvPAD_NAMELIST(sv)); } + SvUPGRADE(sv, SVt_PVMG); Newxz(mg, 1, MAGIC); mg->mg_moremagic = SvMAGIC(sv); @@ -5370,6 +5445,24 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, return mg; } +MAGIC * +Perl_sv_magicext_mglob(pTHX_ SV *sv) +{ + PERL_ARGS_ASSERT_SV_MAGICEXT_MGLOB; + if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') { + /* This sv is only a delegate. //g magic must be attached to + its target. */ + vivify_defelem(sv); + sv = LvTARG(sv); + } +#ifdef PERL_OLD_COPY_ON_WRITE + if (SvIsCOW(sv)) + sv_force_normal_flags(sv, 0); +#endif + return sv_magicext(sv, NULL, PERL_MAGIC_regex_global, + &PL_vtbl_mglob, 0, 0); +} + /* =for apidoc sv_magic @@ -5412,17 +5505,13 @@ Perl_sv_magic(pTHX_ SV *const sv, SV *const obj, const int how, vtable = (vtable_index == magic_vtable_max) ? NULL : PL_magic_vtables + vtable_index; -#ifdef PERL_ANY_COW +#ifdef PERL_OLD_COPY_ON_WRITE if (SvIsCOW(sv)) sv_force_normal_flags(sv, 0); #endif if (SvREADONLY(sv)) { if ( - /* its okay to attach magic to shared strings */ - !SvIsCOW(sv) - - && IN_PERL_RUNTIME - && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how) + !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how) ) { Perl_croak_no_modify(); @@ -5439,6 +5528,16 @@ Perl_sv_magic(pTHX_ SV *const sv, SV *const obj, const int how, } } + /* Force pos to be stored as characters, not bytes. */ + if (SvMAGICAL(sv) && DO_UTF8(sv) + && (mg = mg_find(sv, PERL_MAGIC_regex_global)) + && mg->mg_len != -1 + && mg->mg_flags & MGf_BYTES) { + mg->mg_len = (SSize_t)sv_pos_b2u_flags(sv, (STRLEN)mg->mg_len, + SV_CONST_RETURN); + mg->mg_flags &= ~MGf_BYTES; + } + /* Rest of work is done else where */ mg = sv_magicext(sv,obj,how,vtable,name,namlen); @@ -5603,12 +5702,10 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv) if (SvTYPE(tsv) == SVt_PVHV) { svp = (SV**)Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(tsv)); } else { - if (! ((mg = - (SvMAGICAL(tsv) ? mg_find(tsv, PERL_MAGIC_backref) : NULL)))) - { - sv_magic(tsv, NULL, PERL_MAGIC_backref, NULL, 0); - mg = mg_find(tsv, PERL_MAGIC_backref); - } + if (SvMAGICAL(tsv)) + mg = mg_find(tsv, PERL_MAGIC_backref); + if (!mg) + mg = sv_magicext(tsv, NULL, PERL_MAGIC_backref, &PL_vtbl_backref, NULL, 0); svp = &(mg->mg_obj); } @@ -5618,32 +5715,32 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv) || (*svp && SvTYPE(*svp) != SVt_PVAV) ) { /* create array */ + if (mg) + mg->mg_flags |= MGf_REFCOUNTED; av = newAV(); AvREAL_off(av); - SvREFCNT_inc_simple_void(av); + SvREFCNT_inc_simple_void_NN(av); /* av now has a refcnt of 2; see discussion above */ + av_extend(av, *svp ? 2 : 1); if (*svp) { /* move single existing backref to the array */ - av_extend(av, 1); AvARRAY(av)[++AvFILLp(av)] = *svp; /* av_push() */ } *svp = (SV*)av; - if (mg) - mg->mg_flags |= MGf_REFCOUNTED; } - else + else { av = MUTABLE_AV(*svp); - - if (!av) { - /* optimisation: store single backref directly in HvAUX or mg_obj */ - *svp = sv; - return; + if (!av) { + /* optimisation: store single backref directly in HvAUX or mg_obj */ + *svp = sv; + return; + } + assert(SvTYPE(av) == SVt_PVAV); + if (AvFILLp(av) >= AvMAX(av)) { + av_extend(av, AvFILLp(av)+1); + } } /* push new backref */ - assert(SvTYPE(av) == SVt_PVAV); - if (AvFILLp(av) >= AvMAX(av)) { - av_extend(av, AvFILLp(av)+1); - } AvARRAY(av)[++AvFILLp(av)] = sv; /* av_push() */ } @@ -6144,6 +6241,9 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) } else if (type == SVt_PVMG && SvPAD_OUR(sv)) { SvREFCNT_dec(SvOURSTASH(sv)); + } + else if (type == SVt_PVAV && AvPAD_NAMELIST(sv)) { + assert(!SvMAGICAL(sv)); } else if (SvMAGIC(sv)) { /* Free back-references before other types of magic. */ sv_unmagic(sv, PERL_MAGIC_backref); @@ -6154,7 +6254,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) SvREFCNT_dec(SvSTASH(sv)); } switch (type) { - /* case SVt_DUMMY: */ + /* case SVt_INVLIST: */ case SVt_PVIO: if (IoIFP(sv) && IoIFP(sv) != PerlIO_stdin() && @@ -6201,8 +6301,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) if (PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ "sv_clear clearing PL_stashcache for '%"SVf"'\n", sv)); - (void)hv_delete(PL_stashcache, name, - HvNAMEUTF8((HV*)sv) ? -HvNAMELEN_get((HV*)sv) : HvNAMELEN_get((HV*)sv), G_DISCARD); + (void)hv_deletehek(PL_stashcache, + HvNAME_HEK((HV*)sv), G_DISCARD); } hv_name_set((HV*)sv, NULL, 0, 0); } @@ -6280,6 +6380,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) case SVt_PVMG: case SVt_PVNV: case SVt_PVIV: + case SVt_INVLIST: case SVt_PV: freescalar: /* Don't bother with SvOOK_off(sv); as we're only going to @@ -6460,14 +6561,21 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) { assert(SvTYPE(stash) == SVt_PVHV); if (HvNAME(stash)) { CV* destructor = NULL; + assert (SvOOK(stash)); if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash); - if (!destructor) { + if (!destructor || HvMROMETA(stash)->destroy_gen + != PL_sub_generation) + { GV * const gv = gv_fetchmeth_autoload(stash, "DESTROY", 7, 0); if (gv) destructor = GvCV(gv); if (!SvOBJECT(stash)) + { SvSTASH(stash) = destructor ? (HV *)destructor : ((HV *)0)+1; + HvAUX(stash)->xhv_mro_meta->destroy_gen = + PL_sub_generation; + } } assert(!destructor || destructor == ((CV *)0)+1 || SvTYPE(destructor) == SVt_PVCV); @@ -6581,7 +6689,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc) PERL_ARGS_ASSERT_SV_FREE2; - if (rc == 1) { + if (LIKELY( rc == 1 )) { /* normal case */ SvREFCNT(sv) = 0; @@ -6916,7 +7024,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start /* =for apidoc sv_pos_u2b_flags -Converts the value pointed to by offsetp from a count of UTF-8 chars from +Converts the offset from a count of UTF-8 chars from the start of the string, to a count of the equivalent number of bytes; if lenp is non-zero, it does the same to lenp, but this time starting from the offset, rather than from the start @@ -7025,9 +7133,6 @@ S_utf8_mg_len_cache_update(pTHX_ SV *const sv, MAGIC **const mgp, assert(*mgp); (*mgp)->mg_len = ulen; - /* For now, treat "overflowed" as "still unknown". See RT #72924. */ - if (ulen != (STRLEN) (*mgp)->mg_len) - (*mgp)->mg_len = -1; } /* Create and update the UTF8 magic offset cache, with the proffered utf8/ @@ -7205,44 +7310,41 @@ S_sv_pos_b2u_midway(pTHX_ const U8 *const s, const U8 *const target, } /* -=for apidoc sv_pos_b2u +=for apidoc sv_pos_b2u_flags -Converts the value pointed to by offsetp from a count of bytes from the -start of the string, to a count of the equivalent number of UTF-8 chars. -Handles magic and type coercion. +Converts the offset from a count of bytes from the start of the string, to +a count of the equivalent number of UTF-8 chars. Handles type coercion. +I is passed to C, and usually should be +C to handle magic. =cut */ /* - * sv_pos_b2u() uses, like sv_pos_u2b(), the mg_ptr of the potential - * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and - * byte offsets. + * sv_pos_b2u_flags() uses, like sv_pos_u2b_flags(), the mg_ptr of the + * potential PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 + * and byte offsets. * */ -void -Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) +STRLEN +Perl_sv_pos_b2u_flags(pTHX_ SV *const sv, STRLEN const offset, U32 flags) { const U8* s; - const STRLEN byte = *offsetp; STRLEN len = 0; /* Actually always set, but let's keep gcc happy. */ STRLEN blen; MAGIC* mg = NULL; const U8* send; bool found = FALSE; - PERL_ARGS_ASSERT_SV_POS_B2U; - - if (!sv) - return; + PERL_ARGS_ASSERT_SV_POS_B2U_FLAGS; - s = (const U8*)SvPV_const(sv, blen); + s = (const U8*)SvPV_flags(sv, blen, flags); - if (blen < byte) + if (blen < offset) Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%"UVuf - ", byte=%"UVuf, (UV)blen, (UV)byte); + ", byte=%"UVuf, (UV)blen, (UV)offset); - send = s + byte; + send = s + offset; if (!SvREADONLY(sv) && PL_utf8cache @@ -7251,18 +7353,16 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) { if (mg->mg_ptr) { STRLEN * const cache = (STRLEN *) mg->mg_ptr; - if (cache[1] == byte) { + if (cache[1] == offset) { /* An exact match. */ - *offsetp = cache[0]; - return; + return cache[0]; } - if (cache[3] == byte) { + if (cache[3] == offset) { /* An exact match. */ - *offsetp = cache[2]; - return; + return cache[2]; } - if (cache[1] < byte) { + if (cache[1] < offset) { /* We already know part of the way. */ if (mg->mg_len != -1) { /* Actually, we know the end too. */ @@ -7273,7 +7373,7 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) len = cache[0] + utf8_length(s + cache[1], send); } } - else if (cache[3] < byte) { + else if (cache[3] < offset) { /* We're between the two cached pairs, so we do the calculation offset by the byte/utf-8 positions for the earlier pair, then add the utf-8 characters from the string start to @@ -7283,7 +7383,7 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) + cache[2]; } - else { /* cache[3] > byte */ + else { /* cache[3] > offset */ len = S_sv_pos_b2u_midway(aTHX_ s, send, s + cache[3], cache[2]); @@ -7302,14 +7402,46 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) assert_uft8_cache_coherent("sv_pos_b2u", len, real_len, sv); len = real_len; } - *offsetp = len; if (PL_utf8cache) { - if (blen == byte) + if (blen == offset) utf8_mg_len_cache_update(sv, &mg, len); else - utf8_mg_pos_cache_update(sv, &mg, byte, len, blen); + utf8_mg_pos_cache_update(sv, &mg, offset, len, blen); } + + return len; +} + +/* +=for apidoc sv_pos_b2u + +Converts the value pointed to by offsetp from a count of bytes from the +start of the string, to a count of the equivalent number of UTF-8 chars. +Handles magic and type coercion. + +Use C in preference, which correctly handles strings +longer than 2Gb. + +=cut +*/ + +/* + * sv_pos_b2u() uses, like sv_pos_u2b(), the mg_ptr of the potential + * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and + * byte offsets. + * + */ +void +Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp) +{ + PERL_ARGS_ASSERT_SV_POS_B2U; + + if (!sv) + return; + + *offsetp = (I32)sv_pos_b2u_flags(sv, (STRLEN)*offsetp, + SV_GMAGIC|SV_CONST_RETURN); } static void @@ -7816,9 +7948,9 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) STRLEN rslen; STDCHAR rslast; STDCHAR *bp; - I32 cnt; - I32 i = 0; - I32 rspara = 0; + SSize_t cnt; + int i = 0; + int rspara = 0; PERL_ARGS_ASSERT_SV_GETS; @@ -7963,8 +8095,9 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) DEBUG_P(PerlIO_printf(Perl_debug_log, "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=%ld, base=%"UVuf"\n", - PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp), + "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%zd, base=%" + UVuf"\n", + PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0))); for (;;) { screamer: @@ -7998,13 +8131,13 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append) cannot_be_shortbuffered: DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: going to getc, ptr=%"UVuf", cnt=%ld\n", - PTR2UV(ptr),(long)cnt)); + "Screamer: going to getc, ptr=%"UVuf", cnt=%zd\n", + PTR2UV(ptr),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=%ld, base=%"UVuf"\n", - PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp), + "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n", + PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); /* This used to call 'filbuf' in stdio form, but as that behaves like @@ -8013,14 +8146,15 @@ 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=%ld, base=%"UVuf"\n", - PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp), + "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n", + PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); 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=%ld\n",PTR2UV(ptr),(long)cnt)); + "Screamer: after getc, ptr=%"UVuf", cnt=%zd\n", + PTR2UV(ptr),cnt)); if (i == EOF) /* all done for ever? */ goto thats_really_all_folks; @@ -8044,11 +8178,12 @@ thats_really_all_folks: if (shortbuffered) cnt += shortbuffered; DEBUG_P(PerlIO_printf(Perl_debug_log, - "Screamer: quitting, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt)); + "Screamer: quitting, ptr=%"UVuf", cnt=%zd\n",PTR2UV(ptr),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=%ld, base=%"UVuf"\n", - PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp), + "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf + "\n", + PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp), PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); *bp = '\0'; SvCUR_set(sv, bp - (STDCHAR*)SvPVX_const(sv)); /* set length */ @@ -8169,10 +8304,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) if (!sv) return; if (SvTHINKFIRST(sv)) { - if (SvIsCOW(sv) || isGV_with_GP(sv)) - sv_force_normal_flags(sv, 0); if (SvREADONLY(sv)) { - if (IN_PERL_RUNTIME) Perl_croak_no_modify(); } if (SvROK(sv)) { @@ -8183,6 +8315,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) sv_unref(sv); sv_setiv(sv, i); } + else sv_force_normal_flags(sv, 0); } flags = SvFLAGS(sv); if ((flags & (SVp_NOK|SVp_IOK)) == SVp_NOK) { @@ -8237,11 +8370,11 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) while (isALPHA(*d)) d++; while (isDIGIT(*d)) d++; if (d < SvEND(sv)) { + const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), NULL); #ifdef PERL_PRESERVE_IVUV /* Got to punt this as an integer if needs be, but we don't issue warnings. Probably ought to make the sv_iv_please() that does the conversion if possible, and silently. */ - const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), NULL); if (numtype && !(numtype & IS_NUMBER_INFINITY)) { /* Need to try really hard to see if it's an integer. 9.22337203685478e+18 is an integer. @@ -8272,6 +8405,8 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) #endif } #endif /* PERL_PRESERVE_IVUV */ + if (!numtype && ckWARN(WARN_NUMERIC)) + not_incrementable(sv); sv_setnv(sv,Atof(SvPVX_const(sv)) + 1.0); return; } @@ -8351,10 +8486,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv) if (!sv) return; if (SvTHINKFIRST(sv)) { - if (SvIsCOW(sv) || isGV_with_GP(sv)) - sv_force_normal_flags(sv, 0); if (SvREADONLY(sv)) { - if (IN_PERL_RUNTIME) Perl_croak_no_modify(); } if (SvROK(sv)) { @@ -8365,6 +8497,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv) sv_unref(sv); sv_setiv(sv, i); } + else sv_force_normal_flags(sv, 0); } /* Unlike sv_inc we don't have to worry about string-never-numbers and keeping them magic. But we mustn't warn on punting */ @@ -8552,13 +8685,13 @@ Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags new_SV(sv); sv_setpvn(sv,s,len); - /* This code used to a sv_2mortal(), however we now unroll the call to sv_2mortal() - * and do what it does ourselves here. - * Since we have asserted that flags can only have the SVf_UTF8 and/or SVs_TEMP flags - * set above we can use it to enable the sv flags directly (bypassing SvTEMP_on), which - * in turn means we dont need to mask out the SVf_UTF8 flag below, which means that we - * eliminate quite a few steps than it looks - Yves (explaining patch by gfx) - */ + /* This code used to do a sv_2mortal(), however we now unroll the call to + * sv_2mortal() and do what it does ourselves here. Since we have asserted + * that flags can only have the SVf_UTF8 and/or SVs_TEMP flags set above we + * can use it to enable the sv flags directly (bypassing SvTEMP_on), which + * in turn means we dont need to mask out the SVf_UTF8 flag below, which + * means that we eliminate quite a few steps than it looks - Yves + * (explaining patch by gfx) */ SvFLAGS(sv) |= flags; @@ -9052,35 +9185,15 @@ Perl_sv_resetpvn(pTHX_ const char *s, STRLEN len, HV * const stash) continue; gv = MUTABLE_GV(HeVAL(entry)); sv = GvSV(gv); - if (sv) { - if (SvTHINKFIRST(sv)) { - if (!SvREADONLY(sv) && SvROK(sv)) - sv_unref(sv); - /* XXX Is this continue a bug? Why should THINKFIRST - exempt us from resetting arrays and hashes? */ - continue; - } - SvOK_off(sv); - if (SvTYPE(sv) >= SVt_PV) { - SvCUR_set(sv, 0); - if (SvPVX_const(sv) != NULL) - *SvPVX(sv) = '\0'; - SvTAINT(sv); - } + if (sv && !SvREADONLY(sv)) { + SV_CHECK_THINKFIRST_COW_DROP(sv); + if (!isGV(sv)) SvOK_off(sv); } if (GvAV(gv)) { av_clear(GvAV(gv)); } if (GvHV(gv) && !HvNAME_get(GvHV(gv))) { -#if defined(VMS) - Perl_die(aTHX_ "Can't reset %%ENV on this system"); -#else /* ! VMS */ hv_clear(GvHV(gv)); -# if defined(USE_ENVIRON_ARRAY) - if (gv == PL_envgv) - my_clearenv(); -# endif /* USE_ENVIRON_ARRAY */ -#endif /* VMS */ } } } @@ -9290,7 +9403,7 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS; if (flags & SV_GMAGIC) SvGETMAGIC(sv); - if (SvTHINKFIRST(sv) && !SvROK(sv)) + if (SvTHINKFIRST(sv) && (!SvROK(sv) || SvREADONLY(sv))) sv_force_normal_flags(sv, 0); if (SvPOK(sv)) { @@ -9301,14 +9414,6 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) char *s; STRLEN len; - if (SvREADONLY(sv) && !(flags & SV_MUTABLE_RETURN)) { - const char * const ref = sv_reftype(sv,0); - if (PL_op) - Perl_croak(aTHX_ "Can't coerce readonly %s to string in %s", - ref, OP_DESC(PL_op)); - else - Perl_croak(aTHX_ "Can't coerce readonly %s to string", ref); - } if (SvTYPE(sv) > SVt_PVLV || isGV_with_GP(sv)) /* diag_listed_as: Can't coerce %s to %s in %s */ @@ -9424,7 +9529,7 @@ Perl_sv_reftype(pTHX_ const SV *const sv, const int ob) ? "GLOB" : "SCALAR"); case SVt_PVFM: return "FORMAT"; case SVt_PVIO: return "IO"; - case SVt_DUMMY: return "DUMMY"; + case SVt_INVLIST: return "INVLIST"; case SVt_REGEXP: return "REGEXP"; default: return "UNKNOWN"; } @@ -9563,6 +9668,19 @@ Perl_newSVrv(pTHX_ SV *const rv, const char *const classname) return sv; } +SV * +Perl_newSVavdefelem(pTHX_ AV *av, SSize_t ix, bool extendible) +{ + SV * const lv = newSV_type(SVt_PVLV); + PERL_ARGS_ASSERT_NEWSVAVDEFELEM; + LvTYPE(lv) = 'y'; + sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0); + LvTARG(lv) = SvREFCNT_inc_simple_NN(av); + LvSTARGOFF(lv) = ix; + LvTARGLEN(lv) = extendible ? 1 : (STRLEN)UV_MAX; + return lv; +} + /* =for apidoc sv_setref_pv @@ -9700,22 +9818,25 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash) { dVAR; SV *tmpRef; + HV *oldstash = NULL; PERL_ARGS_ASSERT_SV_BLESS; + SvGETMAGIC(sv); if (!SvROK(sv)) Perl_croak(aTHX_ "Can't bless non-reference value"); tmpRef = SvRV(sv); if (SvFLAGS(tmpRef) & (SVs_OBJECT|SVf_READONLY)) { - if (SvREADONLY(tmpRef) && !SvIsCOW(tmpRef)) + if (SvREADONLY(tmpRef)) Perl_croak_no_modify(); if (SvOBJECT(tmpRef)) { - SvREFCNT_dec(SvSTASH(tmpRef)); + oldstash = SvSTASH(tmpRef); } } SvOBJECT_on(tmpRef); SvUPGRADE(tmpRef, SVt_PVMG); SvSTASH_set(tmpRef, MUTABLE_HV(SvREFCNT_inc_simple(stash))); + SvREFCNT_dec(oldstash); if(SvSMAGICAL(tmpRef)) if(mg_find(tmpRef, PERL_MAGIC_ext) || mg_find(tmpRef, PERL_MAGIC_uvar)) @@ -10283,6 +10404,9 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p char ebuf[IV_DIG * 4 + NV_DIG + 32]; /* large enough for "%#.#f" --chip */ /* what about long double NVs? --jhi */ +#ifdef USE_LOCALE_NUMERIC + SV* oldlocale = NULL; +#endif PERL_ARGS_ASSERT_SV_VCATPVFN_FLAGS; PERL_UNUSED_ARG(maybe_tainted); @@ -10451,7 +10575,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p %-p include an SV with precision %2p include a HEK %3p include a HEK with precision of 256 - %p (where num != 2 or 3) reserved for future + %4p char* preceded by utf8 flag and length + %p (where num is 1 or > 4) reserved for future extensions Robin Barker 2005-07-14 (but modified since) @@ -10463,6 +10588,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p STRLEN n = 0; if (*q == '-') sv = *q++; + else if (strnEQ(q, UTF8f, sizeof(UTF8f)-1)) { /* UTF8f */ + /* The argument has already gone through cBOOL, so the cast + is safe. */ + is_utf8 = (bool)va_arg(*args, int); + elen = va_arg(*args, UV); + eptr = va_arg(*args, char *); + q += sizeof(UTF8f)-1; + goto string; + } n = expect_number(&q); if (*q++ == 'p') { if (sv) { /* SVf */ @@ -10678,10 +10812,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p q++; break; #endif -#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE) +#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE) case 'L': /* Ld */ /*FALLTHROUGH*/ -#ifdef HAS_QUAD +#if IVSIZE >= 8 case 'q': /* qd */ #endif intsize = 'q'; @@ -10690,7 +10824,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p #endif case 'l': ++q; -#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE) +#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE) if (*q == 'l') { /* lld, llf */ intsize = 'q'; ++q; @@ -10749,7 +10883,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p goto unknown; uv = (args) ? va_arg(*args, int) : SvIV(argsv); if ((uv > 255 || - (!UNI_IS_INVARIANT(uv) && SvUTF8(sv))) + (!UVCHR_IS_INVARIANT(uv) && SvUTF8(sv))) && !IN_BYTES) { eptr = (char*)utf8buf; elen = uvchr_to_utf8((U8*)eptr, uv) - utf8buf; @@ -10850,7 +10984,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p case 'j': iv = va_arg(*args, intmax_t); break; #endif case 'q': -#ifdef HAS_QUAD +#if IVSIZE >= 8 iv = va_arg(*args, Quad_t); break; #else goto unknown; @@ -10866,7 +11000,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p case 'V': default: iv = tiv; break; case 'q': -#ifdef HAS_QUAD +#if IVSIZE >= 8 iv = (Quad_t)tiv; break; #else goto unknown; @@ -10948,7 +11082,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p #endif default: uv = va_arg(*args, unsigned); break; case 'q': -#ifdef HAS_QUAD +#if IVSIZE >= 8 uv = va_arg(*args, Uquad_t); break; #else goto unknown; @@ -10964,7 +11098,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p case 'V': default: uv = tuv; break; case 'q': -#ifdef HAS_QUAD +#if IVSIZE >= 8 uv = (Uquad_t)tuv; break; #else goto unknown; @@ -11233,6 +11367,21 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p /* No taint. Otherwise we are in the strange situation * where printf() taints but print($float) doesn't. * --jhi */ + +#ifdef USE_LOCALE_NUMERIC + if (! PL_numeric_standard && ! IN_SOME_LOCALE_FORM) { + + /* We use a mortal SV, so that any failures (such as if + * warnings are made fatal) won't leak */ + char *oldlocale_string = setlocale(LC_NUMERIC, NULL); + oldlocale = newSVpvn_flags(oldlocale_string, + strlen(oldlocale_string), + SVs_TEMP); + PL_numeric_standard = TRUE; + setlocale(LC_NUMERIC, "C"); + } +#endif + #if defined(HAS_LONG_DOUBLE) elen = ((intsize == 'q') ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv) @@ -11243,6 +11392,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } float_converted: eptr = PL_efloatbuf; + +#ifdef USE_LOCALE_NUMERIC + if (PL_numeric_radix_sv && SvUTF8(PL_numeric_radix_sv) + && instr(eptr, SvPVX_const(PL_numeric_radix_sv))) + { + is_utf8 = TRUE; + } +#endif + break; /* SPECIAL */ @@ -11264,7 +11422,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p case 'j': *(va_arg(*args, intmax_t*)) = i; break; #endif case 'q': -#ifdef HAS_QUAD +#if IVSIZE >= 8 *(va_arg(*args, Quad_t*)) = i; break; #else goto unknown; @@ -11343,13 +11501,13 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p have = esignlen + zeros + elen; if (have < zeros) - Perl_croak_memory_wrap(); + croak_memory_wrap(); need = (have > width ? have : width); gap = need - have; if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1)) - Perl_croak_memory_wrap(); + croak_memory_wrap(); SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1); p = SvEND(sv); if (esignlen && fill == '0') { @@ -11399,6 +11557,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } } SvTAINT(sv); + +#ifdef USE_LOCALE_NUMERIC /* Done outside loop, so don't have to save/restore + each iteration. */ + if (oldlocale) { + setlocale(LC_NUMERIC, SvPVX(oldlocale)); + PL_numeric_standard = FALSE; + } +#endif } /* ========================================================================= @@ -12151,7 +12317,6 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) SvANY(dstr) = new_XNV(); SvNV_set(dstr, SvNVX(sstr)); break; - /* case SVt_DUMMY: */ default: { /* These are all the types that need complex bodies allocating. */ @@ -12176,6 +12341,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) case SVt_PVMG: case SVt_PVNV: case SVt_PVIV: + case SVt_INVLIST: case SVt_PV: assert(sv_type_details->body_size); if (sv_type_details->arena) { @@ -12213,6 +12379,8 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) if (sv_type >= SVt_PVMG) { if ((sv_type == SVt_PVMG) && SvPAD_OUR(dstr)) { SvOURSTASH_set(dstr, hv_dup_inc(SvOURSTASH(dstr), param)); + } else if (sv_type == SVt_PVAV && AvPAD_NAMELIST(dstr)) { + NOOP; } else if (SvMAGIC(dstr)) SvMAGIC_set(dstr, mg_dup(SvMAGIC(dstr), param)); if (SvOBJECT(dstr) && SvSTASH(dstr)) @@ -12395,7 +12563,6 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) daux->xhv_mro_meta = saux->xhv_mro_meta ? mro_meta_dup(saux->xhv_mro_meta, param) : 0; - daux->xhv_super = NULL; /* Record stashes for possible cloning in Perl_clone(). */ if (HvNAME(sstr)) @@ -12712,6 +12879,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) /* fall through */ case SAVEt_FREESV: case SAVEt_MORTALIZESV: + case SAVEt_READONLY_OFF: sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); break; @@ -12765,6 +12933,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPINT(nss,ix) = i; break; case SAVEt_IV: /* IV reference */ + case SAVEt_STRLEN: /* STRLEN/size_t ref */ ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); iv = POPIV(ss,ix); @@ -12834,6 +13003,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = cophh_copy((COPHH *)ptr); break; + case SAVEt_ADELETE: + av = (const AV *)POPPTR(ss,ix); + TOPPTR(nss,ix) = av_dup_inc(av, param); + i = POPINT(ss,ix); + TOPINT(nss,ix) = i; + break; case SAVEt_DELETE: hv = (const HV *)POPPTR(ss,ix); TOPPTR(nss,ix) = hv_dup_inc(hv, param); @@ -13217,8 +13392,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_cryptseen = proto_perl->Icryptseen; #endif - PL_hints = proto_perl->Ihints; - #ifdef USE_LOCALE_COLLATE PL_collation_ix = proto_perl->Icollation_ix; PL_collation_standard = proto_perl->Icollation_standard; @@ -13270,6 +13443,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_last_swash_slen = 0; PL_srand_called = proto_perl->Isrand_called; + Copy(&(proto_perl->Irandom_state), &PL_random_state, 1, PL_RANDOM_STATE_TYPE); if (flags & CLONEf_COPY_STACKS) { /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */ @@ -13362,6 +13536,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab)); ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab); + Zero(PL_sv_consts, SV_CONSTS_COUNT, SV*); + /* This PV will be free'd special way so must set it same way op.c does */ PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file); ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file); @@ -13389,9 +13565,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PerlIO_clone(aTHX_ proto_perl, param); #endif - PL_envgv = gv_dup(proto_perl->Ienvgv, param); - PL_incgv = gv_dup(proto_perl->Iincgv, param); - PL_hintgv = gv_dup(proto_perl->Ihintgv, param); + PL_envgv = gv_dup_inc(proto_perl->Ienvgv, param); + PL_incgv = gv_dup_inc(proto_perl->Iincgv, param); + PL_hintgv = gv_dup_inc(proto_perl->Ihintgv, param); PL_origfilename = SAVEPV(proto_perl->Iorigfilename); PL_diehook = sv_dup_inc(proto_perl->Idiehook, param); PL_warnhook = sv_dup_inc(proto_perl->Iwarnhook, param); @@ -13433,20 +13609,20 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_stdingv = gv_dup(proto_perl->Istdingv, param); PL_stderrgv = gv_dup(proto_perl->Istderrgv, param); PL_defgv = gv_dup(proto_perl->Idefgv, param); - PL_argvgv = gv_dup(proto_perl->Iargvgv, param); + PL_argvgv = gv_dup_inc(proto_perl->Iargvgv, param); PL_argvoutgv = gv_dup(proto_perl->Iargvoutgv, param); PL_argvout_stack = av_dup_inc(proto_perl->Iargvout_stack, param); /* shortcuts to regexp stuff */ - PL_replgv = gv_dup(proto_perl->Ireplgv, param); + PL_replgv = gv_dup_inc(proto_perl->Ireplgv, param); /* shortcuts to misc objects */ PL_errgv = gv_dup(proto_perl->Ierrgv, param); /* shortcuts to debugging objects */ - PL_DBgv = gv_dup(proto_perl->IDBgv, param); - PL_DBline = gv_dup(proto_perl->IDBline, param); - PL_DBsub = gv_dup(proto_perl->IDBsub, param); + PL_DBgv = gv_dup_inc(proto_perl->IDBgv, param); + PL_DBline = gv_dup_inc(proto_perl->IDBline, param); + PL_DBsub = gv_dup_inc(proto_perl->IDBsub, param); PL_DBsingle = sv_dup(proto_perl->IDBsingle, param); PL_DBtrace = sv_dup(proto_perl->IDBtrace, param); PL_DBsignal = sv_dup(proto_perl->IDBsignal, param); @@ -13555,8 +13731,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, #endif /* !USE_LOCALE_NUMERIC */ /* Unicode inversion lists */ - PL_ASCII = sv_dup_inc(proto_perl->IASCII, param); PL_Latin1 = sv_dup_inc(proto_perl->ILatin1, param); + PL_UpperLatin1 = sv_dup_inc(proto_perl->IUpperLatin1, param); + PL_AboveLatin1 = sv_dup_inc(proto_perl->IAboveLatin1, param); PL_NonL1NonFinalFold = sv_dup_inc(proto_perl->INonL1NonFinalFold, param); PL_HasMultiCharFold= sv_dup_inc(proto_perl->IHasMultiCharFold, param); @@ -13586,9 +13763,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_utf8_foldable = sv_dup_inc(proto_perl->Iutf8_foldable, param); PL_utf8_charname_begin = sv_dup_inc(proto_perl->Iutf8_charname_begin, param); PL_utf8_charname_continue = sv_dup_inc(proto_perl->Iutf8_charname_continue, param); - PL_ASCII = sv_dup_inc(proto_perl->IASCII, param); - PL_AboveLatin1 = sv_dup_inc(proto_perl->IAboveLatin1, param); - PL_Latin1 = sv_dup_inc(proto_perl->ILatin1, param); if (proto_perl->Ipsig_pend) { Newxz(PL_psig_pend, SIG_SIZE, int); @@ -13671,8 +13845,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_errors = sv_dup_inc(proto_perl->Ierrors, param); PL_sortcop = (OP*)any_dup(proto_perl->Isortcop, proto_perl); - PL_firstgv = gv_dup(proto_perl->Ifirstgv, param); - PL_secondgv = gv_dup(proto_perl->Isecondgv, param); + PL_firstgv = gv_dup_inc(proto_perl->Ifirstgv, param); + PL_secondgv = gv_dup_inc(proto_perl->Isecondgv, param); PL_stashcache = newHV(); @@ -14342,8 +14516,10 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, break; } else { + SV * const opsv = cSVOPx_sv(kid); + const IV opsviv = SvIV(opsv); SV * const * const svp = av_fetch(MUTABLE_AV(sv), - negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)), + negate ? - opsviv : opsviv, FALSE); if (!svp || *svp != uninit_sv) break;