X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=fe3f36253c290a8b37c0c7c3bc8509642a44b9ff;hb=4f7003f5e8adb225a16f3788ec81e193021f41e5;hp=31db3152ee3c7d3d631cb32ea0580dab326c1d8f;hpb=c6bf6a65e4bf512beae58d59446046f4ca20372f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index 31db315..fe3f362 100644 --- a/sv.c +++ b/sv.c @@ -915,35 +915,54 @@ static const struct body_details bodies_by_type[] = { }, /* 8 bytes on most ILP32 with IEEE doubles */ - { sizeof(NV), sizeof(NV), 0, SVt_NV, FALSE, HADNV, HASARENA, - FIT_ARENA(0, sizeof(NV)) }, + { 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), + { sizeof(XPV), 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)) }, +#if 2 *PTRSIZE <= IVSIZE /* 12 */ - { sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur), + { sizeof(XPVIV), copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur), - + STRUCT_OFFSET(XPVIV, xpv_cur), + + STRUCT_OFFSET(XPV, xpv_cur), SVt_PVIV, FALSE, NONV, HASARENA, - FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) }, + FIT_ARENA(0, sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur)) }, + /* 12 */ +#else + { sizeof(XPVIV), + copy_length(XPVIV, xiv_u), + 0, + SVt_PVIV, FALSE, NONV, HASARENA, + FIT_ARENA(0, sizeof(XPVIV)) }, +#endif +#if (2 *PTRSIZE <= IVSIZE) && (2 *PTRSIZE <= NVSIZE) /* 20 */ - { sizeof(XPVNV), copy_length(XPVNV, xiv_u), 0, SVt_PVNV, FALSE, HADNV, + { sizeof(XPVNV), + 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)) }, +#else + /* 20 */ + { sizeof(XPVNV), copy_length(XPVNV, xnv_u), 0, SVt_PVNV, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVNV)) }, +#endif /* 28 */ - { sizeof(XPVMG), copy_length(XPVMG, xmg_stash), 0, SVt_PVMG, FALSE, HADNV, + { sizeof(XPVMG), copy_length(XPVMG, xnv_u), 0, SVt_PVMG, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVMG)) }, /* something big */ - { sizeof(regexp) - STRUCT_OFFSET(regexp, xpv_cur), - sizeof(regexp) - STRUCT_OFFSET(regexp, xpv_cur), - + STRUCT_OFFSET(regexp, xpv_cur), + { sizeof(regexp), + sizeof(regexp), + 0, SVt_REGEXP, FALSE, NONV, HASARENA, FIT_ARENA(0, sizeof(regexp) - STRUCT_OFFSET(regexp, xpv_cur)) }, @@ -956,46 +975,39 @@ static const struct body_details bodies_by_type[] = { { sizeof(XPVLV), sizeof(XPVLV), 0, SVt_PVLV, TRUE, HADNV, HASARENA, FIT_ARENA(0, sizeof(XPVLV)) }, - { sizeof(XPVAV) - STRUCT_OFFSET(XPVAV, xav_fill), - copy_length(XPVAV, xmg_stash) - STRUCT_OFFSET(XPVAV, xav_fill), - + STRUCT_OFFSET(XPVAV, xav_fill), + { sizeof(XPVAV), + copy_length(XPVAV, xav_alloc), + 0, SVt_PVAV, TRUE, NONV, HASARENA, - FIT_ARENA(0, sizeof(XPVAV) - STRUCT_OFFSET(XPVAV, xav_fill)) }, + FIT_ARENA(0, sizeof(XPVAV)) }, - { sizeof(XPVHV) - STRUCT_OFFSET(XPVHV, xhv_fill), - copy_length(XPVHV, xmg_stash) - STRUCT_OFFSET(XPVHV, xhv_fill), - + STRUCT_OFFSET(XPVHV, xhv_fill), + { sizeof(XPVHV), + copy_length(XPVHV, xiv_u), + 0, SVt_PVHV, TRUE, NONV, HASARENA, - FIT_ARENA(0, sizeof(XPVHV) - STRUCT_OFFSET(XPVHV, xhv_fill)) }, + FIT_ARENA(0, sizeof(XPVHV)) }, /* 56 */ - { sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur), - sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur), - + STRUCT_OFFSET(XPVCV, xpv_cur), + { sizeof(XPVCV), + sizeof(XPVCV), + 0, SVt_PVCV, TRUE, NONV, HASARENA, - FIT_ARENA(0, sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur)) }, + FIT_ARENA(0, sizeof(XPVCV)) }, - { sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur), - sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur), - + STRUCT_OFFSET(XPVFM, xpv_cur), + { sizeof(XPVFM), + sizeof(XPVFM), + 0, SVt_PVFM, TRUE, NONV, NOARENA, - FIT_ARENA(20, sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur)) }, + FIT_ARENA(20, sizeof(XPVFM)) }, /* XPVIO is 84 bytes, fits 48x */ - { sizeof(XPVIO) - STRUCT_OFFSET(XPVIO, xpv_cur), - sizeof(XPVIO) - STRUCT_OFFSET(XPVIO, xpv_cur), - + STRUCT_OFFSET(XPVIO, xpv_cur), + { sizeof(XPVIO), + sizeof(XPVIO), + 0, SVt_PVIO, TRUE, NONV, HASARENA, - FIT_ARENA(24, sizeof(XPVIO) - STRUCT_OFFSET(XPVIO, xpv_cur)) }, + FIT_ARENA(24, sizeof(XPVIO)) }, }; -#define new_body_type(sv_type) \ - (void *)((char *)S_new_body(aTHX_ sv_type)) - -#define del_body_type(p, sv_type) \ - del_body(p, &PL_body_roots[sv_type]) - - #define new_body_allocated(sv_type) \ (void *)((char *)S_new_body(aTHX_ sv_type) \ - bodies_by_type[sv_type].offset) @@ -1030,11 +1042,11 @@ static const struct body_details bodies_by_type[] = { #else /* !PURIFY */ -#define new_XNV() new_body_type(SVt_NV) -#define del_XNV(p) del_body_type(p, SVt_NV) +#define new_XNV() new_body_allocated(SVt_NV) +#define del_XNV(p) del_body_allocated(p, SVt_NV) -#define new_XPVNV() new_body_type(SVt_PVNV) -#define del_XPVNV(p) del_body_type(p, SVt_PVNV) +#define new_XPVNV() new_body_allocated(SVt_PVNV) +#define del_XPVNV(p) del_body_allocated(p, SVt_PVNV) #define new_XPVAV() new_body_allocated(SVt_PVAV) #define del_XPVAV(p) del_body_allocated(p, SVt_PVAV) @@ -1042,11 +1054,11 @@ static const struct body_details bodies_by_type[] = { #define new_XPVHV() new_body_allocated(SVt_PVHV) #define del_XPVHV(p) del_body_allocated(p, SVt_PVHV) -#define new_XPVMG() new_body_type(SVt_PVMG) -#define del_XPVMG(p) del_body_type(p, SVt_PVMG) +#define new_XPVMG() new_body_allocated(SVt_PVMG) +#define del_XPVMG(p) del_body_allocated(p, SVt_PVMG) -#define new_XPVGV() new_body_type(SVt_PVGV) -#define del_XPVGV(p) del_body_type(p, SVt_PVGV) +#define new_XPVGV() new_body_allocated(SVt_PVGV) +#define del_XPVGV(p) del_body_allocated(p, SVt_PVGV) #endif /* PURIFY */ @@ -2322,7 +2334,10 @@ Perl_sv_2iv_flags(pTHX_ register SV *const sv, const I32 flags) if (SvROK(sv)) { return_rok: if (SvAMAGIC(sv)) { - SV * const tmpstr=AMG_CALLun(sv,numer); + SV * tmpstr; + if (flags & SV_SKIP_OVERLOAD) + return 0; + tmpstr=AMG_CALLun(sv,numer); if (tmpstr && (!SvROK(tmpstr) || (SvRV(tmpstr) != SvRV(sv)))) { return SvIV(tmpstr); } @@ -2398,7 +2413,10 @@ Perl_sv_2uv_flags(pTHX_ register SV *const sv, const I32 flags) if (SvROK(sv)) { return_rok: if (SvAMAGIC(sv)) { - SV *const tmpstr = AMG_CALLun(sv,numer); + SV *tmpstr; + if (flags & SV_SKIP_OVERLOAD) + return 0; + tmpstr = AMG_CALLun(sv,numer); if (tmpstr && (!SvROK(tmpstr) || (SvRV(tmpstr) != SvRV(sv)))) { return SvUV(tmpstr); } @@ -2428,14 +2446,14 @@ Perl_sv_2uv_flags(pTHX_ register SV *const sv, const I32 flags) =for apidoc sv_2nv Return the num value of an SV, doing any necessary string or integer -conversion, magic etc. Normally used via the C and C -macros. +conversion. If flags includes SV_GMAGIC, does an mg_get() first. +Normally used via the C and C macros. =cut */ NV -Perl_sv_2nv(pTHX_ register SV *const sv) +Perl_sv_2nv_flags(pTHX_ register SV *const sv, const I32 flags) { dVAR; if (!sv) @@ -2443,7 +2461,8 @@ Perl_sv_2nv(pTHX_ register SV *const sv) 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. */ - mg_get(sv); + if (flags & SV_GMAGIC) + mg_get(sv); if (SvNOKp(sv)) return SvNVX(sv); if ((SvPOKp(sv) && SvLEN(sv)) && !SvIOKp(sv)) { @@ -2468,7 +2487,10 @@ Perl_sv_2nv(pTHX_ register SV *const sv) if (SvROK(sv)) { return_rok: if (SvAMAGIC(sv)) { - SV *const tmpstr = AMG_CALLun(sv,numer); + SV *tmpstr; + if (flags & SV_SKIP_OVERLOAD) + return 0; + tmpstr = AMG_CALLun(sv,numer); if (tmpstr && (!SvROK(tmpstr) || (SvRV(tmpstr) != SvRV(sv)))) { return SvNV(tmpstr); } @@ -2785,7 +2807,10 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags if (SvROK(sv)) { return_rok: if (SvAMAGIC(sv)) { - SV *const tmpstr = AMG_CALLun(sv,string); + SV *tmpstr; + if (flags & SV_SKIP_OVERLOAD) + return NULL; + tmpstr = AMG_CALLun(sv,string); if (tmpstr && (!SvROK(tmpstr) || (SvRV(tmpstr) != SvRV(sv)))) { /* Unwrap this: */ /* char *pv = lp ? SvPV(tmpstr, *lp) : SvPV_nolen(tmpstr); @@ -4063,9 +4088,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags) (!(flags & SV_NOSTEAL)) && /* and we're allowed to steal temps */ SvREFCNT(sstr) == 1 && /* and no other references to it? */ - SvLEN(sstr) && /* and really is a string */ - /* and won't be needed again, potentially */ - !(PL_op && PL_op->op_type == OP_AASSIGN)) + SvLEN(sstr)) /* and really is a string */ #ifdef PERL_OLD_COPY_ON_WRITE && ((flags & SV_COW_SHARED_HASH_KEYS) ? (!((sflags & CAN_COW_MASK) == CAN_COW_FLAGS @@ -9367,6 +9390,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, else if (svix < svmax) { sv_catsv(sv, *svargs); } + else + S_vcatpvfn_missing_argument(aTHX); return; } if (args && patlen == 3 && pat[0] == '%' && @@ -9386,13 +9411,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, pp = pat + 2; while (*pp >= '0' && *pp <= '9') digits = 10 * digits + (*pp++ - '0'); - if (pp - pat == (int)patlen - 1) { - NV nv; - - if (svix < svmax) - nv = SvNV(*svargs); - else - return; + if (pp - pat == (int)patlen - 1 && svix < svmax) { + const NV nv = SvNV(*svargs); if (*pp == 'g') { /* Add check for digits != 0 because it seems that some gconverts are buggy in this case, and we don't yet have @@ -11509,6 +11529,8 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPUV(nss,ix) = uv; switch (type) { + case SAVEt_CLEARSV: + break; case SAVEt_HELEM: /* hash element */ sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); @@ -11555,14 +11577,10 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) case SAVEt_LONG: /* long reference */ ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); - /* fall through */ - case SAVEt_CLEARSV: longval = (long)POPLONG(ss,ix); TOPLONG(nss,ix) = longval; break; case SAVEt_I32: /* I32 reference */ - case SAVEt_I16: /* I16 reference */ - case SAVEt_I8: /* I8 reference */ case SAVEt_COP_ARYBASE: /* call CopARYBASE_set */ ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); @@ -11586,6 +11604,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) case SAVEt_VPTR: /* random* reference */ ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); + /* Fall through */ + case SAVEt_INT_SMALL: + case SAVEt_I32_SMALL: + case SAVEt_I16: /* I16 reference */ + case SAVEt_I8: /* I8 reference */ + case SAVEt_BOOL: ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); break; @@ -11663,9 +11687,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) break; case SAVEt_REGCONTEXT: case SAVEt_ALLOC: - i = POPINT(ss,ix); - TOPINT(nss,ix) = i; - ix -= i; + ix -= uv >> SAVE_TIGHT_SHIFT; break; case SAVEt_AELEM: /* array element */ sv = (const SV *)POPPTR(ss,ix); @@ -11702,12 +11724,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); break; - case SAVEt_BOOL: - ptr = POPPTR(ss,ix); - TOPPTR(nss,ix) = any_dup(ptr, proto_perl); - longval = (long)POPBOOL(ss,ix); - TOPBOOL(nss,ix) = cBOOL(longval); - break; case SAVEt_SET_SVFLAGS: i = POPINT(ss,ix); TOPINT(nss,ix) = i;