X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/007f907ea86208f1afdcf1a6e28cf354162f10c3..6e8be9cfdd52adfc933b189c5829c3088178a7fe:/sv.c?ds=sidebyside diff --git a/sv.c b/sv.c index d16625a..e3426ad 100644 --- a/sv.c +++ b/sv.c @@ -552,7 +552,6 @@ do_clean_named_io_objs(pTHX_ SV *const sv) } /* Void wrapper to pass to visit() */ -/* XXX static void do_curse(pTHX_ SV * const sv) { if ((PL_stderrgv && GvGP(PL_stderrgv) && (SV*)GvIO(PL_stderrgv) == sv) @@ -560,7 +559,6 @@ do_curse(pTHX_ SV * const sv) { return; (void)curse(sv, 0); } -*/ /* =for apidoc sv_clean_objs @@ -584,9 +582,7 @@ Perl_sv_clean_objs(pTHX) visit(do_clean_named_io_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP); /* And if there are some very tenacious barnacles clinging to arrays, closures, or what have you.... */ - /* XXX This line breaks Tk and Gtk2. See [perl #82542]. visit(do_curse, SVs_OBJECT, SVs_OBJECT); - */ olddef = PL_defoutgv; PL_defoutgv = NULL; /* disable skip of PL_defoutgv */ if (olddef && isGV_with_GP(olddef)) @@ -897,37 +893,31 @@ static const struct body_details bodies_by_type[] = { NOARENA /* IVS don't need an arena */, 0 }, - /* 8 bytes on most ILP32 with IEEE doubles */ { sizeof(NV), sizeof(NV), STRUCT_OFFSET(XPVNV, xnv_u), SVt_NV, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(NV)) }, - /* 8 bytes on most ILP32 with IEEE doubles */ { sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur), copy_length(XPV, xpv_len) - STRUCT_OFFSET(XPV, xpv_cur), + STRUCT_OFFSET(XPV, xpv_cur), SVt_PV, FALSE, NONV, HASARENA, FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) }, - /* 12 */ { sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur), copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur), + STRUCT_OFFSET(XPV, xpv_cur), SVt_PVIV, FALSE, NONV, HASARENA, FIT_ARENA(0, sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur)) }, - /* 20 */ { sizeof(XPVNV) - STRUCT_OFFSET(XPV, xpv_cur), copy_length(XPVNV, xnv_u) - STRUCT_OFFSET(XPV, xpv_cur), + STRUCT_OFFSET(XPV, xpv_cur), SVt_PVNV, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVNV) - STRUCT_OFFSET(XPV, xpv_cur)) }, - /* 28 */ { sizeof(XPVMG), copy_length(XPVMG, xnv_u), 0, SVt_PVMG, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVMG)) }, - /* something big */ { sizeof(regexp), sizeof(regexp), 0, @@ -935,11 +925,9 @@ static const struct body_details bodies_by_type[] = { FIT_ARENA(0, sizeof(regexp)) }, - /* 48 */ { sizeof(XPVGV), sizeof(XPVGV), 0, SVt_PVGV, TRUE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVGV)) }, - /* 64 */ { sizeof(XPVLV), sizeof(XPVLV), 0, SVt_PVLV, TRUE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVLV)) }, @@ -955,7 +943,6 @@ static const struct body_details bodies_by_type[] = { SVt_PVHV, TRUE, NONV, HASARENA, FIT_ARENA(0, sizeof(XPVHV)) }, - /* 56 */ { sizeof(XPVCV), sizeof(XPVCV), 0, @@ -968,7 +955,6 @@ static const struct body_details bodies_by_type[] = { SVt_PVFM, TRUE, NONV, NOARENA, FIT_ARENA(20, sizeof(XPVFM)) }, - /* XPVIO is 84 bytes, fits 48x */ { sizeof(XPVIO), sizeof(XPVIO), 0, @@ -2271,11 +2257,13 @@ Perl_sv_2iv_flags(pTHX_ register SV *const sv, const I32 flags) dVAR; if (!sv) return 0; - if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) { - /* FBMs use the same flag bit as SVf_IVisUV, so must let them - cache IVs just in case. In practice it seems that they never - actually anywhere accessible by user Perl code, let alone get used - in anything other than a string context. */ + if (SvGMAGICAL(sv) || SvVALID(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. + 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. + */ if (flags & SV_GMAGIC) mg_get(sv); if (SvIOKp(sv)) @@ -2358,9 +2346,9 @@ Perl_sv_2uv_flags(pTHX_ register SV *const sv, const I32 flags) dVAR; if (!sv) return 0; - if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) { - /* FBMs use the same flag bit as SVf_IVisUV, so must let them - cache IVs just in case. */ + if (SvGMAGICAL(sv) || SvVALID(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. */ if (flags & SV_GMAGIC) mg_get(sv); if (SvIOKp(sv)) @@ -2438,9 +2426,9 @@ Perl_sv_2nv_flags(pTHX_ register SV *const sv, const I32 flags) dVAR; if (!sv) return 0.0; - if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) { - /* FBMs use the same flag bit as SVf_IVisUV, so must let them - cache IVs just in case. */ + if (SvGMAGICAL(sv) || SvVALID(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. */ if (flags & SV_GMAGIC) mg_get(sv); if (SvNOKp(sv)) @@ -3433,6 +3421,29 @@ must_be_utf8: } } } + + 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) */ + 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); + } + } + if ((mg = mg_find(sv, PERL_MAGIC_utf8))) + magic_setutf8(sv,mg); /* clear UTF8 cache */ + } } } @@ -3467,11 +3478,28 @@ Perl_sv_utf8_downgrade(pTHX_ register SV *const sv, const bool fail_ok) if (SvCUR(sv)) { U8 *s; STRLEN len; + int mg_flags = SV_GMAGIC; if (SvIsCOW(sv)) { sv_force_normal_flags(sv, 0); } - s = (U8 *) SvPV(sv, len); + 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); + 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 */ + + } + s = (U8 *) SvPV_flags(sv, len, mg_flags); + if (!utf8_to_bytes(s, &len)) { if (fail_ok) return FALSE; @@ -3520,7 +3548,7 @@ Perl_sv_utf8_encode(pTHX_ register SV *const sv) If the PV of the SV is an octet sequence in 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 being off. +characters, the C flag stays off. Scans PV for validity and returns false if the PV is invalid UTF-8. =cut @@ -3532,7 +3560,7 @@ Perl_sv_utf8_decode(pTHX_ register SV *const sv) PERL_ARGS_ASSERT_SV_UTF8_DECODE; if (SvPOKp(sv)) { - const U8 *c; + const U8 *start, *c; const U8 *e; /* The octets may have got themselves encoded - get them back as @@ -3544,7 +3572,7 @@ Perl_sv_utf8_decode(pTHX_ register SV *const sv) /* it is actually just a matter of turning the utf8 flag on, but * we want to make sure everything inside is valid utf8 first. */ - c = (const U8 *) SvPVX_const(sv); + c = start = (const U8 *) SvPVX_const(sv); if (!is_utf8_string(c, SvCUR(sv)+1)) return FALSE; e = (const U8 *) SvEND(sv); @@ -3555,6 +3583,22 @@ Perl_sv_utf8_decode(pTHX_ register SV *const sv) break; } } + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { + /* adjust pos to the start of a UTF8 char sequence */ + MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global); + if (mg) { + I32 pos = mg->mg_len; + if (pos > 0) { + for (c = start + pos; c > start; c--) { + if (UTF8_IS_START(*c)) + break; + } + mg->mg_len = c - start; + } + } + if ((mg = mg_find(sv, PERL_MAGIC_utf8))) + magic_setutf8(sv,mg); /* clear UTF8 cache */ + } } return TRUE; } @@ -3663,7 +3707,8 @@ S_glob_assign_glob(pTHX_ SV *const dstr, SV *const sstr, const int dtype) mro_changes = 2; else { const STRLEN len = GvNAMELEN(dstr); - if (len > 1 && name[len-2] == ':' && name[len-1] == ':') { + if ((len > 1 && name[len-2] == ':' && name[len-1] == ':') + || (len == 1 && name[0] == ':')) { mro_changes = 3; /* Set aside the old stash, so we can reset isa caches on @@ -3823,7 +3868,10 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) const char * const name = GvNAME((GV*)dstr); const STRLEN len = GvNAMELEN(dstr); if ( - len > 1 && name[len-2] == ':' && name[len-1] == ':' + ( + (len > 1 && name[len-2] == ':' && name[len-1] == ':') + || (len == 1 && name[0] == ':') + ) && (!dref || HvENAME_get(dref)) ) { mro_package_moved( @@ -4030,8 +4078,6 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags) /* case SVt_BIND: */ case SVt_PVLV: case SVt_PVGV: - /* SvVALID means that this PVGV is playing at being an FBM. */ - case SVt_PVMG: if (SvGMAGICAL(sstr) && (flags & SV_GMAGIC)) { mg_get(sstr); @@ -4121,7 +4167,8 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags) const STRLEN len = GvNAMELEN(dstr); HV *old_stash = NULL; bool reset_isa = FALSE; - if (len > 1 && name[len-2] == ':' && name[len-1] == ':') { + if ((len > 1 && name[len-2] == ':' && name[len-1] == ':') + || (len == 1 && name[0] == ':')) { /* Set aside the old stash, so we can reset isa caches on its subclasses. */ if((old_stash = GvHV(dstr))) { @@ -4719,7 +4766,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags) } #else if (SvREADONLY(sv)) { - if (SvFAKE(sv)) { + if (SvFAKE(sv) && !isGV_with_GP(sv)) { const char * const pvx = SvPVX_const(sv); const STRLEN len = SvCUR(sv); SvFAKE_off(sv); @@ -5048,7 +5095,7 @@ space is allocated.) The reference count for the new SV is set to 1. In 5.9.3, newSV() replaces the older NEWSV() API, and drops the first parameter, I, a debug aid which allowed callers to identify themselves. This aid has been superseded by a new build option, PERL_MEM_LOG (see -L). The older API is still there for use in XS +L). The older API is still there for use in XS modules supporting older perls. =cut @@ -5182,9 +5229,25 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, dVAR; const MGVTBL *vtable; MAGIC* mg; + unsigned int flags; + unsigned int vtable_index; PERL_ARGS_ASSERT_SV_MAGIC; + if (how < 0 || (unsigned)how > C_ARRAY_LENGTH(PL_magic_data) + || ((flags = PL_magic_data[how]), + (vtable_index = flags & PERL_MAGIC_VTABLE_MASK) + > magic_vtable_max)) + Perl_croak(aTHX_ "Don't know how to handle magic of type \\%o", how); + + /* PERL_MAGIC_ext is reserved for use by extensions not perl internals. + Useful for attaching extension internal data to perl vars. + Note that multiple extensions may clash if magical scalars + etc holding private data from one are passed to another. */ + + vtable = (vtable_index == magic_vtable_max) + ? NULL : PL_magic_vtables + vtable_index; + #ifdef PERL_OLD_COPY_ON_WRITE if (SvIsCOW(sv)) sv_force_normal_flags(sv, 0); @@ -5196,11 +5259,7 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, !(SvFAKE(sv) && SvTYPE(sv) < SVt_PVMG) && IN_PERL_RUNTIME - && how != PERL_MAGIC_regex_global - && how != PERL_MAGIC_bm - && how != PERL_MAGIC_fm - && how != PERL_MAGIC_sv - && how != PERL_MAGIC_backref + && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how) ) { Perl_croak_no_modify(aTHX); @@ -5222,127 +5281,6 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, } } - switch (how) { - case PERL_MAGIC_sv: - vtable = &PL_vtbl_sv; - break; - case PERL_MAGIC_overload: - vtable = &PL_vtbl_amagic; - break; - case PERL_MAGIC_overload_elem: - vtable = &PL_vtbl_amagicelem; - break; - case PERL_MAGIC_overload_table: - vtable = &PL_vtbl_ovrld; - break; - case PERL_MAGIC_bm: - vtable = &PL_vtbl_bm; - break; - case PERL_MAGIC_regdata: - vtable = &PL_vtbl_regdata; - break; - case PERL_MAGIC_regdatum: - vtable = &PL_vtbl_regdatum; - break; - case PERL_MAGIC_env: - vtable = &PL_vtbl_env; - break; - case PERL_MAGIC_fm: - vtable = &PL_vtbl_fm; - break; - case PERL_MAGIC_envelem: - vtable = &PL_vtbl_envelem; - break; - case PERL_MAGIC_regex_global: - vtable = &PL_vtbl_mglob; - break; - case PERL_MAGIC_isa: - vtable = &PL_vtbl_isa; - break; - case PERL_MAGIC_isaelem: - vtable = &PL_vtbl_isaelem; - break; - case PERL_MAGIC_nkeys: - vtable = &PL_vtbl_nkeys; - break; - case PERL_MAGIC_dbfile: - vtable = NULL; - break; - case PERL_MAGIC_dbline: - vtable = &PL_vtbl_dbline; - break; -#ifdef USE_LOCALE_COLLATE - case PERL_MAGIC_collxfrm: - vtable = &PL_vtbl_collxfrm; - break; -#endif /* USE_LOCALE_COLLATE */ - case PERL_MAGIC_tied: - vtable = &PL_vtbl_pack; - break; - case PERL_MAGIC_tiedelem: - case PERL_MAGIC_tiedscalar: - vtable = &PL_vtbl_packelem; - break; - case PERL_MAGIC_qr: - vtable = &PL_vtbl_regexp; - break; - case PERL_MAGIC_sig: - vtable = &PL_vtbl_sig; - break; - case PERL_MAGIC_sigelem: - vtable = &PL_vtbl_sigelem; - break; - case PERL_MAGIC_taint: - vtable = &PL_vtbl_taint; - break; - case PERL_MAGIC_uvar: - vtable = &PL_vtbl_uvar; - break; - case PERL_MAGIC_vec: - vtable = &PL_vtbl_vec; - break; - case PERL_MAGIC_arylen_p: - case PERL_MAGIC_rhash: - case PERL_MAGIC_symtab: - case PERL_MAGIC_vstring: - case PERL_MAGIC_checkcall: - vtable = NULL; - break; - case PERL_MAGIC_utf8: - vtable = &PL_vtbl_utf8; - break; - case PERL_MAGIC_substr: - vtable = &PL_vtbl_substr; - break; - case PERL_MAGIC_defelem: - vtable = &PL_vtbl_defelem; - break; - case PERL_MAGIC_arylen: - vtable = &PL_vtbl_arylen; - break; - case PERL_MAGIC_pos: - vtable = &PL_vtbl_pos; - break; - case PERL_MAGIC_backref: - vtable = &PL_vtbl_backref; - break; - case PERL_MAGIC_hintselem: - vtable = &PL_vtbl_hintselem; - break; - case PERL_MAGIC_hints: - vtable = &PL_vtbl_hints; - break; - case PERL_MAGIC_ext: - /* Reserved for use by extensions not perl internals. */ - /* Useful for attaching extension internal data to perl vars. */ - /* Note that multiple extensions may clash if magical scalars */ - /* etc holding private data from one are passed to another. */ - vtable = NULL; - break; - default: - Perl_croak(aTHX_ "Don't know how to handle magic of type \\%o", how); - } - /* Rest of work is done else where */ mg = sv_magicext(sv,obj,how,vtable,name,namlen); @@ -5357,7 +5295,7 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, } } -int +static int S_sv_unmagicext_flags(pTHX_ SV *const sv, const int type, MGVTBL *vtbl, const U32 flags) { MAGIC* mg; @@ -5471,16 +5409,13 @@ Perl_sv_rvweaken(pTHX_ SV *const sv) * store it directly in the HvAUX or mg_obj slot, avoiding the need to * allocate an AV. (Whether the slot holds an AV tells us whether this is * active.) - * - * If an HV's backref is stored in magic, it is moved back to HvAUX. */ /* A discussion about the backreferences array and its refcount: * * The AV holding the backreferences is pointed to either as the mg_obj of - * PERL_MAGIC_backref, or in the specific case of a HV that has the hv_aux - * structure, from the xhv_backreferences field. (A HV without hv_aux will - * have the standard magic instead.) The array is created with a refcount + * PERL_MAGIC_backref, or in the specific case of a HV, from the + * xhv_backreferences field. The array is created with a refcount * of 2. This means that if during global destruction the array gets * picked on before its parent to have its refcount decremented by the * random zapper, it won't actually be freed, meaning it's still there for @@ -5508,21 +5443,6 @@ 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)); - - if (!*svp) { - if ((mg = mg_find(tsv, PERL_MAGIC_backref))) { - /* Aha. They've got it stowed in magic instead. - * Move it back to xhv_backreferences */ - *svp = mg->mg_obj; - /* Stop mg_free decreasing the reference count. */ - mg->mg_obj = NULL; - /* Stop mg_free even calling the destructor, given that - there's no AV to free up. */ - mg->mg_virtual = 0; - sv_unmagic(tsv, PERL_MAGIC_backref); - mg = NULL; - } - } } else { if (! ((mg = (SvMAGICAL(tsv) ? mg_find(tsv, PERL_MAGIC_backref) : NULL)))) @@ -5580,10 +5500,11 @@ Perl_sv_del_backref(pTHX_ SV *const tsv, SV *const sv) PERL_ARGS_ASSERT_SV_DEL_BACKREF; - if (SvTYPE(tsv) == SVt_PVHV && SvOOK(tsv)) { - svp = (SV**)Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(tsv)); + if (SvTYPE(tsv) == SVt_PVHV) { + if (SvOOK(tsv)) + svp = (SV**)Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(tsv)); } - if (!svp || !*svp) { + else { MAGIC *const mg = SvMAGICAL(tsv) ? mg_find(tsv, PERL_MAGIC_backref) : NULL; svp = mg ? &(mg->mg_obj) : NULL; @@ -5663,6 +5584,17 @@ Perl_sv_kill_backrefs(pTHX_ SV *const sv, AV *const av) if (!av) return; + /* after multiple passes through Perl_sv_clean_all() for a thinngy + * that has badly leaked, the backref array may have gotten freed, + * since we only protect it against 1 round of cleanup */ + if (SvIS_FREED(av)) { + if (PL_in_clean_all) /* All is fair */ + return; + Perl_croak(aTHX_ + "panic: magic_killbackrefs (freed backref AV/SV)"); + } + + is_array = (SvTYPE(av) == SVt_PVAV); if (is_array) { assert(!SvIS_FREED(av)); @@ -5935,7 +5867,8 @@ S_anonymise_cv_maybe(pTHX_ GV *gv, CV* cv) } /* if not, anonymise: */ - stash = GvSTASH(gv) ? HvNAME(GvSTASH(gv)) : NULL; + stash = GvSTASH(gv) && HvNAME(GvSTASH(gv)) + ? HvENAME(GvSTASH(gv)) : NULL; gvname = Perl_newSVpvf(aTHX_ "%s::__ANON__", stash ? stash : "__ANON__"); anongv = gv_fetchsv(gvname, GV_ADDMULTI, SVt_PVCV); @@ -5971,6 +5904,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) SV* iter_sv = NULL; SV* next_sv = NULL; register SV *sv = orig_sv; + STRLEN hash_index; PERL_ARGS_ASSERT_SV_CLEAR; @@ -5996,15 +5930,21 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) goto free_head; } - if (SvOBJECT(sv)) { - if (!curse(sv, 1)) goto get_next_sv; - } + assert(!SvOBJECT(sv) || type >= SVt_PVMG); /* objs are always >= MG */ + if (type >= SVt_PVMG) { + if (SvOBJECT(sv)) { + if (!curse(sv, 1)) goto get_next_sv; + type = SvTYPE(sv); /* destructor may have changed it */ + } /* Free back-references before magic, in case the magic calls * Perl code that has weak references to sv. */ - if (type == SVt_PVHV) + if (type == SVt_PVHV) { Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv)); - if (type == SVt_PVMG && SvPAD_OUR(sv)) { + if (SvMAGIC(sv)) + mg_free(sv); + } + else if (type == SVt_PVMG && SvPAD_OUR(sv)) { SvREFCNT_dec(SvOURSTASH(sv)); } else if (SvMAGIC(sv)) { /* Free back-references before other types of magic. */ @@ -6049,7 +5989,38 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) if (PL_last_swash_hv == (const HV *)sv) { PL_last_swash_hv = NULL; } + if (HvTOTALKEYS((HV*)sv) > 0) { + const char *name; + /* this statement should match the one at the beginning of + * hv_undef_flags() */ + if ( PL_phase != PERL_PHASE_DESTRUCT + && (name = HvNAME((HV*)sv))) + { + if (PL_stashcache) + (void)hv_delete(PL_stashcache, name, + HvNAMELEN_get((HV*)sv), G_DISCARD); + hv_name_set((HV*)sv, NULL, 0, 0); + } + + /* save old iter_sv in unused SvSTASH field */ + assert(!SvOBJECT(sv)); + SvSTASH(sv) = (HV*)iter_sv; + iter_sv = sv; + + /* XXX ideally we should save the old value of hash_index + * too, but I can't think of any place to hide it. The + * effect of not saving it is that for freeing hashes of + * hashes, we become quadratic in scanning the HvARRAY of + * the top hash looking for new entries to free; but + * hopefully this will be dwarfed by the freeing of all + * the nested hashes. */ + hash_index = 0; + next_sv = Perl_hfree_next_entry(aTHX_ (HV*)sv, &hash_index); + goto get_next_sv; /* process this new sv */ + } + /* free empty hash */ Perl_hv_undef_flags(aTHX_ MUTABLE_HV(sv), HV_NAME_SETALL); + assert(!HvARRAY((HV*)sv)); break; case SVt_PVAV: { @@ -6198,6 +6169,25 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) Safefree(AvALLOC(av)); goto free_body; } + } else if (SvTYPE(iter_sv) == SVt_PVHV) { + sv = Perl_hfree_next_entry(aTHX_ (HV*)iter_sv, &hash_index); + if (!sv && !HvTOTALKEYS((HV *)iter_sv)) { + /* no more elements of current HV to free */ + sv = iter_sv; + type = SvTYPE(sv); + /* Restore previous value of iter_sv, squirrelled away */ + assert(!SvOBJECT(sv)); + iter_sv = (SV*)SvSTASH(sv); + + /* ideally we should restore the old hash_index here, + * but we don't currently save the old value */ + hash_index = 0; + + /* free any remaining detritus from the hash struct */ + Perl_hv_undef_flags(aTHX_ MUTABLE_HV(sv), HV_NAME_SETALL); + assert(!HvARRAY((HV*)sv)); + goto free_body; + } } /* unrolled SvREFCNT_dec and sv_free2 follows: */ @@ -9485,6 +9475,7 @@ Perl_sv_unref_flags(pTHX_ SV *const ref, const U32 flags) =for apidoc sv_untaint Untaint an SV. Use C instead. + =cut */ @@ -9504,6 +9495,7 @@ Perl_sv_untaint(pTHX_ SV *const sv) =for apidoc sv_tainted Test an SV for taintedness. Use C instead. + =cut */ @@ -10319,8 +10311,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, break; #endif case 'l': + ++q; #if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE) - if (*++q == 'l') { /* lld, llf */ + if (*q == 'l') { /* lld, llf */ intsize = 'q'; ++q; } @@ -12711,6 +12704,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PoisonNew(my_perl, 1, PerlInterpreter); PL_op = NULL; PL_curcop = NULL; + PL_defstash = NULL; /* may be used by perl malloc() */ PL_markstack = 0; PL_scopestack = 0; PL_scopestack_name = 0; @@ -12764,67 +12758,23 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_hash_seed = proto_perl->Ihash_seed; PL_rehash_seed = proto_perl->Irehash_seed; -#ifdef USE_REENTRANT_API - /* XXX: things like -Dm will segfault here in perlio, but doing - * PERL_SET_CONTEXT(proto_perl); - * breaks too many other things - */ - Perl_reentrant_init(aTHX); -#endif - - /* create SV map for pointer relocation */ - PL_ptr_table = ptr_table_new(); - - /* initialize these special pointers as early as possible */ SvANY(&PL_sv_undef) = NULL; SvREFCNT(&PL_sv_undef) = (~(U32)0)/2; SvFLAGS(&PL_sv_undef) = SVf_READONLY|SVt_NULL; - ptr_table_store(PL_ptr_table, &proto_perl->Isv_undef, &PL_sv_undef); - - SvANY(&PL_sv_no) = new_XPVNV(); SvREFCNT(&PL_sv_no) = (~(U32)0)/2; SvFLAGS(&PL_sv_no) = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV; - SvPV_set(&PL_sv_no, savepvn(PL_No, 0)); - SvCUR_set(&PL_sv_no, 0); - SvLEN_set(&PL_sv_no, 1); - SvIV_set(&PL_sv_no, 0); - SvNV_set(&PL_sv_no, 0); - ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no); SvANY(&PL_sv_yes) = new_XPVNV(); SvREFCNT(&PL_sv_yes) = (~(U32)0)/2; SvFLAGS(&PL_sv_yes) = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV; - SvPV_set(&PL_sv_yes, savepvn(PL_Yes, 1)); - SvCUR_set(&PL_sv_yes, 1); - SvLEN_set(&PL_sv_yes, 2); - SvIV_set(&PL_sv_yes, 1); - SvNV_set(&PL_sv_yes, 1); - ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes); /* dbargs array probably holds garbage */ PL_dbargs = NULL; - /* create (a non-shared!) shared string table */ - PL_strtab = newHV(); - HvSHAREKEYS_off(PL_strtab); - hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab)); - ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab); - PL_compiling = proto_perl->Icompiling; - /* These two PVs will be free'd special way so must set them same way op.c does */ - PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv); - ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, PL_compiling.cop_stashpv); - - PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file); - ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file); - - ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling); - PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings); - CopHINTHASH_set(&PL_compiling, cophh_copy(CopHINTHASH_get(&PL_compiling))); - PL_curcop = (COP*)any_dup(proto_perl->Icurcop, proto_perl); #ifdef PERL_DEBUG_READONLY_OPS PL_slabs = NULL; PL_slab_count = 0; @@ -12834,39 +12784,12 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_origargc = proto_perl->Iorigargc; PL_origargv = proto_perl->Iorigargv; - param->stashes = newAV(); /* Setup array of objects to call clone on */ - /* This makes no difference to the implementation, as it always pushes - and shifts pointers to other SVs without changing their reference - count, with the array becoming empty before it is freed. However, it - makes it conceptually clear what is going on, and will avoid some - work inside av.c, filling slots between AvFILL() and AvMAX() with - &PL_sv_undef, and SvREFCNT_dec()ing those. */ - AvREAL_off(param->stashes); - - if (!(flags & CLONEf_COPY_STACKS)) { - param->unreferenced = newAV(); - } - /* Set tainting stuff before PerlIO_debug can possibly get called */ PL_tainting = proto_perl->Itainting; PL_taint_warn = proto_perl->Itaint_warn; -#ifdef PERLIO_LAYERS - /* Clone PerlIO tables as soon as we can handle general xx_dup() */ - 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_origfilename = SAVEPV(proto_perl->Iorigfilename); - PL_diehook = sv_dup_inc(proto_perl->Idiehook, param); - PL_warnhook = sv_dup_inc(proto_perl->Iwarnhook, param); - - /* switches */ PL_minus_c = proto_perl->Iminus_c; - PL_patchlevel = sv_dup_inc(proto_perl->Ipatchlevel, param); - PL_apiversion = sv_dup_inc(proto_perl->Iapiversion, param); + PL_localpatches = proto_perl->Ilocalpatches; PL_splitstr = proto_perl->Isplitstr; PL_minus_n = proto_perl->Iminus_n; @@ -12879,16 +12802,12 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_dowarn = proto_perl->Idowarn; PL_sawampersand = proto_perl->Isawampersand; PL_unsafe = proto_perl->Iunsafe; - PL_inplace = SAVEPV(proto_perl->Iinplace); - PL_e_script = sv_dup_inc(proto_perl->Ie_script, param); PL_perldb = proto_perl->Iperldb; PL_perl_destruct_level = proto_perl->Iperl_destruct_level; PL_exit_flags = proto_perl->Iexit_flags; - /* magical thingies */ /* XXX time(&PL_basetime) when asked for? */ PL_basetime = proto_perl->Ibasetime; - PL_formfeed = sv_dup(proto_perl->Iformfeed, param); PL_maxsysfd = proto_perl->Imaxsysfd; PL_statusvalue = proto_perl->Istatusvalue; @@ -12897,119 +12816,357 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, #else PL_statusvalue_posix = proto_perl->Istatusvalue_posix; #endif - PL_encoding = sv_dup(proto_perl->Iencoding, param); - - 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. */ - /* RE engine related */ Zero(&PL_reg_state, 1, struct re_save_state); PL_reginterp_cnt = 0; PL_regmatch_slab = NULL; - - /* Clone the regex array */ - /* ORANGE FIXME for plugins, probably in the SV dup code. - newSViv(PTR2IV(CALLREGDUPE( - INT2PTR(REGEXP *, SvIVX(regex)), param)))) - */ - PL_regex_padav = av_dup_inc(proto_perl->Iregex_padav, param); - PL_regex_pad = AvARRAY(PL_regex_padav); - - /* shortcuts to various I/O objects */ - PL_ofsgv = gv_dup_inc(proto_perl->Iofsgv, param); - 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_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); - - /* 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_DBsingle = sv_dup(proto_perl->IDBsingle, param); - PL_DBtrace = sv_dup(proto_perl->IDBtrace, param); - PL_DBsignal = sv_dup(proto_perl->IDBsignal, param); - - /* symbol tables */ - PL_defstash = hv_dup_inc(proto_perl->Idefstash, param); - PL_curstash = hv_dup(proto_perl->Icurstash, param); - PL_debstash = hv_dup(proto_perl->Idebstash, param); - PL_globalstash = hv_dup(proto_perl->Iglobalstash, param); - PL_curstname = sv_dup_inc(proto_perl->Icurstname, param); - - PL_beginav = av_dup_inc(proto_perl->Ibeginav, param); - PL_beginav_save = av_dup_inc(proto_perl->Ibeginav_save, param); - PL_checkav_save = av_dup_inc(proto_perl->Icheckav_save, param); - PL_unitcheckav = av_dup_inc(proto_perl->Iunitcheckav, param); - PL_unitcheckav_save = av_dup_inc(proto_perl->Iunitcheckav_save, param); - PL_endav = av_dup_inc(proto_perl->Iendav, param); - PL_checkav = av_dup_inc(proto_perl->Icheckav, param); - PL_initav = av_dup_inc(proto_perl->Iinitav, param); PL_sub_generation = proto_perl->Isub_generation; - PL_isarev = hv_dup_inc(proto_perl->Iisarev, param); /* funky return mechanisms */ PL_forkprocess = proto_perl->Iforkprocess; - /* subprocess state */ - PL_fdpid = av_dup_inc(proto_perl->Ifdpid, param); - /* internal state */ PL_maxo = proto_perl->Imaxo; - if (proto_perl->Iop_mask) - PL_op_mask = SAVEPVN(proto_perl->Iop_mask, PL_maxo); - else - PL_op_mask = NULL; - /* PL_asserting = proto_perl->Iasserting; */ - /* current interpreter roots */ - PL_main_cv = cv_dup_inc(proto_perl->Imain_cv, param); - OP_REFCNT_LOCK; - PL_main_root = OpREFCNT_inc(proto_perl->Imain_root); - OP_REFCNT_UNLOCK; PL_main_start = proto_perl->Imain_start; PL_eval_root = proto_perl->Ieval_root; PL_eval_start = proto_perl->Ieval_start; - /* runtime control stuff */ - PL_curcopdb = (COP*)any_dup(proto_perl->Icurcopdb, proto_perl); - PL_filemode = proto_perl->Ifilemode; PL_lastfd = proto_perl->Ilastfd; PL_oldname = proto_perl->Ioldname; /* XXX not quite right */ PL_Argv = NULL; PL_Cmd = NULL; PL_gensym = proto_perl->Igensym; - PL_preambleav = av_dup_inc(proto_perl->Ipreambleav, param); + PL_laststatval = proto_perl->Ilaststatval; PL_laststype = proto_perl->Ilaststype; PL_mess_sv = NULL; - PL_ors_sv = sv_dup_inc(proto_perl->Iors_sv, param); + PL_profiledata = NULL; - /* interpreter atexit processing */ - PL_exitlistlen = proto_perl->Iexitlistlen; - if (PL_exitlistlen) { - Newx(PL_exitlist, PL_exitlistlen, PerlExitListEntry); - Copy(proto_perl->Iexitlist, PL_exitlist, PL_exitlistlen, PerlExitListEntry); - } - else - PL_exitlist = (PerlExitListEntry*)NULL; + PL_generation = proto_perl->Igeneration; - PL_my_cxt_size = proto_perl->Imy_cxt_size; - if (PL_my_cxt_size) { - Newx(PL_my_cxt_list, PL_my_cxt_size, void *); + PL_in_clean_objs = proto_perl->Iin_clean_objs; + PL_in_clean_all = proto_perl->Iin_clean_all; + + PL_uid = proto_perl->Iuid; + PL_euid = proto_perl->Ieuid; + PL_gid = proto_perl->Igid; + PL_egid = proto_perl->Iegid; + PL_nomemok = proto_perl->Inomemok; + PL_an = proto_perl->Ian; + PL_evalseq = proto_perl->Ievalseq; + PL_origenviron = proto_perl->Iorigenviron; /* XXX not quite right */ + PL_origalen = proto_perl->Iorigalen; + + PL_sighandlerp = proto_perl->Isighandlerp; + + PL_runops = proto_perl->Irunops; + + PL_subline = proto_perl->Isubline; + +#ifdef FCRYPT + PL_cryptseen = proto_perl->Icryptseen; +#endif + + PL_hints = proto_perl->Ihints; + + PL_amagic_generation = proto_perl->Iamagic_generation; + +#ifdef USE_LOCALE_COLLATE + PL_collation_ix = proto_perl->Icollation_ix; + PL_collation_standard = proto_perl->Icollation_standard; + PL_collxfrm_base = proto_perl->Icollxfrm_base; + PL_collxfrm_mult = proto_perl->Icollxfrm_mult; +#endif /* USE_LOCALE_COLLATE */ + +#ifdef USE_LOCALE_NUMERIC + PL_numeric_standard = proto_perl->Inumeric_standard; + PL_numeric_local = proto_perl->Inumeric_local; +#endif /* !USE_LOCALE_NUMERIC */ + + /* Did the locale setup indicate UTF-8? */ + PL_utf8locale = proto_perl->Iutf8locale; + /* Unicode features (see perlrun/-C) */ + PL_unicode = proto_perl->Iunicode; + + /* Pre-5.8 signals control */ + PL_signals = proto_perl->Isignals; + + /* times() ticks per second */ + PL_clocktick = proto_perl->Iclocktick; + + /* Recursion stopper for PerlIO_find_layer */ + PL_in_load_module = proto_perl->Iin_load_module; + + /* sort() routine */ + PL_sort_RealCmp = proto_perl->Isort_RealCmp; + + /* Not really needed/useful since the reenrant_retint is "volatile", + * but do it for consistency's sake. */ + PL_reentrant_retint = proto_perl->Ireentrant_retint; + + /* Hooks to shared SVs and locks. */ + PL_sharehook = proto_perl->Isharehook; + PL_lockhook = proto_perl->Ilockhook; + PL_unlockhook = proto_perl->Iunlockhook; + PL_threadhook = proto_perl->Ithreadhook; + PL_destroyhook = proto_perl->Idestroyhook; + PL_signalhook = proto_perl->Isignalhook; + +#ifdef THREADS_HAVE_PIDS + PL_ppid = proto_perl->Ippid; +#endif + + /* swatch cache */ + PL_last_swash_hv = NULL; /* reinits on demand */ + PL_last_swash_klen = 0; + PL_last_swash_key[0]= '\0'; + PL_last_swash_tmps = (U8*)NULL; + PL_last_swash_slen = 0; + + PL_glob_index = proto_perl->Iglob_index; + PL_srand_called = proto_perl->Isrand_called; + + if (flags & CLONEf_COPY_STACKS) { + /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */ + PL_tmps_ix = proto_perl->Itmps_ix; + PL_tmps_max = proto_perl->Itmps_max; + PL_tmps_floor = proto_perl->Itmps_floor; + + /* next push_scope()/ENTER sets PL_scopestack[PL_scopestack_ix] + * NOTE: unlike the others! */ + PL_scopestack_ix = proto_perl->Iscopestack_ix; + PL_scopestack_max = proto_perl->Iscopestack_max; + + /* next SSPUSHFOO() sets PL_savestack[PL_savestack_ix] + * NOTE: unlike the others! */ + PL_savestack_ix = proto_perl->Isavestack_ix; + PL_savestack_max = proto_perl->Isavestack_max; + } + + PL_start_env = proto_perl->Istart_env; /* XXXXXX */ + PL_top_env = &PL_start_env; + + PL_op = proto_perl->Iop; + + PL_Sv = NULL; + PL_Xpv = (XPV*)NULL; + my_perl->Ina = proto_perl->Ina; + + PL_statbuf = proto_perl->Istatbuf; + PL_statcache = proto_perl->Istatcache; + +#ifdef HAS_TIMES + PL_timesbuf = proto_perl->Itimesbuf; +#endif + + PL_tainted = proto_perl->Itainted; + PL_curpm = proto_perl->Icurpm; /* XXX No PMOP ref count */ + + PL_chopset = proto_perl->Ichopset; /* XXX never deallocated */ + + PL_restartjmpenv = proto_perl->Irestartjmpenv; + PL_restartop = proto_perl->Irestartop; + PL_in_eval = proto_perl->Iin_eval; + PL_delaymagic = proto_perl->Idelaymagic; + PL_phase = proto_perl->Iphase; + PL_localizing = proto_perl->Ilocalizing; + + PL_hv_fetch_ent_mh = NULL; + PL_modcount = proto_perl->Imodcount; + PL_lastgotoprobe = NULL; + PL_dumpindent = proto_perl->Idumpindent; + + PL_efloatbuf = NULL; /* reinits on demand */ + PL_efloatsize = 0; /* reinits on demand */ + + /* regex stuff */ + + PL_regdummy = proto_perl->Iregdummy; + PL_colorset = 0; /* reinits PL_colors[] */ + /*PL_colors[6] = {0,0,0,0,0,0};*/ + + /* Pluggable optimizer */ + PL_peepp = proto_perl->Ipeepp; + PL_rpeepp = proto_perl->Irpeepp; + /* op_free() hook */ + PL_opfreehook = proto_perl->Iopfreehook; + +#ifdef USE_REENTRANT_API + /* XXX: things like -Dm will segfault here in perlio, but doing + * PERL_SET_CONTEXT(proto_perl); + * breaks too many other things + */ + Perl_reentrant_init(aTHX); +#endif + + /* create SV map for pointer relocation */ + PL_ptr_table = ptr_table_new(); + + /* initialize these special pointers as early as possible */ + ptr_table_store(PL_ptr_table, &proto_perl->Isv_undef, &PL_sv_undef); + + SvANY(&PL_sv_no) = new_XPVNV(); + SvPV_set(&PL_sv_no, savepvn(PL_No, 0)); + SvCUR_set(&PL_sv_no, 0); + SvLEN_set(&PL_sv_no, 1); + SvIV_set(&PL_sv_no, 0); + SvNV_set(&PL_sv_no, 0); + ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no); + + SvPV_set(&PL_sv_yes, savepvn(PL_Yes, 1)); + SvCUR_set(&PL_sv_yes, 1); + SvLEN_set(&PL_sv_yes, 2); + SvIV_set(&PL_sv_yes, 1); + SvNV_set(&PL_sv_yes, 1); + ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes); + + /* create (a non-shared!) shared string table */ + PL_strtab = newHV(); + HvSHAREKEYS_off(PL_strtab); + hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab)); + ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab); + + /* These two PVs will be free'd special way so must set them same way op.c does */ + PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv); + ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, PL_compiling.cop_stashpv); + + PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file); + ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file); + + ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling); + PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings); + CopHINTHASH_set(&PL_compiling, cophh_copy(CopHINTHASH_get(&PL_compiling))); + PL_curcop = (COP*)any_dup(proto_perl->Icurcop, proto_perl); + + param->stashes = newAV(); /* Setup array of objects to call clone on */ + /* This makes no difference to the implementation, as it always pushes + and shifts pointers to other SVs without changing their reference + count, with the array becoming empty before it is freed. However, it + makes it conceptually clear what is going on, and will avoid some + work inside av.c, filling slots between AvFILL() and AvMAX() with + &PL_sv_undef, and SvREFCNT_dec()ing those. */ + AvREAL_off(param->stashes); + + if (!(flags & CLONEf_COPY_STACKS)) { + param->unreferenced = newAV(); + } + +#ifdef PERLIO_LAYERS + /* Clone PerlIO tables as soon as we can handle general xx_dup() */ + 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_origfilename = SAVEPV(proto_perl->Iorigfilename); + PL_diehook = sv_dup_inc(proto_perl->Idiehook, param); + PL_warnhook = sv_dup_inc(proto_perl->Iwarnhook, param); + + /* switches */ + PL_patchlevel = sv_dup_inc(proto_perl->Ipatchlevel, param); + PL_apiversion = sv_dup_inc(proto_perl->Iapiversion, param); + PL_inplace = SAVEPV(proto_perl->Iinplace); + PL_e_script = sv_dup_inc(proto_perl->Ie_script, param); + + /* magical thingies */ + PL_formfeed = sv_dup(proto_perl->Iformfeed, param); + + PL_encoding = sv_dup(proto_perl->Iencoding, param); + + 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. */ + + + /* Clone the regex array */ + /* ORANGE FIXME for plugins, probably in the SV dup code. + newSViv(PTR2IV(CALLREGDUPE( + INT2PTR(REGEXP *, SvIVX(regex)), param)))) + */ + PL_regex_padav = av_dup_inc(proto_perl->Iregex_padav, param); + PL_regex_pad = AvARRAY(PL_regex_padav); + + /* shortcuts to various I/O objects */ + PL_ofsgv = gv_dup_inc(proto_perl->Iofsgv, param); + 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_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); + + /* 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_DBsingle = sv_dup(proto_perl->IDBsingle, param); + PL_DBtrace = sv_dup(proto_perl->IDBtrace, param); + PL_DBsignal = sv_dup(proto_perl->IDBsignal, param); + + /* symbol tables */ + PL_defstash = hv_dup_inc(proto_perl->Idefstash, param); + PL_curstash = hv_dup(proto_perl->Icurstash, param); + PL_debstash = hv_dup(proto_perl->Idebstash, param); + PL_globalstash = hv_dup(proto_perl->Iglobalstash, param); + PL_curstname = sv_dup_inc(proto_perl->Icurstname, param); + + PL_beginav = av_dup_inc(proto_perl->Ibeginav, param); + PL_beginav_save = av_dup_inc(proto_perl->Ibeginav_save, param); + PL_checkav_save = av_dup_inc(proto_perl->Icheckav_save, param); + PL_unitcheckav = av_dup_inc(proto_perl->Iunitcheckav, param); + PL_unitcheckav_save = av_dup_inc(proto_perl->Iunitcheckav_save, param); + PL_endav = av_dup_inc(proto_perl->Iendav, param); + PL_checkav = av_dup_inc(proto_perl->Icheckav, param); + PL_initav = av_dup_inc(proto_perl->Iinitav, param); + + PL_isarev = hv_dup_inc(proto_perl->Iisarev, param); + + /* subprocess state */ + PL_fdpid = av_dup_inc(proto_perl->Ifdpid, param); + + if (proto_perl->Iop_mask) + PL_op_mask = SAVEPVN(proto_perl->Iop_mask, PL_maxo); + else + PL_op_mask = NULL; + /* PL_asserting = proto_perl->Iasserting; */ + + /* current interpreter roots */ + PL_main_cv = cv_dup_inc(proto_perl->Imain_cv, param); + OP_REFCNT_LOCK; + PL_main_root = OpREFCNT_inc(proto_perl->Imain_root); + OP_REFCNT_UNLOCK; + + /* runtime control stuff */ + PL_curcopdb = (COP*)any_dup(proto_perl->Icurcopdb, proto_perl); + + PL_preambleav = av_dup_inc(proto_perl->Ipreambleav, param); + + PL_ors_sv = sv_dup_inc(proto_perl->Iors_sv, param); + + /* interpreter atexit processing */ + PL_exitlistlen = proto_perl->Iexitlistlen; + if (PL_exitlistlen) { + Newx(PL_exitlist, PL_exitlistlen, PerlExitListEntry); + Copy(proto_perl->Iexitlist, PL_exitlist, PL_exitlistlen, PerlExitListEntry); + } + else + PL_exitlist = (PerlExitListEntry*)NULL; + + PL_my_cxt_size = proto_perl->Imy_cxt_size; + if (PL_my_cxt_size) { + Newx(PL_my_cxt_list, PL_my_cxt_size, void *); Copy(proto_perl->Imy_cxt_list, PL_my_cxt_list, PL_my_cxt_size, void *); #ifdef PERL_GLOBAL_STRUCT_PRIVATE Newx(PL_my_cxt_keys, PL_my_cxt_size, const char *); @@ -13027,8 +13184,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_custom_op_descs = hv_dup_inc(proto_perl->Icustom_op_descs,param); PL_custom_ops = hv_dup_inc(proto_perl->Icustom_ops, param); - PL_profiledata = NULL; - PL_compcv = cv_dup(proto_perl->Icompcv, param); PAD_CLONE_VARS(proto_perl, param); @@ -13037,30 +13192,12 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, sys_intern_dup(&proto_perl->Isys_intern, &PL_sys_intern); #endif - /* more statics moved here */ - PL_generation = proto_perl->Igeneration; PL_DBcv = cv_dup(proto_perl->IDBcv, param); - PL_in_clean_objs = proto_perl->Iin_clean_objs; - PL_in_clean_all = proto_perl->Iin_clean_all; - - PL_uid = proto_perl->Iuid; - PL_euid = proto_perl->Ieuid; - PL_gid = proto_perl->Igid; - PL_egid = proto_perl->Iegid; - PL_nomemok = proto_perl->Inomemok; - PL_an = proto_perl->Ian; - PL_evalseq = proto_perl->Ievalseq; - PL_origenviron = proto_perl->Iorigenviron; /* XXX not quite right */ - PL_origalen = proto_perl->Iorigalen; #ifdef PERL_USES_PL_PIDSTATUS PL_pidstatus = newHV(); /* XXX flag for cloning? */ #endif PL_osname = SAVEPV(proto_perl->Iosname); - PL_sighandlerp = proto_perl->Isighandlerp; - - PL_runops = proto_perl->Irunops; - PL_parser = parser_dup(proto_perl->Iparser, param); /* XXX this only works if the saved cop has already been cloned */ @@ -13070,29 +13207,14 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, proto_perl); } - PL_subline = proto_perl->Isubline; PL_subname = sv_dup_inc(proto_perl->Isubname, param); -#ifdef FCRYPT - PL_cryptseen = proto_perl->Icryptseen; -#endif - - PL_hints = proto_perl->Ihints; - - PL_amagic_generation = proto_perl->Iamagic_generation; - #ifdef USE_LOCALE_COLLATE - PL_collation_ix = proto_perl->Icollation_ix; PL_collation_name = SAVEPV(proto_perl->Icollation_name); - PL_collation_standard = proto_perl->Icollation_standard; - PL_collxfrm_base = proto_perl->Icollxfrm_base; - PL_collxfrm_mult = proto_perl->Icollxfrm_mult; #endif /* USE_LOCALE_COLLATE */ #ifdef USE_LOCALE_NUMERIC PL_numeric_name = SAVEPV(proto_perl->Inumeric_name); - PL_numeric_standard = proto_perl->Inumeric_standard; - PL_numeric_local = proto_perl->Inumeric_local; PL_numeric_radix_sv = sv_dup_inc(proto_perl->Inumeric_radix_sv, param); #endif /* !USE_LOCALE_NUMERIC */ @@ -13128,50 +13250,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_utf8_xidstart = sv_dup_inc(proto_perl->Iutf8_xidstart, param); PL_utf8_idcont = sv_dup_inc(proto_perl->Iutf8_idcont, param); PL_utf8_xidcont = sv_dup_inc(proto_perl->Iutf8_xidcont, param); - PL_utf8_foldable = hv_dup_inc(proto_perl->Iutf8_foldable, param); + PL_utf8_foldable = sv_dup_inc(proto_perl->Iutf8_foldable, param); - /* Did the locale setup indicate UTF-8? */ - PL_utf8locale = proto_perl->Iutf8locale; - /* Unicode features (see perlrun/-C) */ - PL_unicode = proto_perl->Iunicode; - - /* Pre-5.8 signals control */ - PL_signals = proto_perl->Isignals; - - /* times() ticks per second */ - PL_clocktick = proto_perl->Iclocktick; - - /* Recursion stopper for PerlIO_find_layer */ - PL_in_load_module = proto_perl->Iin_load_module; - - /* sort() routine */ - PL_sort_RealCmp = proto_perl->Isort_RealCmp; - - /* Not really needed/useful since the reenrant_retint is "volatile", - * but do it for consistency's sake. */ - PL_reentrant_retint = proto_perl->Ireentrant_retint; - - /* Hooks to shared SVs and locks. */ - PL_sharehook = proto_perl->Isharehook; - PL_lockhook = proto_perl->Ilockhook; - PL_unlockhook = proto_perl->Iunlockhook; - PL_threadhook = proto_perl->Ithreadhook; - PL_destroyhook = proto_perl->Idestroyhook; - PL_signalhook = proto_perl->Isignalhook; - -#ifdef THREADS_HAVE_PIDS - PL_ppid = proto_perl->Ippid; -#endif - - /* swatch cache */ - PL_last_swash_hv = NULL; /* reinits on demand */ - PL_last_swash_klen = 0; - PL_last_swash_key[0]= '\0'; - PL_last_swash_tmps = (U8*)NULL; - PL_last_swash_slen = 0; - - PL_glob_index = proto_perl->Iglob_index; - PL_srand_called = proto_perl->Isrand_called; if (proto_perl->Ipsig_pend) { Newxz(PL_psig_pend, SIG_SIZE, int); @@ -13191,13 +13271,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_psig_name = (SV**)NULL; } - /* intrpvar.h stuff */ - if (flags & CLONEf_COPY_STACKS) { - /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */ - PL_tmps_ix = proto_perl->Itmps_ix; - PL_tmps_max = proto_perl->Itmps_max; - PL_tmps_floor = proto_perl->Itmps_floor; Newx(PL_tmps_stack, PL_tmps_max, SV*); sv_dup_inc_multiple(proto_perl->Itmps_stack, PL_tmps_stack, PL_tmps_ix+1, param); @@ -13214,8 +13288,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, /* next push_scope()/ENTER sets PL_scopestack[PL_scopestack_ix] * NOTE: unlike the others! */ - PL_scopestack_ix = proto_perl->Iscopestack_ix; - PL_scopestack_max = proto_perl->Iscopestack_max; Newxz(PL_scopestack, PL_scopestack_max, I32); Copy(proto_perl->Iscopestack, PL_scopestack, PL_scopestack_ix, I32); @@ -13236,10 +13308,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, - proto_perl->Istack_base); PL_stack_max = PL_stack_base + AvMAX(PL_curstack); - /* next SSPUSHFOO() sets PL_savestack[PL_savestack_ix] - * NOTE: unlike the others! */ - PL_savestack_ix = proto_perl->Isavestack_ix; - PL_savestack_max = proto_perl->Isavestack_max; /*Newxz(PL_savestack, PL_savestack_max, ANY);*/ PL_savestack = ss_dup(proto_perl, param); } @@ -13248,72 +13316,22 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, ENTER; /* perl_destruct() wants to LEAVE; */ } - PL_start_env = proto_perl->Istart_env; /* XXXXXX */ - PL_top_env = &PL_start_env; - - PL_op = proto_perl->Iop; - - PL_Sv = NULL; - PL_Xpv = (XPV*)NULL; - my_perl->Ina = proto_perl->Ina; - - PL_statbuf = proto_perl->Istatbuf; - PL_statcache = proto_perl->Istatcache; PL_statgv = gv_dup(proto_perl->Istatgv, param); PL_statname = sv_dup_inc(proto_perl->Istatname, param); -#ifdef HAS_TIMES - PL_timesbuf = proto_perl->Itimesbuf; -#endif - PL_tainted = proto_perl->Itainted; - PL_curpm = proto_perl->Icurpm; /* XXX No PMOP ref count */ PL_rs = sv_dup_inc(proto_perl->Irs, param); PL_last_in_gv = gv_dup(proto_perl->Ilast_in_gv, param); PL_defoutgv = gv_dup_inc(proto_perl->Idefoutgv, param); - PL_chopset = proto_perl->Ichopset; /* XXX never deallocated */ PL_toptarget = sv_dup_inc(proto_perl->Itoptarget, param); PL_bodytarget = sv_dup_inc(proto_perl->Ibodytarget, param); PL_formtarget = sv_dup(proto_perl->Iformtarget, param); - PL_restartjmpenv = proto_perl->Irestartjmpenv; - PL_restartop = proto_perl->Irestartop; - PL_in_eval = proto_perl->Iin_eval; - PL_delaymagic = proto_perl->Idelaymagic; - PL_phase = proto_perl->Iphase; - PL_localizing = proto_perl->Ilocalizing; - PL_errors = sv_dup_inc(proto_perl->Ierrors, param); - PL_hv_fetch_ent_mh = NULL; - PL_modcount = proto_perl->Imodcount; - PL_lastgotoprobe = NULL; - PL_dumpindent = proto_perl->Idumpindent; PL_sortcop = (OP*)any_dup(proto_perl->Isortcop, proto_perl); PL_sortstash = hv_dup(proto_perl->Isortstash, param); PL_firstgv = gv_dup(proto_perl->Ifirstgv, param); PL_secondgv = gv_dup(proto_perl->Isecondgv, param); - PL_efloatbuf = NULL; /* reinits on demand */ - PL_efloatsize = 0; /* reinits on demand */ - - /* regex stuff */ - - PL_screamfirst = NULL; - PL_screamnext = NULL; - PL_maxscream = -1; /* reinits on demand */ - PL_lastscream = NULL; - - - PL_regdummy = proto_perl->Iregdummy; - PL_colorset = 0; /* reinits PL_colors[] */ - /*PL_colors[6] = {0,0,0,0,0,0};*/ - - - - /* Pluggable optimizer */ - PL_peepp = proto_perl->Ipeepp; - PL_rpeepp = proto_perl->Irpeepp; - /* op_free() hook */ - PL_opfreehook = proto_perl->Iopfreehook; PL_stashcache = newHV(); @@ -13535,6 +13553,14 @@ Perl_sv_recode_to_utf8(pTHX_ SV *sv, SV *encoding) } FREETMPS; LEAVE; + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { + /* clear pos and any utf8 cache */ + MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global); + if (mg) + mg->mg_len = -1; + if ((mg = mg_find(sv, PERL_MAGIC_utf8))) + magic_setutf8(sv,mg); /* clear UTF8 cache */ + } SvUTF8_on(sv); return SvPVX(sv); } @@ -13826,21 +13852,20 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, break; return varname(gv, '$', 0, NULL, 0, FUV_SUBSCRIPT_NONE); - case OP_AELEMFAST: - if (obase->op_flags & OPf_SPECIAL) { /* lexical array */ - if (match) { - SV **svp; - AV *av = MUTABLE_AV(PAD_SV(obase->op_targ)); - if (!av || SvRMAGICAL(av)) - break; - svp = av_fetch(av, (I32)obase->op_private, FALSE); - if (!svp || *svp != uninit_sv) - break; - } - return varname(NULL, '$', obase->op_targ, - NULL, (I32)obase->op_private, FUV_SUBSCRIPT_ARRAY); + case OP_AELEMFAST_LEX: + if (match) { + SV **svp; + AV *av = MUTABLE_AV(PAD_SV(obase->op_targ)); + if (!av || SvRMAGICAL(av)) + break; + svp = av_fetch(av, (I32)obase->op_private, FALSE); + if (!svp || *svp != uninit_sv) + break; } - else { + return varname(NULL, '$', obase->op_targ, + NULL, (I32)obase->op_private, FUV_SUBSCRIPT_ARRAY); + case OP_AELEMFAST: + { gv = cGVOPx_gv(obase); if (!gv) break;