This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
handy.h: Create nBIT_MASK(n) macro
authorKarl Williamson <khw@cpan.org>
Fri, 29 May 2020 20:25:19 +0000 (14:25 -0600)
committerKarl Williamson <khw@cpan.org>
Sat, 18 Jul 2020 04:04:08 +0000 (22:04 -0600)
This encapsulates a common paradigm, making sure that it is done
correctly for the platform's size.

doop.c
handy.h
malloc.c
op_reg_common.h
os2/os2ish.h
pp_pack.c
regcomp.h
utf8.h

diff --git a/doop.c b/doop.c
index 267b640..a06992f 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -857,7 +857,7 @@ Perl_do_vecget(pTHX_ SV *sv, STRLEN offset, int size)
        }
     }
     else if (size < 8)
-       retnum = (s[uoffset] >> bitoffs) & ((1 << size) - 1);
+       retnum = (s[uoffset] >> bitoffs) & nBIT_MASK(size);
     else {
        if (size == 8)
            retnum = s[uoffset];
@@ -960,7 +960,7 @@ Perl_do_vecset(pTHX_ SV *sv)
     }
 
     if (size < 8) {
-       mask = (1 << size) - 1;
+       mask = nBIT_MASK(size);
        lval &= mask;
        s[offset] &= ~(mask << bitoffs);
        s[offset] |= lval << bitoffs;
diff --git a/handy.h b/handy.h
index 4451e9d..7f07417 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -269,6 +269,13 @@ typedef U64TYPE U64;
 #  define isPOWER_OF_2(n) ((n) && ((n) & ((n)-1)) == 0)
 #endif
 
+/* Returns a mask with the lowest n bits set */
+#ifdef HAS_LONG_LONG
+#  define nBIT_MASK(n) ((1ULL << (n)) - 1)
+#else
+#  define nBIT_MASK(n) ((1UL << (n)) - 1)
+#endif
+
 /*
 =for apidoc Am|void|__ASSERT_|bool expr
 
index 337efa8..9e5ff76 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -596,7 +596,7 @@ static const u_short buck_size[MAX_BUCKET_BY_TABLE + 1] =
 #  define MAX_PACKED_POW2 6
 #  define MAX_PACKED (MAX_PACKED_POW2 * BUCKETS_PER_POW2 + BUCKET_POW2_SHIFT)
 #  define MAX_POW2_ALGO ((1<<(MAX_PACKED_POW2 + 1)) - M_OVERHEAD)
-#  define TWOK_MASK ((1<<LOG_OF_MIN_ARENA) - 1)
+#  define TWOK_MASK nBITMASK(LOG_OF_MIN_ARENA)
 #  define TWOK_MASKED(x) (PTR2UV(x) & ~TWOK_MASK)
 #  define TWOK_SHIFT(x) (PTR2UV(x) & TWOK_MASK)
 #  define OV_INDEXp(block) (INT2PTR(u_char*,TWOK_MASKED(block)))
@@ -618,7 +618,7 @@ static const u_short buck_size[MAX_BUCKET_BY_TABLE + 1] =
 #ifdef IGNORE_SMALL_BAD_FREE
 #define FIRST_BUCKET_WITH_CHECK (6 * BUCKETS_PER_POW2) /* 64 */
 #  define N_BLKS(bucket) ( (bucket) < FIRST_BUCKET_WITH_CHECK          \
-                        ? ((1<<LOG_OF_MIN_ARENA) - 1)/BUCKET_SIZE_NO_SURPLUS(bucket) \
+                        ? nBIT_MASK(LOG_OF_MIN_ARENA)/BUCKET_SIZE_NO_SURPLUS(bucket) \
                         : n_blks[bucket] )
 #else
 #  define N_BLKS(bucket) n_blks[bucket]
index c500aa4..e8770e6 100644 (file)
@@ -137,8 +137,8 @@ get_regex_charset(const U32 flags)
  *  directly in the #define because doing so confuses regcomp.pl.
  *  (2**n - 1) is n 1 bits, so the below gets the contiguous bits between the
  *  beginning and ending shifts */
-#if RXf_PMf_COMPILETIME != (((1 << (_RXf_PMf_SHIFT_COMPILETIME))-1) \
-                            & (~((1 << RXf_PMf_STD_PMMOD_SHIFT)-1)))
+#if RXf_PMf_COMPILETIME != ((nBIT_MASK(_RXf_PMf_SHIFT_COMPILETIME)) \
+                        & (~(nBIT_MASK( RXf_PMf_STD_PMMOD_SHIFT))))
 #   error RXf_PMf_COMPILETIME is invalid
 #endif
 
