X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=ee78fbcbbe450133538fa873d518fbc1bb3d7812;hb=efe15bf0980629945e70e47a4eaaffc5bdc49b7d;hp=a22316c72a1c119879feb08ca352a45d5cb06785;hpb=b0b93b3c773176a99136baa97661d11503277415;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index a22316c..ee78fbc 100644 --- a/sv.c +++ b/sv.c @@ -1185,13 +1185,22 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type) PERL_ARGS_ASSERT_SV_UPGRADE; + if (old_type == new_type) + return; + + /* This clause was purposefully added ahead of the early return above to + the shared string hackery for (sort {$a <=> $b} keys %hash), with the + inference by Nick I-S that it would fix other troublesome cases. See + changes 7162, 7163 (f130fd4589cf5fbb24149cd4db4137c8326f49c1 and parent) + + Given that shared hash key scalars are no longer PVIV, but PV, there is + no longer need to unshare so as to free up the IVX slot for its proper + purpose. So it's safe to move the early return earlier. */ + if (new_type != SVt_PV && SvIsCOW(sv)) { sv_force_normal_flags(sv, 0); } - if (old_type == new_type) - return; - old_body = SvANY(sv); /* Copying structures onto other structures that have been neatly zeroed @@ -1421,8 +1430,22 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type) SvNV_set(sv, 0); #endif - if (new_type == SVt_PVIO) + if (new_type == SVt_PVIO) { + IO * const io = MUTABLE_IO(sv); + GV *iogv = gv_fetchpvs("FileHandle::", 0, SVt_PVHV); + + SvOBJECT_on(io); + /* Clear the stashcache because a new IO could overrule a package + name */ + hv_clear(PL_stashcache); + + /* unless exists($main::{FileHandle}) and + defined(%main::FileHandle::) */ + if (!(iogv && GvHV(iogv) && HvARRAY(GvHV(iogv)))) + iogv = gv_fetchpvs("IO::Handle::", GV_ADD, SVt_PVHV); + SvSTASH_set(io, MUTABLE_HV(SvREFCNT_inc(GvHV(iogv)))); IoPAGE_LEN(sv) = 60; + } if (old_type < SVt_PV) { /* referant will be NULL unless the old type was SVt_IV emulating SVt_RV */ @@ -5073,8 +5096,6 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, case PERL_MAGIC_qr: vtable = &PL_vtbl_regexp; break; - case PERL_MAGIC_hints: - /* As this vtable is all NULL, we can reuse it. */ case PERL_MAGIC_sig: vtable = &PL_vtbl_sig; break; @@ -5117,6 +5138,9 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, 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. */ @@ -7274,7 +7298,7 @@ Perl_sv_inc(pTHX_ register SV *const sv) d = SvPVX(sv); while (isALPHA(*d)) d++; while (isDIGIT(*d)) d++; - if (*d) { + if (d < SvEND(sv)) { #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 @@ -7474,6 +7498,16 @@ Perl_sv_dec(pTHX_ register SV *const sv) sv_setnv(sv,Atof(SvPVX_const(sv)) - 1.0); /* punt */ } +/* this define is used to eliminate a chunk of duplicated but shared logic + * it has the suffix __SV_C to signal that it isnt API, and isnt meant to be + * used anywhere but here - yves + */ +#define PUSH_EXTEND_MORTAL__SV_C(AnSv) \ + STMT_START { \ + EXTEND_MORTAL(1); \ + PL_tmps_stack[++PL_tmps_ix] = (AnSv); \ + } STMT_END + /* =for apidoc sv_mortalcopy @@ -7498,8 +7532,7 @@ Perl_sv_mortalcopy(pTHX_ SV *const oldstr) new_SV(sv); sv_setsv(sv,oldstr); - EXTEND_MORTAL(1); - PL_tmps_stack[++PL_tmps_ix] = sv; + PUSH_EXTEND_MORTAL__SV_C(sv); SvTEMP_on(sv); return sv; } @@ -7523,8 +7556,7 @@ Perl_sv_newmortal(pTHX) new_SV(sv); SvFLAGS(sv) = SVs_TEMP; - EXTEND_MORTAL(1); - PL_tmps_stack[++PL_tmps_ix] = sv; + PUSH_EXTEND_MORTAL__SV_C(sv); return sv; } @@ -7558,8 +7590,22 @@ Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags assert(!(flags & ~(SVf_UTF8|SVs_TEMP))); new_SV(sv); sv_setpvn(sv,s,len); - SvFLAGS(sv) |= (flags & SVf_UTF8); - return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; + + /* This code used to a sv_2mortal(), however we now unroll the call to sv_2mortal() + * and do what it does outselves 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 + * eleminate quite a few steps than it looks - Yves (explaining patch by gfx) + */ + + SvFLAGS(sv) |= flags; + + if(flags & SVs_TEMP){ + PUSH_EXTEND_MORTAL__SV_C(sv); + } + + return sv; } /* @@ -7582,8 +7628,7 @@ Perl_sv_2mortal(pTHX_ register SV *const sv) return NULL; if (SvREADONLY(sv) && SvIMMORTAL(sv)) return sv; - EXTEND_MORTAL(1); - PL_tmps_stack[++PL_tmps_ix] = sv; + PUSH_EXTEND_MORTAL__SV_C(sv); SvTEMP_on(sv); return sv; } @@ -12123,7 +12168,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, /* utf8 character classes */ PL_utf8_alnum = sv_dup_inc(proto_perl->Iutf8_alnum, param); - PL_utf8_alnumc = sv_dup_inc(proto_perl->Iutf8_alnumc, param); PL_utf8_ascii = sv_dup_inc(proto_perl->Iutf8_ascii, param); PL_utf8_alpha = sv_dup_inc(proto_perl->Iutf8_alpha, param); PL_utf8_space = sv_dup_inc(proto_perl->Iutf8_space, param); @@ -12264,8 +12308,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, SV * const nsv = MUTABLE_SV(ptr_table_fetch(PL_ptr_table, proto_perl->Itmps_stack[i])); if (nsv && !SvREFCNT(nsv)) { - EXTEND_MORTAL(1); - PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple(nsv); + PUSH_EXTEND_MORTAL__SV_C(SvREFCNT_inc_simple(nsv)); } } }