emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 81e7eef: Fix bignum bugs with nth, elt, =


From: Paul Eggert
Subject: [Emacs-diffs] master 81e7eef: Fix bignum bugs with nth, elt, =
Date: Tue, 21 Aug 2018 14:41:59 -0400 (EDT)

branch: master
commit 81e7eef8224c8a99a207b7a7b9dae1d598392ef7
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/bytecode.c | 39 +++++++++++++--------------------------
 src/fns.c      |  5 ++---
 src/lisp.h     |  5 +++++
 3 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/src/bytecode.c b/src/bytecode.c
index b27fa7c..17457fc 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,
        CASE (Bnth):
          {
            Lisp_Object v2 = POP, v1 = TOP;
-           CHECK_FIXNUM (v1);
-           for (EMACS_INT n = XFIXNUM (v1); 0 < n && CONSP (v2); n--)
+           if (RANGED_FIXNUMP (0, v1, SMALL_LIST_LEN_MAX))
              {
-               v2 = XCDR (v2);
-               rarely_quit (n);
+               for (EMACS_INT n = XFIXNUM (v1); 0 < n && CONSP (v2); n--)
+                 v2 = XCDR (v2);
+               TOP = CAR (v2);
              }
-           TOP = CAR (v2);
+           else
+             TOP = Fnth (v1, v2);
            NEXT;
          }
 
@@ -985,15 +986,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
 
        CASE (Beqlsign):
          {
-           Lisp_Object v2 = POP, v1 = TOP;
-           if (FLOATP (v1) || FLOATP (v2))
-             TOP = arithcompare (v1, v2, ARITH_EQUAL);
-           else
-             {
-               CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER (v1);
-               CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER (v2);
-               TOP = EQ (v1, v2) ? Qt : Qnil;
-             }
+           Lisp_Object v1 = POP;
+           TOP = arithcompare (TOP, v1, ARITH_EQUAL);
            NEXT;
          }
 
@@ -1264,23 +1258,16 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object 
vector, Lisp_Object maxdepth,
 
        CASE (Belt):
          {
-           if (CONSP (TOP))
+           Lisp_Object v2 = POP, v1 = TOP;
+           if (CONSP (v1) && RANGED_FIXNUMP (0, v2, SMALL_LIST_LEN_MAX))
              {
-               /* Exchange args and then do nth.  */
-               Lisp_Object v2 = POP, v1 = TOP;
-               CHECK_FIXNUM (v2);
+               /* Like the fast case for Bnth, but with args reversed.  */
                for (EMACS_INT n = XFIXNUM (v2); 0 < n && CONSP (v1); n--)
-                 {
-                   v1 = XCDR (v1);
-                   rarely_quit (n);
-                 }
+                 v1 = XCDR (v1);
                TOP = CAR (v1);
              }
            else
-             {
-               Lisp_Object v1 = POP;
-               TOP = Felt (TOP, v1);
-             }
+             TOP = Felt (v1, v2);
            NEXT;
          }
 
diff --git a/src/fns.c b/src/fns.c
index 9d68101..b368ffd 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1418,7 +1418,7 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
       num = XFIXNUM (n);
 
       /* Speed up small lists by omitting circularity and quit checking.  */
-      if (num < 128)
+      if (num <= SMALL_LIST_LEN_MAX)
        {
          for (; 0 < num; num--, tail = XCDR (tail))
            if (! CONSP (tail))
@@ -1503,9 +1503,8 @@ N counts from zero.  If LIST is not that long, nil is 
returned.  */)
 
 DEFUN ("elt", Felt, Selt, 2, 2, 0,
        doc: /* Return element of SEQUENCE at index N.  */)
-  (register Lisp_Object sequence, Lisp_Object n)
+  (Lisp_Object sequence, Lisp_Object n)
 {
-  CHECK_FIXNUM (n);
   if (CONSP (sequence) || NILP (sequence))
     return Fcar (Fnthcdr (n, sequence));
 
diff --git a/src/lisp.h b/src/lisp.h
index 8f48a33..c5593b2 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4694,6 +4694,11 @@ enum
         Lisp_String))                                                  \
      : make_unibyte_string (str, len))
 
+/* The maximum length of "small" lists, as a heuristic.  These lists
+   are so short that code need not check for cycles or quits while
+   traversing.  */
+enum { SMALL_LIST_LEN_MAX = 127 };
+
 /* Loop over conses of the list TAIL, signaling if a cycle is found,
    and possibly quitting after each loop iteration.  In the loop body,
    set TAIL to the current cons.  If the loop exits normally,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]