From: Philipp Stephani Date: Mon, 23 Dec 2019 14:37:49 +0000 (+0100) Subject: Document and verify that emacs_limb_t doesn’t have padding bits. X-Git-Tag: emacs-27.0.90~300 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f8e83d73a259e1809020d47e920a96a1f5803f7a;p=emacs.git Document and verify that emacs_limb_t doesn’t have padding bits. This is a useful property when doing further bit-twiddling with the magnitude array before/after calling extract_big_integer or make_big_integer. For example, constructing an emacs_limb_t object using repeated shift-and-add should work as expected, but relies on the type not having padding bits. Since the C standard already guarantees that unsigned integers use a pure binary representation, not having padding bits is enough to guarantee that the type has unique object representations in the sense of C++’s std::has_unique_object_representations. * doc/lispref/internals.texi (Module Values): Document that emacs_limb_t doesn’t have padding bits. * src/emacs-module.c: Verify that emacs_limb_t doesn’t have padding bits. --- diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 2a4e64dbb56..bccdca65e4e 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -1508,9 +1508,10 @@ overflow in the size calculation. @end deftypefn @deftp {Type alias} emacs_limb_t -This is an unsigned integer type, -used as the element type for the magnitude arrays for the big -integer conversion functions. +This is an unsigned integer type, used as the element type for the +magnitude arrays for the big integer conversion functions. The type +is guaranteed to have unique object representations, i.e., no padding +bits. @end deftp @defvr Macro EMACS_LIMB_MAX diff --git a/src/emacs-module.c b/src/emacs-module.c index f372a153ccf..f2e3f627756 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -827,6 +827,13 @@ enum module_bignum_count_max = min (SIZE_MAX, PTRDIFF_MAX) / sizeof (emacs_limb_t) }; +/* Verify that emacs_limb_t indeed has unique object + representations. */ +verify (CHAR_BIT == 8); +verify ((sizeof (emacs_limb_t) == 4 && EMACS_LIMB_MAX == 0xFFFFFFFF) + || (sizeof (emacs_limb_t) == 8 + && EMACS_LIMB_MAX == 0xFFFFFFFFFFFFFFFF)); + static bool module_extract_big_integer (emacs_env *env, emacs_value arg, int *sign, ptrdiff_t *count, emacs_limb_t *magnitude)