X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=d2eed0d4a39277cd978540add3798bf181791bf8;hb=1e73acc8af3eecb1b36ee831483e1e9a7b3d1662;hp=b27865698f2f3e79c93764978474d2a7532b5bb5;hpb=19f6321d25d193c964d4da055e9f739f63de1dc6;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index b278656..d2eed0d 100644 --- a/sv.c +++ b/sv.c @@ -35,13 +35,13 @@ * lib/utf8.t lib/Unicode/Collate/t/index.t * --jhi */ -#define ASSERT_UTF8_CACHE(cache) \ +# define ASSERT_UTF8_CACHE(cache) \ STMT_START { if (cache) { assert((cache)[0] <= (cache)[1]); \ assert((cache)[2] <= (cache)[3]); \ assert((cache)[3] <= (cache)[1]);} \ } STMT_END #else -#define ASSERT_UTF8_CACHE(cache) NOOP +# define ASSERT_UTF8_CACHE(cache) NOOP #endif #ifdef PERL_OLD_COPY_ON_WRITE @@ -678,6 +678,7 @@ Perl_sv_free_arenas(pTHX) void* Perl_get_arena(pTHX_ int arena_size) { + dVAR; struct arena_desc* adesc; struct arena_set *newroot, **aroot = (struct arena_set**) &PL_body_arenas; int curr; @@ -692,7 +693,7 @@ Perl_get_arena(pTHX_ int arena_size) newroot->set_size = ARENAS_PER_SET; newroot->next = *aroot; *aroot = newroot; - DEBUG_m(PerlIO_printf(Perl_debug_log, "new arenaset %p\n", *aroot)); + DEBUG_m(PerlIO_printf(Perl_debug_log, "new arenaset %p\n", (void*)*aroot)); } /* ok, now have arena-set with at least 1 empty/available arena-desc */ @@ -1065,8 +1066,9 @@ S_more_bodies (pTHX_ svtype sv_type) /* computed count doesnt reflect the 1st slot reservation */ DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %p end %p arena-size %d type %d size %d ct %d\n", - start, end, bdp->arena_size, sv_type, body_size, - bdp->arena_size / body_size)); + start, end, + (int)bdp->arena_size, sv_type, (int)body_size, + (int)bdp->arena_size / (int)body_size)); *root = (void *)start; @@ -1118,12 +1120,12 @@ You generally want to use the C macro wrapper. See also C. */ void -Perl_sv_upgrade(pTHX_ register SV *sv, U32 new_type) +Perl_sv_upgrade(pTHX_ register SV *sv, svtype new_type) { dVAR; void* old_body; void* new_body; - const U32 old_type = SvTYPE(sv); + const svtype old_type = SvTYPE(sv); const struct body_details *new_type_details; const struct body_details *const old_type_details = bodies_by_type + old_type; @@ -1494,6 +1496,7 @@ Perl_sv_setiv(pTHX_ register SV *sv, IV i) case SVt_PVIO: Perl_croak(aTHX_ "Can't coerce %s to integer in %s", sv_reftype(sv,0), OP_DESC(PL_op)); + default: NOOP; } (void)SvIOK_only(sv); /* validate number */ SvIV_set(sv, i); @@ -1594,6 +1597,7 @@ Perl_sv_setnv(pTHX_ register SV *sv, NV num) case SVt_PVIO: Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0), OP_NAME(PL_op)); + default: NOOP; } SvNV_set(sv, num); (void)SvNOK_only(sv); /* validate number */ @@ -1751,7 +1755,9 @@ S_glob_2pv(pTHX_ GV * const gv, STRLEN * const len) SvFLAGS(gv) |= wasfake; assert(SvPOK(buffer)); - *len = SvCUR(buffer); + if (len) { + *len = SvCUR(buffer); + } return SvPVX(buffer); } @@ -2063,7 +2069,7 @@ S_sv_2iuv_common(pTHX_ SV *sv) { if ((NV)(SvIVX(sv)) == SvNVX(sv)) { SvIOK_on(sv); } else { - /*EMPTY*/; /* Integer is imprecise. NOK, IOKp */ + NOOP; /* Integer is imprecise. NOK, IOKp */ } /* UV will not work better than IV */ } else { @@ -2078,7 +2084,7 @@ S_sv_2iuv_common(pTHX_ SV *sv) { if ((NV)(SvUVX(sv)) == SvNVX(sv)) { SvIOK_on(sv); } else { - /*EMPTY*/; /* Integer is imprecise. NOK, IOKp, is UV */ + NOOP; /* Integer is imprecise. NOK, IOKp, is UV */ } } SvIsUV_on(sv); @@ -2123,7 +2129,7 @@ S_sv_2iuv_common(pTHX_ SV *sv) { } else { if (isGV_with_GP(sv)) - return PTR2IV(glob_2number((GV *)sv)); + return glob_2number((GV *)sv); if (!(SvFLAGS(sv) & SVs_PADTMP)) { if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) @@ -2656,8 +2662,9 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags) STRLEN len; if (SvIOKp(sv)) { - len = SvIsUV(sv) ? my_sprintf(tbuf,"%"UVuf, (UV)SvUVX(sv)) - : my_sprintf(tbuf,"%"IVdf, (IV)SvIVX(sv)); + len = SvIsUV(sv) + ? my_snprintf(tbuf, sizeof(tbuf), "%"UVuf, (UV)SvUVX(sv)) + : my_snprintf(tbuf, sizeof(tbuf), "%"IVdf, (IV)SvIVX(sv)); } else { Gconvert(SvNVX(sv), NV_DIG, 0, tbuf); len = strlen(tbuf); @@ -3091,13 +3098,13 @@ flag off so that it looks like octets again. void Perl_sv_utf8_encode(pTHX_ register SV *sv) { - (void) sv_utf8_upgrade(sv); if (SvIsCOW(sv)) { sv_force_normal_flags(sv, 0); } if (SvREADONLY(sv)) { Perl_croak(aTHX_ PL_no_modify); } + (void) sv_utf8_upgrade(sv); SvUTF8_off(sv); } @@ -3294,7 +3301,7 @@ S_glob_assign_ref(pTHX_ SV *dstr, SV *sstr) { it was a const and its value changed. */ if (CvCONST(cv) && CvCONST((CV*)sref) && cv_const_sv(cv) == cv_const_sv((CV*)sref)) { - /*EMPTY*/ + NOOP; /* They are 2 constant subroutines generated from the same constant. This probably means that they are really the "same" proxy subroutine @@ -3343,7 +3350,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags) dVAR; register U32 sflags; register int dtype; - register int stype; + register svtype stype; if (sstr == dstr) return; @@ -3478,7 +3485,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags) if (stype == SVt_PVLV) SvUPGRADE(dstr, SVt_PVNV); else - SvUPGRADE(dstr, (U32)stype); + SvUPGRADE(dstr, (svtype)stype); } /* dstr may have been upgraded. */ @@ -3671,7 +3678,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags) SvFLAGS(dstr) |= sflags & (SVf_IOK|SVp_IOK|SVf_NOK|SVp_NOK|SVf_UTF8 |SVf_AMAGIC); { - const MAGIC * const smg = SvVOK(sstr); + const MAGIC * const smg = SvVSTRING_mg(sstr); if (smg) { sv_magic(dstr, NULL, PERL_MAGIC_vstring, smg->mg_ptr, smg->mg_len); @@ -4637,7 +4644,8 @@ Perl_sv_unmagic(pTHX_ SV *sv, int type) Weaken a reference: set the C flag on this RV; give the referred-to SV C magic if it hasn't already; and push a back-reference to this RV onto the array of backreferences -associated with that magic. +associated with that magic. If the RV is magical, set magic will be +called after the RV is cleared. =cut */ @@ -4790,6 +4798,7 @@ Perl_sv_kill_backrefs(pTHX_ SV *sv, AV *av) SvRV_set(referrer, 0); SvOK_off(referrer); SvWEAKREF_off(referrer); + SvSETMAGIC(referrer); } else if (SvTYPE(referrer) == SVt_PVGV || SvTYPE(referrer) == SVt_PVLV) { /* You lookin' at me? */ @@ -5070,10 +5079,8 @@ Perl_sv_clear(pTHX_ register SV *sv) } } if (type >= SVt_PVMG) { - HV *ourstash; - if ((type == SVt_PVMG || type == SVt_PVGV) && - (ourstash = OURSTASH(sv))) { - SvREFCNT_dec(ourstash); + if ((type == SVt_PVMG || type == SVt_PVGV) && SvPAD_OUR(sv)) { + SvREFCNT_dec(OURSTASH(sv)); } else if (SvMAGIC(sv)) mg_free(sv); if (type == SVt_PVMG && SvPAD_TYPED(sv)) @@ -5342,7 +5349,7 @@ Perl_sv_len_utf8(pTHX_ register SV *sv) PL_utf8cache = 0; Perl_croak(aTHX_ "panic: sv_len_utf8 cache %"UVf " real %"UVf" for %"SVf, - (UV) ulen, (UV) real, sv); + (UV) ulen, (UV) real, (void*)sv); } } } @@ -5366,13 +5373,11 @@ Perl_sv_len_utf8(pTHX_ register SV *sv) /* Walk forwards to find the byte corresponding to the passed in UTF-8 offset. */ static STRLEN -S_sv_pos_u2b_forwards(pTHX_ const U8 *const start, const U8 *const send, +S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send, STRLEN uoffset) { const U8 *s = start; - PERL_UNUSED_CONTEXT; - while (s < send && uoffset--) s += UTF8SKIP(s); if (s > send) { @@ -5387,7 +5392,7 @@ S_sv_pos_u2b_forwards(pTHX_ const U8 *const start, const U8 *const send, whether to walk forwards or backwards to find the byte corresponding to the passed in UTF-8 offset. */ static STRLEN -S_sv_pos_u2b_midway(pTHX_ const U8 *const start, const U8 *send, +S_sv_pos_u2b_midway(const U8 *const start, const U8 *send, STRLEN uoffset, STRLEN uend) { STRLEN backw = uend - uoffset; @@ -5395,7 +5400,7 @@ S_sv_pos_u2b_midway(pTHX_ const U8 *const start, const U8 *send, /* The assumption is that going forwards is twice the speed of going forward (that's where the 2 * backw comes from). (The real figure of course depends on the UTF-8 data.) */ - return S_sv_pos_u2b_forwards(aTHX_ start, send, uoffset); + return sv_pos_u2b_forwards(start, send, uoffset); } while (backw--) { @@ -5446,12 +5451,12 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start, if ((*mgp)->mg_len != -1) { /* And we know the end too. */ boffset = boffset0 - + S_sv_pos_u2b_midway(aTHX_ start + boffset0, send, + + sv_pos_u2b_midway(start + boffset0, send, uoffset - uoffset0, (*mgp)->mg_len - uoffset0); } else { boffset = boffset0 - + S_sv_pos_u2b_forwards(aTHX_ start + boffset0, + + sv_pos_u2b_forwards(start + boffset0, send, uoffset - uoffset0); } } @@ -5464,13 +5469,13 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start, } boffset = boffset0 - + S_sv_pos_u2b_midway(aTHX_ start + boffset0, + + sv_pos_u2b_midway(start + boffset0, start + cache[1], uoffset - uoffset0, cache[0] - uoffset0); } else { boffset = boffset0 - + S_sv_pos_u2b_midway(aTHX_ start + boffset0, + + sv_pos_u2b_midway(start + boffset0, start + cache[3], uoffset - uoffset0, cache[2] - uoffset0); @@ -5482,7 +5487,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start, /* In fact, offset0 is either 0, or less than offset, so don't need to worry about the other possibility. */ boffset = boffset0 - + S_sv_pos_u2b_midway(aTHX_ start + boffset0, send, + + sv_pos_u2b_midway(start + boffset0, send, uoffset - uoffset0, (*mgp)->mg_len - uoffset0); found = TRUE; @@ -5491,7 +5496,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start, if (!found || PL_utf8cache < 0) { const STRLEN real_boffset - = boffset0 + S_sv_pos_u2b_forwards(aTHX_ start + boffset0, + = boffset0 + sv_pos_u2b_forwards(start + boffset0, send, uoffset - uoffset0); if (found && PL_utf8cache < 0) { @@ -5502,7 +5507,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *sv, MAGIC **mgp, const U8 *const start, PL_utf8cache = 0; Perl_croak(aTHX_ "panic: sv_pos_u2b_cache cache %"UVf " real %"UVf" for %"SVf, - (UV) boffset, (UV) real_boffset, sv); + (UV) boffset, (UV) real_boffset, (void*)sv); } } boffset = real_boffset; @@ -5546,16 +5551,16 @@ Perl_sv_pos_u2b(pTHX_ register SV *sv, I32* offsetp, I32* lenp) STRLEN uoffset = (STRLEN) *offsetp; const U8 * const send = start + len; MAGIC *mg = NULL; - STRLEN boffset = S_sv_pos_u2b_cached(aTHX_ sv, &mg, start, send, + const STRLEN boffset = sv_pos_u2b_cached(sv, &mg, start, send, uoffset, 0, 0); *offsetp = (I32) boffset; if (lenp) { /* Convert the relative offset to absolute. */ - STRLEN uoffset2 = uoffset + (STRLEN) *lenp; - STRLEN boffset2 - = S_sv_pos_u2b_cached(aTHX_ sv, &mg, start, send, uoffset2, + const STRLEN uoffset2 = uoffset + (STRLEN) *lenp; + const STRLEN boffset2 + = sv_pos_u2b_cached(sv, &mg, start, send, uoffset2, uoffset, boffset) - boffset; *lenp = boffset2; @@ -5635,7 +5640,7 @@ S_utf8_mg_pos_cache_update(pTHX_ SV *sv, MAGIC **mgp, STRLEN byte, STRLEN utf8, SAVEI8(PL_utf8cache); PL_utf8cache = 0; Perl_croak(aTHX_ "panic: utf8_mg_pos_cache_update cache %"UVf - " real %"UVf" for %"SVf, (UV) utf8, (UV) realutf8, sv); + " real %"UVf" for %"SVf, (UV) utf8, (UV) realutf8, (void*)sv); } } @@ -5882,7 +5887,7 @@ Perl_sv_pos_b2u(pTHX_ register SV* sv, I32* offsetp) PL_utf8cache = 0; Perl_croak(aTHX_ "panic: sv_pos_b2u cache %"UVf " real %"UVf" for %"SVf, - (UV) len, (UV) real_len, sv); + (UV) len, (UV) real_len, (void*)sv); } } len = real_len; @@ -6528,7 +6533,7 @@ screamer2: * * - jik 9/25/96 */ - if (!(cnt < sizeof(buf) && PerlIO_eof(fp))) + if (!(cnt < (I32)sizeof(buf) && PerlIO_eof(fp))) goto screamer2; } @@ -6978,12 +6983,15 @@ Perl_newSVhek(pTHX_ const HEK *hek) SvUTF8_on (sv); Safefree (as_utf8); /* bytes_to_utf8() allocates a new string */ return sv; - } else if (flags & HVhek_REHASH) { + } else if (flags & (HVhek_REHASH|HVhek_UNSHARED)) { /* We don't have a pointer to the hv, so we have to replicate the flag into every HEK. This hv is using custom a hasing algorithm. Hence we can't return a shared string scalar, as that would contain the (wrong) hash value, and might get passed - into an hv routine with a regular hash */ + into an hv routine with a regular hash. + Similarly, a hash that isn't using shared hash keys has to have + the flag in every key so that we know not to try to call + share_hek_kek on it. */ SV * const sv = newSVpvn (HEK_KEY(hek), HEK_LEN(hek)); if (HEK_UTF8(hek)) @@ -7365,7 +7373,7 @@ Perl_sv_2io(pTHX_ SV *sv) else io = 0; if (!io) - Perl_croak(aTHX_ "Bad filehandle: %"SVf, sv); + Perl_croak(aTHX_ "Bad filehandle: %"SVf, (void*)sv); break; } return io; @@ -7457,7 +7465,7 @@ Perl_sv_2cv(pTHX_ SV *sv, HV **st, GV **gvp, I32 lref) LEAVE; if (!GvCVu(gv)) Perl_croak(aTHX_ "Unable to create sub named \"%"SVf"\"", - sv); + (void*)sv); } return GvCVu(gv); } @@ -9011,18 +9019,19 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV integer: { char *ptr = ebuf + sizeof ebuf; + bool tempalt = uv ? alt : FALSE; /* Vectors can't change alt */ + zeros = 0; + switch (base) { unsigned dig; case 16: - if (!uv) - alt = FALSE; p = (char*)((c == 'X') ? "0123456789ABCDEF" : "0123456789abcdef"); do { dig = uv & 15; *--ptr = p[dig]; } while (uv >>= 4); - if (alt) { + if (tempalt) { esignbuf[esignlen++] = '0'; esignbuf[esignlen++] = c; /* 'x' or 'X' */ } @@ -9036,13 +9045,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV *--ptr = '0'; break; case 2: - if (!uv) - alt = FALSE; do { dig = uv & 1; *--ptr = '0' + dig; } while (uv >>= 1); - if (alt) { + if (tempalt) { esignbuf[esignlen++] = '0'; esignbuf[esignlen++] = 'b'; } @@ -9262,8 +9269,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV * --jhi */ #if defined(HAS_LONG_DOUBLE) elen = ((intsize == 'q') - ? my_sprintf(PL_efloatbuf, ptr, nv) - : my_sprintf(PL_efloatbuf, ptr, (double)nv)); + ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv) + : my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv)); #else elen = my_sprintf(PL_efloatbuf, ptr, nv); #endif @@ -9314,7 +9321,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV (UV)c & 0xFF); } else sv_catpvs(msg, "end of string"); - Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%"SVf, msg); /* yes, this is reentrant */ + Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%"SVf, (void*)msg); /* yes, this is reentrant */ } /* output mangled stuff ... */ @@ -9334,27 +9341,29 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV continue; /* not "break" */ } - /* calculate width before utf8_upgrade changes it */ + if (is_utf8 != has_utf8) { + if (is_utf8) { + if (SvCUR(sv)) + sv_utf8_upgrade(sv); + } + else { + const STRLEN old_elen = elen; + SV * const nsv = sv_2mortal(newSVpvn(eptr, elen)); + sv_utf8_upgrade(nsv); + eptr = SvPVX_const(nsv); + elen = SvCUR(nsv); + + if (width) { /* fudge width (can't fudge elen) */ + width += elen - old_elen; + } + is_utf8 = TRUE; + } + } + have = esignlen + zeros + elen; if (have < zeros) Perl_croak_nocontext(PL_memory_wrap); - if (is_utf8 != has_utf8) { - if (is_utf8) { - if (SvCUR(sv)) - sv_utf8_upgrade(sv); - } - else { - SV * const nsv = sv_2mortal(newSVpvn(eptr, elen)); - sv_utf8_upgrade(nsv); - eptr = SvPVX_const(nsv); - elen = SvCUR(nsv); - } - SvGROW(sv, SvCUR(sv) + elen + 1); - p = SvEND(sv); - *p = '\0'; - } - need = (have > width ? have : width); gap = need - have; @@ -9535,6 +9544,17 @@ Perl_re_dup(pTHX_ const REGEXP *r, CLONE_PARAMS *param) ((reg_trie_data*)d->data[i])->refcount++; OP_REFCNT_UNLOCK; break; + case 'T': + d->data[i] = r->data->data[i]; + OP_REFCNT_LOCK; + ((reg_ac_data*)d->data[i])->refcount++; + OP_REFCNT_UNLOCK; + /* Trie stclasses are readonly and can thus be shared + * without duplication. We free the stclass in pregfree + * when the corresponding reg_ac_data struct is freed. + */ + ret->regstclass= r->regstclass; + break; default: Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'", r->data->what[i]); } @@ -9635,7 +9655,7 @@ Perl_gp_dup(pTHX_ GP *gp, CLONE_PARAMS* param) ret->gp_cv = cv_dup_inc(gp->gp_cv, param); ret->gp_cvgen = gp->gp_cvgen; ret->gp_line = gp->gp_line; - ret->gp_file = gp->gp_file; /* points to COP.cop_file */ + ret->gp_file_hek = hek_dup(gp->gp_file_hek, param); return ret; } @@ -9986,7 +10006,7 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param) case SVt_PVGV: if (GvUNIQUE((GV*)sstr)) { - /*EMPTY*/; /* Do sharing here, and fall through */ + NOOP; /* Do sharing here, and fall through */ } case SVt_PVIO: case SVt_PVFM: @@ -10031,9 +10051,8 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param) missing by always going for the destination. FIXME - instrument and check that assumption */ if (sv_type >= SVt_PVMG) { - HV *ourstash; - if ((sv_type == SVt_PVMG) && (ourstash = OURSTASH(dstr))) { - OURSTASH_set(dstr, hv_dup_inc(ourstash, param)); + if ((sv_type == SVt_PVMG) && SvPAD_OUR(dstr)) { + OURSTASH_set(dstr, hv_dup_inc(OURSTASH(dstr), param)); } else if (SvMAGIC(dstr)) SvMAGIC_set(dstr, mg_dup(SvMAGIC(dstr), param)); if (SvSTASH(dstr)) @@ -10097,7 +10116,7 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param) if (IoDIRP(dstr)) { IoDIRP(dstr) = dirp_dup(IoDIRP(dstr)); } else { - /*EMPTY*/; + NOOP; /* IoDIRP(dstr) is already a copy of IoDIRP(sstr) */ } } @@ -10134,55 +10153,49 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param) } break; case SVt_PVHV: - { - HEK *hvname = NULL; - - if (HvARRAY((HV*)sstr)) { - STRLEN i = 0; - const bool sharekeys = !!HvSHAREKEYS(sstr); - XPVHV * const dxhv = (XPVHV*)SvANY(dstr); - XPVHV * const sxhv = (XPVHV*)SvANY(sstr); - char *darray; - Newx(darray, PERL_HV_ARRAY_ALLOC_BYTES(dxhv->xhv_max+1) - + (SvOOK(sstr) ? sizeof(struct xpvhv_aux) : 0), - char); - HvARRAY(dstr) = (HE**)darray; - while (i <= sxhv->xhv_max) { - const HE *source = HvARRAY(sstr)[i]; - HvARRAY(dstr)[i] = source - ? he_dup(source, sharekeys, param) : 0; - ++i; - } - if (SvOOK(sstr)) { - struct xpvhv_aux * const saux = HvAUX(sstr); - struct xpvhv_aux * const daux = HvAUX(dstr); - /* This flag isn't copied. */ - /* SvOOK_on(hv) attacks the IV flags. */ - SvFLAGS(dstr) |= SVf_OOK; - - hvname = saux->xhv_name; - daux->xhv_name - = hvname ? hek_dup(hvname, param) : hvname; - - daux->xhv_riter = saux->xhv_riter; - daux->xhv_eiter = saux->xhv_eiter - ? he_dup(saux->xhv_eiter, - (bool)!!HvSHAREKEYS(sstr), param) : 0; - daux->xhv_backreferences = saux->xhv_backreferences + if (HvARRAY((HV*)sstr)) { + STRLEN i = 0; + const bool sharekeys = !!HvSHAREKEYS(sstr); + XPVHV * const dxhv = (XPVHV*)SvANY(dstr); + XPVHV * const sxhv = (XPVHV*)SvANY(sstr); + char *darray; + Newx(darray, PERL_HV_ARRAY_ALLOC_BYTES(dxhv->xhv_max+1) + + (SvOOK(sstr) ? sizeof(struct xpvhv_aux) : 0), + char); + HvARRAY(dstr) = (HE**)darray; + while (i <= sxhv->xhv_max) { + const HE * const source = HvARRAY(sstr)[i]; + HvARRAY(dstr)[i] = source + ? he_dup(source, sharekeys, param) : 0; + ++i; + } + if (SvOOK(sstr)) { + HEK *hvname; + const struct xpvhv_aux * const saux = HvAUX(sstr); + struct xpvhv_aux * const daux = HvAUX(dstr); + /* This flag isn't copied. */ + /* SvOOK_on(hv) attacks the IV flags. */ + SvFLAGS(dstr) |= SVf_OOK; + + hvname = saux->xhv_name; + daux->xhv_name = hvname ? hek_dup(hvname, param) : hvname; + + daux->xhv_riter = saux->xhv_riter; + daux->xhv_eiter = saux->xhv_eiter + ? he_dup(saux->xhv_eiter, + (bool)!!HvSHAREKEYS(sstr), param) : 0; + daux->xhv_backreferences = + saux->xhv_backreferences ? (AV*) SvREFCNT_inc( - sv_dup((SV*)saux-> - xhv_backreferences, - param)) + sv_dup((SV*)saux->xhv_backreferences, param)) : 0; - } + /* Record stashes for possible cloning in Perl_clone(). */ + if (hvname) + av_push(param->stashes, dstr); } - else { - SvPV_set(dstr, NULL); - } - /* Record stashes for possible cloning in Perl_clone(). */ - if(hvname) - av_push(param->stashes, dstr); } + else + SvPV_set(dstr, NULL); break; case SVt_PVCV: if (!(param->flags & CLONEf_COPY_STACKS)) { @@ -10268,6 +10281,8 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) ncx->blk_sub.hasargs = cx->blk_sub.hasargs; ncx->blk_sub.lval = cx->blk_sub.lval; ncx->blk_sub.retop = cx->blk_sub.retop; + ncx->blk_sub.oldcomppad = (PAD*)ptr_table_fetch(PL_ptr_table, + cx->blk_sub.oldcomppad); break; case CXt_EVAL: ncx->blk_eval.old_in_eval = cx->blk_eval.old_in_eval; @@ -10923,7 +10938,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, 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)); + 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); @@ -10934,7 +10949,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, 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)); + 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); @@ -10958,11 +10973,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling); PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings); - if (!specialCopIO(PL_compiling.cop_io)) - PL_compiling.cop_io = sv_dup_inc(PL_compiling.cop_io, param); - if (PL_compiling.cop_hints) { + if (PL_compiling.cop_hints_hash) { HINTS_REFCNT_LOCK; - PL_compiling.cop_hints->refcounted_he_refcnt++; + PL_compiling.cop_hints_hash->refcounted_he_refcnt++; HINTS_REFCNT_UNLOCK; } PL_curcop = (COP*)any_dup(proto_perl->Tcurcop, proto_perl); @@ -11743,16 +11756,17 @@ STATIC I32 S_find_array_subscript(pTHX_ AV *av, SV* val) { dVAR; - SV** svp; - I32 i; if (!av || SvMAGICAL(av) || !AvARRAY(av) || (AvFILLp(av) > FUV_MAX_SEARCH_SIZE)) return -1; - svp = AvARRAY(av); - for (i=AvFILLp(av); i>=0; i--) { - if (svp[i] == val && svp[i] != &PL_sv_undef) - return i; + if (val != &PL_sv_undef) { + SV ** const svp = AvARRAY(av); + I32 i; + + for (i=AvFILLp(av); i>=0; i--) + if (svp[i] == val) + return i; } return -1; }