X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=7f4b1c6b48d66f84dd2abcced7e078e859abfd7c;hb=359164a0b0ca9d7142b89ef0b09c1d01437e4471;hp=6fc3ac2a78b5920c149889d865938029c20a70d1;hpb=e0fa7e2be05466f132eb653ebe7b2f9664ffcb3b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index 6fc3ac2..7f4b1c6 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, xhv_max), + 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 */ @@ -1327,13 +1339,6 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type) HvSHAREKEYS_on(sv); /* key-sharing on by default */ #endif HvMAX(sv) = 7; /* (start with 8 buckets) */ - if (old_type_details->body_size) { - HvFILL(sv) = 0; - } else { - /* It will have been zeroed when the new body was allocated. - Lets not write to it, in case it confuses a write-back - cache. */ - } } /* SVt_NULL isn't the only thing upgraded to AV or HV. @@ -2322,7 +2327,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 +2406,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 +2439,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 +2454,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 +2480,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 +2800,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); @@ -7298,7 +7316,7 @@ return_string_or_null: =for apidoc sv_inc Auto-increment of the value in the SV, doing string to numeric conversion -if necessary. Handles 'get' magic. +if necessary. Handles 'get' magic and operator overloading. =cut */ @@ -7306,13 +7324,30 @@ if necessary. Handles 'get' magic. void Perl_sv_inc(pTHX_ register SV *const sv) { + if (!sv) + return; + SvGETMAGIC(sv); + sv_inc_nomg(sv); +} + +/* +=for apidoc sv_inc_nomg + +Auto-increment of the value in the SV, doing string to numeric conversion +if necessary. Handles operator overloading. Skips handling 'get' magic. + +=cut +*/ + +void +Perl_sv_inc_nomg(pTHX_ register SV *const sv) +{ dVAR; register char *d; int flags; if (!sv) return; - SvGETMAGIC(sv); if (SvTHINKFIRST(sv)) { if (SvIsCOW(sv)) sv_force_normal_flags(sv, 0); @@ -7462,7 +7497,7 @@ Perl_sv_inc(pTHX_ register SV *const sv) =for apidoc sv_dec Auto-decrement of the value in the SV, doing string to numeric conversion -if necessary. Handles 'get' magic. +if necessary. Handles 'get' magic and operator overloading. =cut */ @@ -7471,11 +7506,29 @@ void Perl_sv_dec(pTHX_ register SV *const sv) { dVAR; + if (!sv) + return; + SvGETMAGIC(sv); + sv_dec_nomg(sv); +} + +/* +=for apidoc sv_dec_nomg + +Auto-decrement of the value in the SV, doing string to numeric conversion +if necessary. Handles operator overloading. Skips handling 'get' magic. + +=cut +*/ + +void +Perl_sv_dec_nomg(pTHX_ register SV *const sv) +{ + dVAR; int flags; if (!sv) return; - SvGETMAGIC(sv); if (SvTHINKFIRST(sv)) { if (SvIsCOW(sv)) sv_force_normal_flags(sv, 0); @@ -9365,6 +9418,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] == '%' && @@ -9384,13 +9439,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 @@ -11559,8 +11609,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) 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); @@ -11584,6 +11632,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; @@ -11660,12 +11714,8 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) proto_perl)); break; case SAVEt_REGCONTEXT: - ix -= uv >> SAVE_TIGHT_SHIFT; - break; 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 +11752,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;