[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 7f4558e 1/3: Always allow at least double-precision
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 7f4558e 1/3: Always allow at least double-precision bignums |
Date: |
Tue, 4 Jun 2019 11:34:21 -0400 (EDT) |
branch: master
commit 7f4558e3d9edbdee6901e5fbcd4a4072f49ec5b9
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Always allow at least double-precision bignums
Without this fix, Emacs can get into a tight loop reporting
a range error when calculating timestamps.
* doc/lispref/numbers.texi (Integer Basics):
* src/alloc.c (syms_of_alloc): Document this.
* src/bignum.c (make_bignum_bits): Always allow bignums
of at least twice the width of (u)intmax_t.
---
doc/lispref/numbers.texi | 14 +++++++-------
src/alloc.c | 6 +++---
src/bignum.c | 7 +++++--
3 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index fbdd83f..cae8bab 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -191,19 +191,19 @@ on 64-bit platforms.
@cindex integer range
@cindex number of bignum bits, limit on
@defvar integer-width
-The value of this variable is a nonnegative integer that is an upper
-bound on the number of bits in a bignum. Integers outside the fixnum
-range are limited to absolute values less than
+The value of this variable is a nonnegative integer that controls
+whether Emacs signals a range error when a large integer would be
+calculated. Integers with absolute values less than
@ifnottex
address@hidden,
@end ifnottex
@tex
@math{2^{n}},
@end tex
-where @var{n} is this variable's value. Attempts to create bignums outside
-this range signal a range error. Setting this variable
-to zero disables creation of bignums; setting it to a large number can
-cause Emacs to consume large quantities of memory if a computation
+where @var{n} is this variable's value, do not signal a range error.
+Attempts to create larger integers typically signal a range error,
+although there might be no signal if a larger integer can be created cheaply.
+Setting this variable to a large number can be costly if a computation
creates huge integers.
@end defvar
diff --git a/src/alloc.c b/src/alloc.c
index 5c5b56d..64aaa8a 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7369,9 +7369,9 @@ The time is in seconds as a floating point value. */);
doc: /* Accumulated number of garbage collections done. */);
DEFVAR_INT ("integer-width", integer_width,
- doc: /* Maximum number of bits in bignums.
-Integers outside the fixnum range are limited to absolute values less
-than 2**N, where N is this variable's value. N should be nonnegative. */);
+ doc: /* Maximum number N of bits in safely-calculated integers.
+Integers with absolute values less than 2**N do not signal a range error.
+N should be nonnegative. */);
defsubr (&Scons);
defsubr (&Slist);
diff --git a/src/bignum.c b/src/bignum.c
index 009d731..3883d3a 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -82,8 +82,11 @@ static Lisp_Object
make_bignum_bits (size_t bits)
{
/* The documentation says integer-width should be nonnegative, so
- a single comparison suffices even though 'bits' is unsigned. */
- if (integer_width < bits)
+ comparing it to BITS works even though BITS is unsigned. Treat
+ integer-width as if it were at least twice the machine integer width,
+ so that timefns.c can safely use bignums for double-precision
+ timestamps. */
+ if (integer_width < bits && 2 * max (INTMAX_WIDTH, UINTMAX_WIDTH) < bits)
overflow_error ();
struct Lisp_Bignum *b = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Bignum,