aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-08-21 11:40:23 -0700
committerPaul Eggert2018-08-21 11:41:54 -0700
commit81e7eef8224c8a99a207b7a7b9dae1d598392ef7 (patch)
tree1404996c717b76961b02c6a238242d63afc23660 /src
parentad31afc35be2c64863a03b8f3995847332870cb6 (diff)
downloademacs-81e7eef8224c8a99a207b7a7b9dae1d598392ef7.tar.gz
emacs-81e7eef8224c8a99a207b7a7b9dae1d598392ef7.zip
Fix bignum bugs with nth, elt, =
* src/bytecode.c (exec_byte_code): Support bignums when implementing nth, elt, and =. * src/lisp.h (SMALL_LIST_LEN_MAX): New constant. * src/fns.c (Fnthcdr): Use it. (Felt): Do not reject bignum indexes.
Diffstat (limited to 'src')
-rw-r--r--src/bytecode.c39
-rw-r--r--src/fns.c5
-rw-r--r--src/lisp.h5
3 files changed, 20 insertions, 29 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index b27fa7c5c68..17457fc5742 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -832,13 +832,14 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
832 CASE (Bnth): 832 CASE (Bnth):
833 { 833 {
834 Lisp_Object v2 = POP, v1 = TOP; 834 Lisp_Object v2 = POP, v1 = TOP;
835 CHECK_FIXNUM (v1); 835 if (RANGED_FIXNUMP (0, v1, SMALL_LIST_LEN_MAX))
836 for (EMACS_INT n = XFIXNUM (v1); 0 < n && CONSP (v2); n--)
837 { 836 {
838 v2 = XCDR (v2); 837 for (EMACS_INT n = XFIXNUM (v1); 0 < n && CONSP (v2); n--)
839 rarely_quit (n); 838 v2 = XCDR (v2);
839 TOP = CAR (v2);
840 } 840 }
841 TOP = CAR (v2); 841 else
842 TOP = Fnth (v1, v2);
842 NEXT; 843 NEXT;
843 } 844 }
844 845
@@ -985,15 +986,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
985 986
986 CASE (Beqlsign): 987 CASE (Beqlsign):
987 { 988 {
988 Lisp_Object v2 = POP, v1 = TOP; 989 Lisp_Object v1 = POP;
989 if (FLOATP (v1) || FLOATP (v2)) 990 TOP = arithcompare (TOP, v1, ARITH_EQUAL);
990 TOP = arithcompare (v1, v2, ARITH_EQUAL);
991 else
992 {
993 CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER (v1);
994 CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER (v2);
995 TOP = EQ (v1, v2) ? Qt : Qnil;
996 }
997 NEXT; 991 NEXT;
998 } 992 }
999 993
@@ -1264,23 +1258,16 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1264 1258
1265 CASE (Belt): 1259 CASE (Belt):
1266 { 1260 {
1267 if (CONSP (TOP)) 1261 Lisp_Object v2 = POP, v1 = TOP;
1262 if (CONSP (v1) && RANGED_FIXNUMP (0, v2, SMALL_LIST_LEN_MAX))
1268 { 1263 {
1269 /* Exchange args and then do nth. */ 1264 /* Like the fast case for Bnth, but with args reversed. */
1270 Lisp_Object v2 = POP, v1 = TOP;
1271 CHECK_FIXNUM (v2);
1272 for (EMACS_INT n = XFIXNUM (v2); 0 < n && CONSP (v1); n--) 1265 for (EMACS_INT n = XFIXNUM (v2); 0 < n && CONSP (v1); n--)
1273 { 1266 v1 = XCDR (v1);
1274 v1 = XCDR (v1);
1275 rarely_quit (n);
1276 }
1277 TOP = CAR (v1); 1267 TOP = CAR (v1);
1278 } 1268 }
1279 else 1269 else
1280 { 1270 TOP = Felt (v1, v2);
1281 Lisp_Object v1 = POP;
1282 TOP = Felt (TOP, v1);
1283 }
1284 NEXT; 1271 NEXT;
1285 } 1272 }
1286 1273
diff --git a/src/fns.c b/src/fns.c
index 9d681017c14..b368ffd58f2 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1418,7 +1418,7 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
1418 num = XFIXNUM (n); 1418 num = XFIXNUM (n);
1419 1419
1420 /* Speed up small lists by omitting circularity and quit checking. */ 1420 /* Speed up small lists by omitting circularity and quit checking. */
1421 if (num < 128) 1421 if (num <= SMALL_LIST_LEN_MAX)
1422 { 1422 {
1423 for (; 0 < num; num--, tail = XCDR (tail)) 1423 for (; 0 < num; num--, tail = XCDR (tail))
1424 if (! CONSP (tail)) 1424 if (! CONSP (tail))
@@ -1503,9 +1503,8 @@ N counts from zero. If LIST is not that long, nil is returned. */)
1503 1503
1504DEFUN ("elt", Felt, Selt, 2, 2, 0, 1504DEFUN ("elt", Felt, Selt, 2, 2, 0,
1505 doc: /* Return element of SEQUENCE at index N. */) 1505 doc: /* Return element of SEQUENCE at index N. */)
1506 (register Lisp_Object sequence, Lisp_Object n) 1506 (Lisp_Object sequence, Lisp_Object n)
1507{ 1507{
1508 CHECK_FIXNUM (n);
1509 if (CONSP (sequence) || NILP (sequence)) 1508 if (CONSP (sequence) || NILP (sequence))
1510 return Fcar (Fnthcdr (n, sequence)); 1509 return Fcar (Fnthcdr (n, sequence));
1511 1510
diff --git a/src/lisp.h b/src/lisp.h
index 8f48a334844..c5593b21008 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4694,6 +4694,11 @@ enum
4694 Lisp_String)) \ 4694 Lisp_String)) \
4695 : make_unibyte_string (str, len)) 4695 : make_unibyte_string (str, len))
4696 4696
4697/* The maximum length of "small" lists, as a heuristic. These lists
4698 are so short that code need not check for cycles or quits while
4699 traversing. */
4700enum { SMALL_LIST_LEN_MAX = 127 };
4701
4697/* Loop over conses of the list TAIL, signaling if a cycle is found, 4702/* Loop over conses of the list TAIL, signaling if a cycle is found,
4698 and possibly quitting after each loop iteration. In the loop body, 4703 and possibly quitting after each loop iteration. In the loop body,
4699 set TAIL to the current cons. If the loop exits normally, 4704 set TAIL to the current cons. If the loop exits normally,