X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=d2eed0d4a39277cd978540add3798bf181791bf8;hb=1e73acc8af3eecb1b36ee831483e1e9a7b3d1662;hp=d6e307d583196a696ad4efb56f87a7807830bf5f;hpb=11bcd5dad4f9d911a9454f9d858c2dd0d14ddf2a;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index d6e307d..d2eed0d 100644 --- a/sv.c +++ b/sv.c @@ -1120,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; @@ -1496,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); @@ -1596,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 */ @@ -3348,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; @@ -3483,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. */ @@ -4642,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 */ @@ -4795,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? */ @@ -9015,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' */ } @@ -9040,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'; } @@ -9338,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; @@ -9539,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]); } @@ -10137,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; - } - } - else { - SvPV_set(dstr, NULL); + /* Record stashes for possible cloning in Perl_clone(). */ + if (hvname) + av_push(param->stashes, dstr); } - /* 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)) {