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.
This commit is contained in:
Philipp Stephani 2019-12-23 15:37:49 +01:00
parent 0abdb01be6
commit f8e83d73a2
2 changed files with 11 additions and 3 deletions

View file

@ -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

View file

@ -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)