index c82419e..e209fb5 100644 (file)
@@ -874,7 +874,7 @@ int os2_do_aspawn(pTHX_ SV *really, SV **vmark, SV **vsp);
  * arguments to setlogmask.
  */
 #  define      LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
-#  define      LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
+#  define       LOG_UPTO(pri)   nBIT_MASK((pri)+1)      /* all priorities through pri */
 
 /*
  * Option flags for openlog.
index 8ac5316..53d63f9 100644 (file)
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -1808,7 +1808,7 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const c
            }
            else {
                if (checksum < bits_in_uv) {
-                   UV mask = ((UV)1 << checksum) - 1;
+                   UV mask = nBIT_MASK(checksum);
                    cuv &= mask;
                }
                sv = newSVuv(cuv);
index 312c905..d39f1ae 100644 (file)
--- a/regcomp.h
+++ b/regcomp.h
@@ -359,7 +359,7 @@ struct regnode_ssc {
     } STMT_END
 
 #define ANYOFR_BASE_BITS    20
-#define ANYOFRbase(p)   (ARG(p) & ((1 << ANYOFR_BASE_BITS) - 1))
+#define ANYOFRbase(p)   (ARG(p) & nBIT_MASK(ANYOFR_BASE_BITS))
 #define ANYOFRdelta(p)  (ARG(p) >> ANYOFR_BASE_BITS)
 
 #undef NODE_ALIGN
@@ -697,7 +697,7 @@ struct regnode_ssc {
      } STMT_END
 
 /* Shifts a bit to get, eg. 0x4000_0000, then subtracts 1 to get 0x3FFF_FFFF */
-#define ANYOF_POSIXL_SETALL(ret) STMT_START { ((regnode_charclass_posixl*) (ret))->classflags = ((1U << ((ANYOF_POSIXL_MAX) - 1))) - 1; } STMT_END
+#define ANYOF_POSIXL_SETALL(ret) STMT_START { ((regnode_charclass_posixl*) (ret))->classflags = nBIT_MASK(ANYOF_POSIXL_MAX); } STMT_END
 #define ANYOF_CLASS_SETALL(ret) ANYOF_POSIXL_SETALL(ret)
 
 #define ANYOF_POSIXL_TEST_ANY_SET(p)                               \
@@ -711,12 +711,12 @@ struct regnode_ssc {
                             cBOOL(((regnode_ssc*)(p))->classflags)
 #define ANYOF_POSIXL_SSC_TEST_ALL_SET(p) /* Are all bits set? */       \
         (((regnode_ssc*) (p))->classflags                              \
-                        == ((1U << ((ANYOF_POSIXL_MAX) - 1))) - 1)
+                                        == nBIT_MASK(ANYOF_POSIXL_MAX))
 
 #define ANYOF_POSIXL_TEST_ALL_SET(p)                                   \
-        ((ANYOF_FLAGS(p) & ANYOF_MATCHES_POSIXL)                               \
+        ((ANYOF_FLAGS(p) & ANYOF_MATCHES_POSIXL)                       \
          && ((regnode_charclass_posixl*) (p))->classflags              \
-                        == ((1U << ((ANYOF_POSIXL_MAX) - 1))) - 1)
+                                    == nBIT_MASK(ANYOF_POSIXL_MAX))
 
 #define ANYOF_POSIXL_OR(source, dest) STMT_START { (dest)->classflags |= (source)->classflags ; } STMT_END
 #define ANYOF_CLASS_OR(source, dest) ANYOF_POSIXL_OR((source), (dest))
diff --git a/utf8.h b/utf8.h
index 01bf447..25ebd70 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -283,7 +283,7 @@ are in the character. */
 /* 2**UTF_ACCUMULATION_SHIFT - 1.  This masks out all but the bits that carry
  * real information in a continuation byte.  This turns out to be 0x3F in
  * UTF-8, 0x1F in UTF-EBCDIC. */
-#define UTF_CONTINUATION_MASK  ((U8) ((1U << UTF_ACCUMULATION_SHIFT) - 1))
+#define UTF_CONTINUATION_MASK  ((U8) (nBIT_MASK(UTF_ACCUMULATION_SHIFT)))
 
 /* For use in UTF8_IS_CONTINUATION().  This turns out to be 0xC0 in UTF-8,
  * E0 in UTF-EBCDIC */
@@ -417,7 +417,7 @@ encoded as UTF-8.  C<cp> is a native (ASCII or EBCDIC) code point if less than
 /* The largest code point representable by two UTF-8 bytes on any platform that
  * Perl runs on.  This value is constrained by EBCDIC which has 5 bits per
  * continuation byte */
-#define MAX_PORTABLE_UTF8_TWO_BYTE (32 * (1U << 5) - 1)
+#define MAX_PORTABLE_UTF8_TWO_BYTE (32 * nBIT_MAX(5))
 
 /*