From d361b00481905de183664c6b0d414fd509a0e68f Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Sat, 6 Jul 2013 15:33:57 -0600 Subject: [PATCH 1/1] Reinstate "Use new Svt_INVLIST for inversion lists." This reverts commit 2e0b8fbeab3502bee36f25825c3cdd0d075c4fd3, which reverted e0ce103ae532f9576f54a5938a24d1ee98dfb928, thus reinstating the latter commit. It turns out that the error being chased down was not due to this commit. Its original message was: This converts inversion lists to use their own scalar type. --- embed.fnc | 2 +- inline_invlist.c | 2 +- perl.h | 3 ++- proto.h | 2 +- regcomp.c | 23 +++++++++++------------ sv.c | 15 +++++++++------ sv.h | 8 ++++++++ 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/embed.fnc b/embed.fnc index 1ef5935..03214b7 100644 --- a/embed.fnc +++ b/embed.fnc @@ -1434,7 +1434,7 @@ EsM |void |_append_range_to_invlist |NN SV* const invlist|const UV start|const EiMR |UV* |_invlist_array_init |NN SV* const invlist|const bool will_have_0 EiMR |UV* |invlist_array |NN SV* const invlist EsM |void |invlist_extend |NN SV* const invlist|const UV len -EiMR |U8* |get_invlist_offset_addr|NN SV* invlist +EiMR |bool* |get_invlist_offset_addr|NN SV* invlist EiMR |UV |invlist_max |NN SV* const invlist EiM |void |invlist_set_len|NN SV* const invlist|const UV len EiMR |IV* |get_invlist_previous_index_addr|NN SV* invlist diff --git a/inline_invlist.c b/inline_invlist.c index ced42d8..a299645 100644 --- a/inline_invlist.c +++ b/inline_invlist.c @@ -21,7 +21,7 @@ S__get_invlist_len_addr(pTHX_ SV* invlist) PERL_ARGS_ASSERT__GET_INVLIST_LEN_ADDR; - return &(LvTARGLEN(invlist)); + return &(((XINVLIST*) SvANY(invlist))->count); } PERL_STATIC_INLINE UV diff --git a/perl.h b/perl.h index c4f29db..cfcf871 100644 --- a/perl.h +++ b/perl.h @@ -2286,6 +2286,7 @@ typedef struct xpvuv XPVUV; typedef struct xpvnv XPVNV; typedef struct xpvmg XPVMG; typedef struct xpvlv XPVLV; +typedef struct xpvinvlist XINVLIST; typedef struct xpvav XPVAV; typedef struct xpvhv XPVHV; typedef struct xpvgv XPVGV; @@ -5057,7 +5058,7 @@ PL_valid_types_IVX[] = { 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 }; EXTCONST bool PL_valid_types_NVX[] = { 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 }; EXTCONST bool -PL_valid_types_PVX[] = { 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1 }; +PL_valid_types_PVX[] = { 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1 }; EXTCONST bool PL_valid_types_RV[] = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }; EXTCONST bool diff --git a/proto.h b/proto.h index eb2c7c1..f6e0883 100644 --- a/proto.h +++ b/proto.h @@ -6509,7 +6509,7 @@ PERL_STATIC_INLINE STRLEN* S_get_invlist_iter_addr(pTHX_ SV* invlist) #define PERL_ARGS_ASSERT_GET_INVLIST_ITER_ADDR \ assert(invlist) -PERL_STATIC_INLINE U8* S_get_invlist_offset_addr(pTHX_ SV* invlist) +PERL_STATIC_INLINE bool* S_get_invlist_offset_addr(pTHX_ SV* invlist) __attribute__warn_unused_result__ __attribute__nonnull__(pTHX_1); #define PERL_ARGS_ASSERT_GET_INVLIST_OFFSET_ADDR \ diff --git a/regcomp.c b/regcomp.c index c747071..908257a 100644 --- a/regcomp.c +++ b/regcomp.c @@ -7025,9 +7025,8 @@ S_reg_scan_name(pTHX_ RExC_state_t *pRExC_state, U32 flags) /* This section of code defines the inversion list object and its methods. The * interfaces are highly subject to change, so as much as possible is static to - * this file. An inversion list is here implemented as a malloc'd C UV array. - * Currently it is a SVt_PVLV, with some of the header fields from that - * repurposed for uses here. + * this file. An inversion list is here implemented as a malloc'd C UV array + * as an SVt_INVLIST scalar. * * An inversion list for Unicode is an array of code points, sorted by ordinal * number. The zeroth element is the first code point in the list. The 1th @@ -7087,7 +7086,7 @@ S__invlist_array_init(pTHX_ SV* const invlist, const bool will_have_0) * element is either the element reserved for 0, if TRUE, or the element * after it, if FALSE */ - U8* offset = get_invlist_offset_addr(invlist); + bool* offset = get_invlist_offset_addr(invlist); UV* zero_addr = (UV *) SvPVX(invlist); PERL_ARGS_ASSERT__INVLIST_ARRAY_INIT; @@ -7143,12 +7142,12 @@ S_invlist_set_len(pTHX_ SV* const invlist, const UV len) PERL_STATIC_INLINE IV* S_get_invlist_previous_index_addr(pTHX_ SV* invlist) { - /* Return the address of the UV that is reserved to hold the cached index + /* Return the address of the IV that is reserved to hold the cached index * */ PERL_ARGS_ASSERT_GET_INVLIST_PREVIOUS_INDEX_ADDR; - return &(((XPVLV*) SvANY(invlist))->xiv_u.xivu_iv); + return &(((XINVLIST*) SvANY(invlist))->prev_index); } PERL_STATIC_INLINE IV @@ -7186,7 +7185,7 @@ S_invlist_max(pTHX_ SV* const invlist) : FROM_INTERNAL_SIZE(SvLEN(invlist)); } -PERL_STATIC_INLINE U8* +PERL_STATIC_INLINE bool* S_get_invlist_offset_addr(pTHX_ SV* invlist) { /* Return the address of the field that says whether the inversion list is @@ -7194,7 +7193,7 @@ S_get_invlist_offset_addr(pTHX_ SV* invlist) PERL_ARGS_ASSERT_GET_INVLIST_OFFSET_ADDR; - return (U8*) &(LvFLAGS(invlist)); + return &(((XINVLIST*) SvANY(invlist))->is_offset); } #ifndef PERL_IN_XSUB_RE @@ -7207,14 +7206,14 @@ Perl__new_invlist(pTHX_ IV initial_size) * system default is used instead */ SV* new_list; - U8* offset_addr; + bool* offset_addr; if (initial_size < 0) { initial_size = 10; } /* Allocate the initial space */ - new_list = newSV_type(SVt_PVLV); + new_list = newSV_type(SVt_INVLIST); SvGROW(new_list, TO_INTERNAL_SIZE(initial_size) + 1); /* 1 is for trailing NUL */ invlist_set_len(new_list, 0); @@ -7258,7 +7257,7 @@ S__new_invlist_C_array(pTHX_ const UV* const list) inversion list of the correct vintage. */ - SV* invlist = newSV_type(SVt_PVLV); + SV* invlist = newSV_type(SVt_INVLIST); PERL_ARGS_ASSERT__NEW_INVLIST_C_ARRAY; @@ -8167,7 +8166,7 @@ S_get_invlist_iter_addr(pTHX_ SV* invlist) PERL_ARGS_ASSERT_GET_INVLIST_ITER_ADDR; - return &(LvTARGOFF(invlist)); + return &(((XINVLIST*) SvANY(invlist))->iterator); } PERL_STATIC_INLINE void diff --git a/sv.c b/sv.c index 4f53c5c..3977204 100644 --- a/sv.c +++ b/sv.c @@ -898,10 +898,11 @@ static const struct body_details bodies_by_type[] = { SVt_PV, FALSE, NONV, HASARENA, FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) }, - /* The invlist placeholder pretends to be an RV for now. - Also it's marked as "can't upgrade" to stop anyone using it before it's - implemented. */ - { 0, 0, 0, SVt_INVLIST, TRUE, NONV, NOARENA, 0 }, + { sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur), + copy_length(XINVLIST, is_offset) - STRUCT_OFFSET(XPV, xpv_cur), + + STRUCT_OFFSET(XPV, xpv_cur), + SVt_INVLIST, TRUE, NONV, HASARENA, + FIT_ARENA(0, sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur)) }, { sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur), copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur), @@ -1340,6 +1341,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type) case SVt_PVGV: case SVt_PVCV: case SVt_PVLV: + case SVt_INVLIST: case SVt_REGEXP: case SVt_PVMG: case SVt_PVNV: @@ -4127,7 +4129,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) } break; - /* case SVt_INVLIST: */ + case SVt_INVLIST: case SVt_PVLV: case SVt_PVGV: case SVt_PVMG: @@ -6338,6 +6340,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) case SVt_PVMG: case SVt_PVNV: case SVt_PVIV: + case SVt_INVLIST: case SVt_PV: freescalar: /* Don't bother with SvOOK_off(sv); as we're only going to @@ -12217,7 +12220,6 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) SvANY(dstr) = new_XNV(); SvNV_set(dstr, SvNVX(sstr)); break; - /* case SVt_INVLIST: */ default: { /* These are all the types that need complex bodies allocating. */ @@ -12242,6 +12244,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) case SVt_PVMG: case SVt_PVNV: case SVt_PVIV: + case SVt_INVLIST: case SVt_PV: assert(sv_type_details->body_size); if (sv_type_details->arena) { diff --git a/sv.h b/sv.h index 0205f58..a891ce9 100644 --- a/sv.h +++ b/sv.h @@ -528,6 +528,14 @@ struct xpvlv { char xlv_flags; /* 1 = negative offset 2 = negative len */ }; +struct xpvinvlist { + _XPV_HEAD; + IV prev_index; + STRLEN iterator; + STRLEN count; + bool is_offset; /* */ +}; + /* This structure works in 3 ways - regular scalar, GV with GP, or fast Boyer-Moore. */ struct xpvgv { -- 1.8.3.1