This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Reinstate "Use new Svt_INVLIST for inversion lists."
authorKarl Williamson <public@khwilliamson.com>
Sat, 6 Jul 2013 21:33:57 +0000 (15:33 -0600)
committerKarl Williamson <public@khwilliamson.com>
Tue, 16 Jul 2013 19:58:09 +0000 (13:58 -0600)
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
inline_invlist.c
perl.h
proto.h
regcomp.c
sv.c
sv.h

index 1ef5935..03214b7 100644 (file)
--- 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
index ced42d8..a299645 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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       \
index c747071..908257a 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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 {