changeset 4885:6772ce4d982b

Fix hash tables, #'member*, #'assoc*, #'eql compiler macros if bignums lisp/ChangeLog addition: 2010-01-24 Aidan Kehoe <kehoea@parhasard.net> Correct the semantics of #'member*, #'eql, #'assoc* in the presence of bignums; change the integerp byte code to fixnump semantics. * bytecomp.el (fixnump, integerp, byte-compile-integerp): Change the integerp byte code to fixnump; add a byte-compile method to integerp using fixnump and numberp and avoiding a funcall most of the time, since in the non-core contexts where integerp is used, it's mostly distinguishing between fixnums and things that are not numbers at all. * byte-optimize.el (side-effect-free-fns, byte-after-unbind-ops) (byte-compile-side-effect-and-error-free-ops): Replace the integerp bytecode with fixnump; add fixnump to the side-effect-free-fns. Add the other extended number type predicates to the list in passing. * obsolete.el (floatp-safe): Mark this as obsolete. * cl.el (eql): Go into more detail in the docstring here. Don't bother checking whether both arguments are numbers; one is enough, #'equal will fail correctly if they have distinct types. (subst): Replace a call to #'integerp (deciding whether to use #'memq or not) with one to #'fixnump. Delete most-positive-fixnum, most-negative-fixnum from this file; they're now always in C, so they can't be modified from Lisp. * cl-seq.el (member*, assoc*, rassoc*): Correct these functions in the presence of bignums. * cl-macs.el (cl-make-type-test): The type test for a fixnum is now fixnump. Ditch floatp-safe, use floatp instead. (eql): Correct this compiler macro in the presence of bignums. (assoc*): Correct this compiler macro in the presence of bignums. * simple.el (undo): Change #'integerp to #'fixnump here, since we use #'delq with the same value as ELT a few lines down. src/ChangeLog addition: 2010-01-24 Aidan Kehoe <kehoea@parhasard.net> Fix problems with #'eql, extended number types, and the hash table implementation; change the Bintegerp bytecode to fixnump semantics even on bignum builds, since #'integerp can have a fast implementation in terms of #'fixnump for most of its extant uses, but not vice-versa. * lisp.h: Always #include number.h; we want the macros provided in it, even if the various number types are not available. * number.h (NON_FIXNUM_NUMBER_P): New macro, giving 1 when its argument is of non-immediate number type. Equivalent to FLOATP if WITH_NUMBER_TYPES is not defined. * elhash.c (lisp_object_eql_equal, lisp_object_eql_hash): Use NON_FIXNUM_NUMBER_P in these functions, instead of FLOATP, giving more correct behaviour in the presence of the extended number types. * bytecode.c (Bfixnump, execute_optimized_program): Rename Bintegerp to Bfixnump; change its semantics to reflect the new name on builds with bignum support. * data.c (Ffixnump, Fintegerp, syms_of_data, vars_of_data): Always make #'fixnump available, even on non-BIGNUM builds; always implement #'integerp in this file, even on BIGNUM builds. Move most-positive-fixnum, most-negative-fixnum here from number.c, so they are Lisp constants even on builds without number types, and attempts to change or bind them error. Use the NUMBERP and INTEGERP macros even on builds without extended number types. * data.c (fixnum_char_or_marker_to_int): Rename this function from integer_char_or_marker_to_int, to better reflect the arguments it accepts. * number.c (Fevenp, Foddp, syms_of_number): Never provide #'integerp in this file. Remove #'oddp, #'evenp; their implementations are overridden by those in cl.el. * number.c (vars_of_number): most-positive-fixnum, most-negative-fixnum are no longer here. man/ChangeLog addition: 2010-01-23 Aidan Kehoe <kehoea@parhasard.net> Generally: be careful to say fixnum, not integer, when talking about fixed-precision integral types. I'm sure I've missed instances, both here and in the docstrings, but this is a decent start. * lispref/text.texi (Columns): Document where only fixnums, not integers generally, are accepted. (Registers): Remove some ancient char-int confoundance here. * lispref/strings.texi (Creating Strings, Creating Strings): Be more exact in describing where fixnums but not integers in general are accepted. (Creating Strings): Use a more contemporary example to illustrate how concat deals with lists including integers about #xFF. Delete some obsolete documentation on same. (Char Table Types): Document that only fixnums are accepted as values in syntax tables. * lispref/searching.texi (String Search, Search and Replace): Be exact in describing where fixnums but not integers in general are accepted. * lispref/range-tables.texi (Range Tables): Be exact in describing them; only fixnums are accepted to describe ranges. * lispref/os.texi (Killing XEmacs, User Identification) (Time of Day, Time Conversion): Be more exact about using fixnum where only fixed-precision integers are accepted. * lispref/objects.texi (Integer Type): Be more exact (and up-to-date) about the possible values for integers. Cross-reference to documentation of the bignum extension. (Equality Predicates): (Range Table Type): (Array Type): Use fixnum, not integer, to describe a fixed-precision integer. (Syntax Table Type): Correct some English syntax here. * lispref/numbers.texi (Numbers): Change the phrasing here to use fixnum to mean the fixed-precision integers normal in emacs. Document that our terminology deviates from that of Common Lisp, and that we're working on it. (Compatibility Issues): Reiterate the Common Lisp versus Emacs Lisp compatibility issues. (Comparison of Numbers, Arithmetic Operations): * lispref/commands.texi (Command Loop Info, Working With Events): * lispref/buffers.texi (Modification Time): Be more exact in describing where fixnums but not integers in general are accepted.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 24 Jan 2010 15:21:27 +0000
parents e533a9912ef1
children 1e9078742fa7
files lisp/ChangeLog lisp/byte-optimize.el lisp/bytecomp.el lisp/cl-macs.el lisp/cl-seq.el lisp/cl.el lisp/obsolete.el lisp/simple.el man/ChangeLog man/lispref/buffers.texi man/lispref/commands.texi man/lispref/numbers.texi man/lispref/objects.texi man/lispref/os.texi man/lispref/positions.texi man/lispref/processes.texi man/lispref/range-tables.texi man/lispref/searching.texi man/lispref/strings.texi man/lispref/text.texi src/ChangeLog src/bytecode.c src/data.c src/elhash.c src/lisp.h src/number.c src/number.h tests/automated/lisp-tests.el
diffstat 28 files changed, 450 insertions(+), 232 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/ChangeLog	Sun Jan 24 15:21:27 2010 +0000
@@ -1,3 +1,41 @@
+2010-01-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Correct the semantics of #'member*, #'eql, #'assoc* in the
+	presence of bignums; change the integerp byte code to fixnump
+	semantics.
+
+	* bytecomp.el (fixnump, integerp, byte-compile-integerp): 
+	Change the integerp byte code to fixnump; add a byte-compile
+	method to integerp using fixnump and numberp and avoiding a
+	funcall most of the time, since in the non-core contexts where
+	integerp is used, it's mostly distinguishing between fixnums and
+	things that are not numbers at all.
+	* byte-optimize.el (side-effect-free-fns, byte-after-unbind-ops)
+	(byte-compile-side-effect-and-error-free-ops):
+	Replace the integerp bytecode with fixnump; add fixnump to the
+	side-effect-free-fns. Add the other extended number type
+	predicates to the list in passing.
+
+	* obsolete.el (floatp-safe): Mark this as obsolete.
+
+	* cl.el (eql): Go into more detail in the docstring here. Don't
+	bother checking whether both arguments are numbers; one is enough,
+	#'equal will fail correctly if they have distinct types.
+	(subst): Replace a call to #'integerp (deciding whether to use
+	#'memq or not) with one to #'fixnump.
+	Delete most-positive-fixnum, most-negative-fixnum from this file;
+	they're now always in C, so they can't be modified from Lisp.
+	* cl-seq.el (member*, assoc*, rassoc*):
+	Correct these functions in the presence of bignums.
+	* cl-macs.el (cl-make-type-test): The type test for a fixnum is
+	now fixnump. Ditch floatp-safe, use floatp instead.
+	(eql): Correct this compiler macro in the presence of bignums.
+	(assoc*): Correct this compiler macro in the presence of bignums.
+
+	* simple.el (undo): 
+	Change #'integerp to #'fixnump here, since we use #'delq with the
+	same value as ELT a few lines down.
+
 2010-01-20  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* simple.el (handle-pre-motion-command-current-command-is-motion):
--- a/lisp/byte-optimize.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/byte-optimize.el	Sun Jan 24 15:21:27 2010 +0000
@@ -1209,12 +1209,12 @@
 (let ((side-effect-free-fns
        '(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan
 	 assoc assq
-	 boundp buffer-file-name buffer-local-variables buffer-modified-p
-	 buffer-substring
+	 bigfloat-get-precision boundp buffer-file-name buffer-local-variables
+	 buffer-modified-p buffer-substring
 	 capitalize car-less-than-car car cdr ceiling concat
 	 ;; coordinates-in-window-p not in XEmacs
 	 copy-marker cos count-lines
-	 default-boundp default-value documentation downcase
+	 default-boundp default-value denominator documentation downcase
 	 elt exp expt fboundp featurep
 	 file-directory-p file-exists-p file-locked-p file-name-absolute-p
 	 file-newer-than-file-p file-readable-p file-symlink-p file-writable-p
@@ -1233,7 +1233,7 @@
 	 int-to-string
 	 length log log10 logand logb logior lognot logxor lsh
 	 marker-buffer max member memq min mod
-	 next-window nth nthcdr number-to-string
+	 next-window nth nthcdr number-to-string numerator
 	 parse-colon-path plist-get previous-window
 	 radians-to-degrees rassq regexp-quote reverse round
 	 sin sqrt string< string= string-equal string-lessp string-to-char
@@ -1252,7 +1252,8 @@
 	 ))
       (side-effect-and-error-free-fns
        '(arrayp atom
-	 bobp bolp buffer-end buffer-list buffer-size buffer-string bufferp
+	 bigfloatp bignump bobp bolp buffer-end buffer-list buffer-size
+	 buffer-string bufferp
 	 car-safe case-table-p cdr-safe char-or-string-p char-table-p
 	 characterp commandp cons
 	 consolep console-live-p consp
@@ -1260,7 +1261,7 @@
 	 ;; XEmacs: extent functions, frame-live-p, various other stuff
 	 devicep device-live-p
 	 dot dot-marker eobp eolp eq eql equal eventp extentp
-	 extent-live-p floatp framep frame-live-p
+	 extent-live-p fixnump floatingp floatp framep frame-live-p
 	 get-largest-window get-lru-window
 	 hash-table-p
 	 identity ignore integerp integer-or-marker-p interactive-p
@@ -1271,14 +1272,14 @@
 	 natnump nlistp not null number-or-marker-p numberp
 	 one-window-p ;; overlayp not in XEmacs
 	 point point-marker point-min point-max processp
-	 range-table-p
+	 rationalp ratiop range-table-p realp
 	 selected-window sequencep stringp subrp symbolp syntax-table-p
 	 user-full-name user-login-name user-original-login-name
 	 user-real-login-name user-real-uid user-uid
 	 vector vectorp
 	 window-configuration-p window-live-p windowp
 	 ;; Functions defined by cl
-	 eql floatp-safe list* subst acons equalp random-state-p
+	 eql list* subst acons equalp random-state-p
 	 copy-tree sublis
 	 )))
   (dolist (fn side-effect-free-fns)
@@ -1456,7 +1457,7 @@
 
 (defconst byte-after-unbind-ops
    '(byte-constant byte-dup
-     byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp
+     byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-fixnump
      byte-eq byte-not
      byte-cons byte-list1 byte-list2	; byte-list3 byte-list4
      byte-interactive-p)
@@ -1469,7 +1470,7 @@
 
 (defconst byte-compile-side-effect-and-error-free-ops
   '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp
-    byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe
+    byte-fixnump byte-numberp byte-eq byte-equal byte-not byte-car-safe
     byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max
     byte-point-min byte-following-char byte-preceding-char
     byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp
--- a/lisp/bytecomp.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/bytecomp.el	Sun Jan 24 15:21:27 2010 +0000
@@ -734,7 +734,7 @@
 (byte-defop 165 -1 byte-quo)
 (byte-defop 166 -1 byte-rem)
 (byte-defop 167  0 byte-numberp)
-(byte-defop 168  0 byte-integerp)
+(byte-defop 168  0 byte-fixnump)
 
 ;; unused: 169
 
@@ -3101,7 +3101,7 @@
 (byte-defop-compiler car-safe		1)
 (byte-defop-compiler cdr-safe		1)
 (byte-defop-compiler numberp		1)
-(byte-defop-compiler integerp		1)
+(byte-defop-compiler fixnump		1)
 (byte-defop-compiler skip-chars-forward     1-2+1)
 (byte-defop-compiler skip-chars-backward    1-2+1)
 (byte-defop-compiler (eql byte-eq) 	2)
@@ -3817,6 +3817,8 @@
 (byte-defop-compiler-1 let)
 (byte-defop-compiler-1 let*)
 
+(byte-defop-compiler-1 integerp)
+
 (defun byte-compile-progn (form)
   (byte-compile-body-do-effect (cdr form)))
 
@@ -3999,6 +4001,55 @@
 	(byte-compile-warn-about-unused-variables))
     (byte-compile-out 'byte-unbind (length (car (cdr form))))))
 
+;; We've renamed the integerp bytecode to fixnump, and changed its semantics
+;; accordingly.  This means #'integerp itself can't be as fast as it used to
+;; be, since it no longer has a bytecode to itself.  As it happens, though,
+;; most of the non-core calls to #'integerp are in contexts where it is
+;; either going to receive a fixnum, or something non-numeric entirely; the
+;; contexts where it needs to distinguish between an integer and a float are
+;; very rare. So, we can have (integerp X) compile to:
+;;
+;; (or (fixnump X) (and (numberp X) (funcall #'integerp X)))
+;;
+;; without the multiple evaluation of X, and where #'fixnump and #'numberp
+;; both have bytecodes. We ignore for-effect, because byte-optimize.el will
+;; delete this call in its presence.
+;;
+;; This approach is byte-code compatible with 21.4 and with earlier 21.5
+;; (except that earlier 21.5 with bignum support will confuse Bfixnump and
+;; Bintegerp; which it did in dealing with byte-compiled code from 21.4
+;; anyway).
+
+(defun byte-compile-integerp (form)
+  (if (/= 2 (length form))
+      (byte-compile-subr-wrong-args form 1)
+    (let ((donetag (byte-compile-make-tag))
+	  (wintag (byte-compile-make-tag))
+	  (failtag (byte-compile-make-tag)))
+      (byte-compile-constant 'integerp)
+      (byte-compile-form (second form))
+      (byte-compile-out 'byte-dup 0)
+      (byte-compile-out 'byte-fixnump 0)
+      (byte-compile-goto 'byte-goto-if-not-nil wintag)
+      (byte-compile-out 'byte-dup 0)
+      (byte-compile-out 'byte-numberp 0)
+      (byte-compile-goto 'byte-goto-if-nil failtag)
+      (byte-compile-out 'byte-call 1)
+      ;; At this point, the only thing from this function remaining on the
+      ;; stack is the return value of the called #'integerp, which reflects
+      ;; exactly what we want. Go directly to donetag, do not discard
+      ;; anything.
+      (byte-compile-goto 'byte-goto donetag)
+      (byte-compile-out-tag failtag)
+      (byte-compile-discard)
+      (byte-compile-discard)
+      (byte-compile-constant nil)
+      (byte-compile-goto 'byte-goto donetag)
+      (byte-compile-out-tag wintag)
+      (byte-compile-discard)
+      (byte-compile-discard)
+      (byte-compile-constant t)
+      (byte-compile-out-tag donetag))))
 
 ;;(byte-defop-compiler-1 /= byte-compile-negated)
 (byte-defop-compiler-1 atom byte-compile-negated)
--- a/lisp/cl-macs.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/cl-macs.el	Sun Jan 24 15:21:27 2010 +0000
@@ -3026,9 +3026,9 @@
 	     (cl-make-type-test val (funcall (get type 'cl-deftype-handler))))
 	    ((memq type '(nil t)) type)
 	    ((eq type 'null) `(null ,val))
-	    ((eq type 'float) `(floatp-safe ,val))
+	    ((eq type 'float) `(floatp ,val))
 	    ((eq type 'real) `(numberp ,val))
-	    ((eq type 'fixnum) `(integerp ,val))
+	    ((eq type 'fixnum) `(fixnump ,val))
 	    ;; XEmacs change: we do not have char-valid-p
 	    ((memq type '(character string-char)) `(characterp ,val))
 	    (t
@@ -3205,12 +3205,12 @@
 (define-compiler-macro eql (&whole form a b)
   (cond ((eq (cl-const-expr-p a) t)
 	 (let ((val (cl-const-expr-val a)))
-	   (if (and (numberp val) (not (integerp val)))
+	   (if (and (numberp val) (not (fixnump val)))
 	       (list 'equal a b)
 	     (list 'eq a b))))
 	((eq (cl-const-expr-p b) t)
 	 (let ((val (cl-const-expr-val b)))
-	   (if (and (numberp val) (not (integerp val)))
+	   (if (and (numberp val) (not (fixnump val)))
 	       (list 'equal a b)
 	     (list 'eq a b))))
 	((cl-simple-expr-p a 5)
@@ -3226,20 +3226,25 @@
 
 (define-compiler-macro member* (&whole form a list &rest keys)
   (let ((test (and (= (length keys) 2) (eq (car keys) :test)
-		   (cl-const-expr-val (nth 1 keys)))))
+		   (cl-const-expr-val (nth 1 keys))))
+	a-val)
     (cond ((eq test 'eq) (list 'memq a list))
 	  ((eq test 'equal) (list 'member a list))
 	  ((or (null keys) (eq test 'eql))
 	   (if (eq (cl-const-expr-p a) t)
-	       (list (if (floatp-safe (cl-const-expr-val a)) 'member 'memq)
+	       (list (if (and (numberp (setq a-val (cl-const-expr-val a)))
+			      (not (fixnump a-val)))
+			 'member
+		       'memq)
 		     a list)
 	     (if (eq (cl-const-expr-p list) t)
 		 (let ((p (cl-const-expr-val list)) (mb nil) (mq nil))
 		   (if (not (cdr p))
 		       (and p (list 'eql a (list 'quote (car p))))
 		     (while p
-		       (if (floatp-safe (car p)) (setq mb t)
-			 (or (integerp (car p)) (symbolp (car p)) (setq mq t)))
+		       (if (and (numberp (car p)) (not (fixnump (car p))))
+			   (setq mb t)
+			 (or (fixnump (car p)) (symbolp (car p)) (setq mq t)))
 		       (setq p (cdr p)))
 		     (if (not mb) (list 'memq a list)
 		       (if (not mq) (list 'member a list) form))))
@@ -3248,11 +3253,13 @@
 
 (define-compiler-macro assoc* (&whole form a list &rest keys)
   (let ((test (and (= (length keys) 2) (eq (car keys) :test)
-		   (cl-const-expr-val (nth 1 keys)))))
+		   (cl-const-expr-val (nth 1 keys))))
+	a-val)
     (cond ((eq test 'eq) (list 'assq a list))
 	  ((eq test 'equal) (list 'assoc a list))
 	  ((and (eq (cl-const-expr-p a) t) (or (null keys) (eq test 'eql)))
-	   (if (floatp-safe (cl-const-expr-val a))
+	   (if (and (numberp (setq a-val (cl-const-expr-val a)))
+		    (not (fixnump a-val)))
 	       (list 'assoc a list) (list 'assq a list)))
 	  (t form))))
 
@@ -3511,7 +3518,7 @@
    (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr)))
 
 ;;; Things that are inline.
-(proclaim '(inline floatp-safe acons map concatenate notany notevery
+(proclaim '(inline acons map concatenate notany notevery
 ;; XEmacs omission: gethash is builtin
 		   cl-set-elt revappend nreconc))
 
@@ -3523,7 +3530,7 @@
 
 ;;; Things that are side-effect-and-error-free.  Moved to byte-optimize.el
 ;(mapcar (function (lambda (x) (put x 'side-effect-free 'error-free)))
-;	'(eql floatp-safe list* subst acons equalp random-state-p
+;	'(eql list* subst acons equalp random-state-p
 ;	  copy-tree sublis))
 
 
--- a/lisp/cl-seq.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/cl-seq.el	Sun Jan 24 15:21:27 2010 +0000
@@ -664,7 +664,7 @@
 	(while (and cl-list (not (cl-check-test cl-item (car cl-list))))
 	  (setq cl-list (cdr cl-list)))
 	cl-list)
-    (if (and (numberp cl-item) (not (integerp cl-item)))
+    (if (and (numberp cl-item) (not (fixnump cl-item)))
 	(member cl-item cl-list)
       (memq cl-item cl-list))))
 
@@ -697,7 +697,7 @@
 			(not (cl-check-test cl-item (car (car cl-alist))))))
 	  (setq cl-alist (cdr cl-alist)))
 	(and cl-alist (car cl-alist)))
-    (if (and (numberp cl-item) (not (integerp cl-item)))
+    (if (and (numberp cl-item) (not (fixnump cl-item)))
 	(assoc cl-item cl-alist)
       (assq cl-item cl-alist))))
 
@@ -714,7 +714,7 @@
 (defun rassoc* (cl-item cl-alist &rest cl-keys)
   "Find the first item whose cdr matches ITEM in LIST.
 Keywords supported:  :test :test-not :key"
-  (if (or cl-keys (numberp cl-item))
+  (if (or cl-keys (and (numberp cl-item) (not (fixnump cl-item))))
       (cl-parsing-keywords (:test :test-not :key :if :if-not) ()
 	(while (and cl-alist
 		    (or (not (consp (car cl-alist)))
--- a/lisp/cl.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/cl.el	Sun Jan 24 15:21:27 2010 +0000
@@ -123,10 +123,17 @@
 ;;; Predicates.
 
 (defun eql (a b)    ; See compiler macro in cl-macs.el
-  "Return t if the two args are the same Lisp object.
-Floating-point numbers of equal value are `eql', but they may not be `eq'."
-  (or (eq a b)
-      (and (numberp a) (numberp b) (equal a b))))
+  "Return t if the arguments are the same Lisp object, or numerically equal.
+
+They must be of the same type; the difference between `eq' and `eql' is most
+relevant when it comes to the non-fixnum number types.  In this
+implementation, fixnums of the same numeric value are always `eq', but this
+is not true for other numeric types, among them floats, bignums and ratios,
+if available.
+
+See also `=' (which doesn't require that its arguments be of the same type,
+but only accepts numeric arguments, characters and markers) and `equal'."
+  (or (eq a b) (and (numberp a) (equal a b))))
 
 ;;; Generalized variables.  These macros are defined here so that they
 ;;; can safely be used in .emacs files.
@@ -317,11 +324,7 @@
 
 ;;; Numbers.
 
-;; XEmacs change: use floatp, which is right even in the presence of ratios
-;; and bigfloats
-(defun floatp-safe (object)
-  "Return t if OBJECT is a floating point number."
-  (floatp object))
+;; XEmacs change: ditch floatp-safe.
 
 (defun plusp (number)
   "Return t if NUMBER is positive."
@@ -344,15 +347,6 @@
 
 (defvar *random-state* (vector 'cl-random-state-tag -1 30 (cl-random-time)))
 
-;; XEmacs: These constants are defined in C when 'number-types is provided.
-;; They are always defined in C on Emacs.  Maybe we should, too.
-(unless (featurep 'number-types)
-;;; We use `eval' in case VALBITS differs from compile-time to load-time.
-  (defconst most-positive-fixnum (eval '(lsh -1 -1))
-    "The integer closest in value to positive infinity.")
-  (defconst most-negative-fixnum (eval '(- -1 (lsh -1 -1)))
-    "The integer closest in value to negative infinity."))
-
 ;;; The following are set by code in cl-extra.el
 (defconst most-positive-float nil
   "The float closest in value to positive infinity.")
@@ -616,7 +610,7 @@
   "Substitute NEW for OLD everywhere in TREE (non-destructively).
 Return a copy of TREE with all elements `eql' to OLD replaced by NEW.
 Keywords supported:  :test :test-not :key"
-  (if (or cl-keys (and (numberp cl-old) (not (integerp cl-old))))
+  (if (or cl-keys (and (numberp cl-old) (not (fixnump cl-old))))
       (apply 'sublis (list (cons cl-old cl-new)) cl-tree cl-keys)
     (cl-do-subst cl-new cl-old cl-tree)))
 
--- a/lisp/obsolete.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/obsolete.el	Sun Jan 24 15:21:27 2010 +0000
@@ -275,6 +275,9 @@
 ;; being called on the values of functions known to return keymaps,
 ;; or known to return vectors of events instead of strings...
 
+;;; Yes there is; make compiler macros for aref, assq, nconc, checking that
+;;; the car of the relevant argument is sane.
+
 (make-obsolete-variable 'executing-macro 'executing-kbd-macro)
 
 (define-compatible-function-alias 'interactive-form 
--- a/lisp/simple.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/lisp/simple.el	Sun Jan 24 15:21:27 2010 +0000
@@ -957,7 +957,7 @@
     (let ((tail buffer-undo-list)
 	  done)
       (while (and tail (not done) (not (null (car tail))))
-	(if (integerp (car tail))
+	(if (fixnump (car tail))
 	    (progn
 	      (setq done t)
 	      (setq buffer-undo-list (delq (car tail) buffer-undo-list))))
--- a/man/ChangeLog	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/ChangeLog	Sun Jan 24 15:21:27 2010 +0000
@@ -1,3 +1,51 @@
+2010-01-23  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Generally: be careful to say fixnum, not integer, when talking
+	about fixed-precision integral types. I'm sure I've missed
+	instances, both here and in the docstrings, but this is a decent
+	start.
+
+	* lispref/text.texi (Columns): 
+	Document where only fixnums, not integers generally, are accepted.
+	(Registers):
+	Remove some ancient char-int confoundance here.
+	* lispref/strings.texi (Creating Strings, Creating Strings):
+	Be more exact in describing where fixnums but not integers in
+	general are accepted.
+	(Creating Strings): Use a more contemporary example to illustrate
+	how concat deals with lists including integers about #xFF.  Delete
+	some obsolete documentation on same.
+	(Char Table Types): Document that only fixnums are accepted as
+	values in syntax tables.
+	* lispref/searching.texi (String Search, Search and Replace):
+	Be exact in describing where fixnums but not integers in general
+	are accepted.
+	* lispref/range-tables.texi (Range Tables): Be exact in describing
+	them; only fixnums are accepted to describe ranges.
+	* lispref/os.texi (Killing XEmacs, User Identification)
+	(Time of Day, Time Conversion):
+	Be more exact about using fixnum where only fixed-precision
+	integers are accepted.
+	* lispref/objects.texi (Integer Type): Be more exact (and
+	up-to-date) about the possible values for
+	integers. Cross-reference to documentation of the bignum extension.
+	(Equality Predicates):
+	(Range Table Type):
+	(Array Type): Use fixnum, not integer, to describe a
+	fixed-precision integer.
+	(Syntax Table Type): Correct some English syntax here.
+	* lispref/numbers.texi (Numbers): Change the phrasing here to use
+	fixnum to mean the fixed-precision integers normal in emacs.
+	Document that our terminology deviates from that of Common Lisp,
+	and that we're working on it.
+	(Compatibility Issues): Reiterate the Common Lisp versus Emacs
+	Lisp compatibility issues.
+	(Comparison of Numbers, Arithmetic Operations):
+	* lispref/commands.texi (Command Loop Info, Working With Events): 
+	* lispref/buffers.texi (Modification Time): 
+	Be more exact in describing where fixnums but not integers in
+	general are accepted.
+
 2010-01-06  Jerry James  <james@xemacs.org>
 
 	* internals/internals.texi (Debugging and Testing): Document
--- a/man/lispref/buffers.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/buffers.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -524,7 +524,7 @@
 
 If @var{time} is not @code{nil}, it should have the form
 @code{(@var{high} . @var{low})} or @code{(@var{high} @var{low})}, in
-either case containing two integers, each of which holds 16 bits of the
+either case containing two fixnums, each of which holds 16 bits of the
 time.
 
 This function is useful if the buffer was not read from the file
--- a/man/lispref/commands.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/commands.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -762,7 +762,7 @@
 
 @defvar echo-keystrokes
 This variable determines how much time should elapse before command
-characters echo.  Its value must be an integer, which specifies the
+characters echo.  Its value must be a float or a fixnum, which specifies the
 number of seconds to wait before echoing.  If the user types a prefix
 key (say @kbd{C-x}) and then delays this many seconds before continuing,
 the key @kbd{C-x} is echoed in the echo area.  Any subsequent characters
@@ -1324,7 +1324,7 @@
 
 @item @code{button}
 The event button.  This an integer, either 1, 2 or 3.  It is allowed
-only for button-press and button-release events.
+for button-press, button-release and misc-user events.
 
 @item @code{modifiers}
 The event modifiers.  This is a list of modifier symbols.  It is allowed
--- a/man/lispref/numbers.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/numbers.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -9,13 +9,13 @@
 @cindex integers
 @cindex numbers
 
-  XEmacs supports two to five numeric data types.  @dfn{Integers} and
+  XEmacs supports two to five numeric data types.  @dfn{Fixnums} and
 @dfn{floating point numbers} are always supported.  As a build-time
 option, @dfn{bignums}, @dfn{ratios}, and @dfn{bigfloats} may be
 enabled on some platforms.
 
-  Integers, which are what Common Lisp calls
-@dfn{fixnums}, are whole numbers such as @minus{}3, 0, #b0111, #xFEED,
+  Fixnums (called just @dfn{integers} in GNU Emacs and older versions
+of XEmacs) are whole numbers such as @minus{}3, 0, #b0111, #xFEED,
 #o744.  Their values are exact, and their range is limited.  The
 number prefixes `#b', `#o', and `#x' are supported to represent numbers
 in binary, octal, and hexadecimal notation (or radix).  Floating point
@@ -52,14 +52,15 @@
 The exact rules are more carefully explained elsewhere
 (@pxref{Canonicalization and Contagion}).
 
-  Note that the term ``integer'' is used throughout the XEmacs
-documentation and code to mean ``fixnum''.  This is inconsistent with
-Common Lisp, and likely to cause confusion.  Similarly, ``float'' is
-used to mean ``fixed precision floating point number'', and the Common
-Lisp distinctions among @dfn{short-floats}, @dfn{long-floats},
-@emph{etc.}, and bigfloats (which are not standardized in Common Lisp)
-are not reflected in XEmacs terminology.  (Volunteers to fix this in the
-XEmacs manuals would be heartily welcomed.)
+  Common Lisp terminology and historical Emacs terminology conflict
+here, to an extent.  We attempt to use ``fixnum'' and ``integer''
+consistently, but older XEmacs and GNU Emacs code and documentation use
+the latter to mean the former.  ``Float'' is used in Emacs documentation
+to mean ``fixed precision floating point number'', and the Common Lisp
+distinctions among @dfn{short-floats}, @dfn{long-floats}, @emph{etc.},
+and bigfloats (which are not standardized in Common Lisp) are not
+reflected in XEmacs terminology.  We're working on this, but volunteers
+to fix it in the XEmacs manuals would be heartily welcomed.
 
 @menu
 * Integer Basics::            Representation and range of integers.
@@ -541,12 +542,11 @@
 yet.)
 
 @item
-Terminology is not Common-Lisp-conforming.  For example, ``integer'' for
-Emacs Lisp means what Common Lisp calls ``fixnum''.  This issue is being
-investigated, but the use of ``integer'' for fixnum is pervasive and may
-cause backward-compatibility and GNU-Emacs-compatibility problems.
-There are similar issues for floating point numbers.  Since Emacs Lisp
-has not had a ratio type before, there should be no problems there.
+Our documentation's terminology, and our API terminology, is not always
+Common-Lisp-conforming.  Many places use ``integer'' where ``fixnum''
+better reflects what the code accepts or produces; there are similar
+issues for the varying types of floating point numbers.  Since Emacs
+Lisp has not had a ratio type before, there are no problems there.
 
 @item
 An atom with ratio read syntax now returns a number, not a symbol.
@@ -759,8 +759,8 @@
 @b{Common Lisp note:} Comparing numbers in Common Lisp always requires
 @code{=} because Common Lisp implements multi-word integers, and two
 distinct integer objects can have the same numeric value.  XEmacs Lisp
-can have just one integer object for any given value because it has a
-limited range of integer values.
+can have just one fixnum object for any given value because it has a
+limited range of fixnum values.
 @end quotation
 
 In addition to numbers, all of the following functions also accept
@@ -914,7 +914,8 @@
 
   It is important to note that in XEmacs Lisp, arithmetic functions
 do not check for overflow.  Thus @code{(1+ 134217727)} may evaluate to
-@minus{}134217728, depending on your hardware.
+@minus{}134217728, depending on your hardware and whether your XEmacs
+supports bignums.
 
 @defun 1+ number
 This function returns @var{number} plus one.  @var{number} may be a
--- a/man/lispref/objects.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/objects.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -290,31 +290,25 @@
 @node Integer Type
 @subsection Integer Type
 
-  The range of values for integers in XEmacs Lisp is @minus{}134217728 to
-134217727 (28 bits; i.e.,
-@ifinfo
--2**27
-@end ifinfo
-@tex
-$-2^{27}$
-@end tex
-to
-@ifinfo
-2**27 - 1)
-@end ifinfo
-@tex
-$2^{28}-1$)
-@end tex
-on most machines.  (Some machines, in particular 64-bit machines such as
-the DEC Alpha, may provide a wider range.)  It is important to note that
-the XEmacs Lisp arithmetic functions do not check for overflow.  Thus
-@code{(1+ 134217727)} is @minus{}134217728 on most machines. (However,
-you @emph{will} get an error if you attempt to read an out-of-range
-number using the Lisp reader.)
-
-  The read syntax for integers is a sequence of (base ten) digits with
-an optional sign at the beginning. (The printed representation produced
-by the Lisp interpreter never has a leading @samp{+}.)
+  In XEmacs Lisp, integers can be fixnums (that is, fixed-precision
+integers) or bignums (arbitrary-precision integers), if compile-time
+configuration supports this.  The read syntax for the two types is the
+same, the type chosen depending on the numeric values involved.
+
+  The range of values for fixnums in XEmacs Lisp is given by the
+constants @code{most-positive-fixnum} and @code{most-negative-fixnum}.
+On 32-bit machines, these constants reflect 31 value bits, ranging from
+@minus{}1073741824 to 1073741823.
+
+  In the absence of @xref{The Bignum Extension}, XEmacs Lisp
+arithmetic functions do not check for overflow; so the code snippet
+@code{(= most-negative-fixnum (1+ most-positive-fixnum))} will give
+@code{t}.  However, you @emph{will} get an error if you attempt to read
+an out-of-range number using the Lisp reader.
+
+  The main read syntax for integers is a sequence of base ten digits
+with an optional sign at the beginning. (The printed representation
+produced by the Lisp interpreter never has a leading @samp{+}.)
 
 @example
 @group
@@ -1022,7 +1016,7 @@
 read syntax; see @ref{String Type}, @ref{Vector Type}, and @ref{Bit
 Vector Type}.
 
-  An array may have any length up to the largest integer; but once
+  An array may have any length up to the largest fixnum; but once
 created, it has a fixed size.  The first element of an array has index
 zero, the second element has index 1, and so on.  This is called
 @dfn{zero-origin} indexing.  For example, an array of four elements has
@@ -1331,7 +1325,7 @@
 @subsection Range Table Type
 @cindex range table type
 
-  A @dfn{range table} is a table that maps from ranges of integers to
+  A @dfn{range table} is a table that maps from ranges of fixnums to
 arbitrary Lisp objects.  Range tables automatically combine overlapping
 ranges that map to the same Lisp object, and operations are provided
 for mapping over all of the ranges in a range table.
@@ -1714,7 +1708,7 @@
 @subsection Syntax Table Type
 
   Under XEmacs 20, a @dfn{syntax table} is a particular type of char
-table.  Under XEmacs 19, a syntax table a vector of 256 integers.  In
+table.  Under XEmacs 19, a syntax table is a vector of 256 integers.  In
 both cases, each element defines how one character is interpreted when it
 appears in a buffer.  For example, in C mode (@pxref{Major Modes}), the
 @samp{+} character is punctuation, but in Lisp mode it is a valid
@@ -2245,7 +2239,7 @@
 change in one will be reflected by the same change in the other.
 
 @code{eq} returns @code{t} if @var{object1} and @var{object2} are
-integers with the same value.  It is preferable to use @code{=} or
+fixnums with the same value.  It is preferable to use @code{=} or
 @code{eql} in many contexts for numeric comparison, especially since
 bignums (integers with values that would have otherwise overflowed, only
 available on some builds) with the same value are not @code{eq};
--- a/man/lispref/os.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/os.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -419,7 +419,7 @@
 @deffn Command kill-emacs &optional exit-data
 This function exits the XEmacs process and kills it.
 
-If @var{exit-data} is an integer, then it is used as the exit status
+If @var{exit-data} is a fixnum, then it is used as the exit status
 of the XEmacs process.  (This is useful primarily in batch operation; see
 @ref{Batch Mode}.)
 
@@ -765,7 +765,7 @@
 on the effective @sc{uid}, not the real @sc{uid}.
 
 If you specify @var{uid}, the value is the user name that corresponds
-to @var{uid} (which should be an integer).
+to @var{uid} (which should be a fixnum).
 
 @example
 @group
@@ -884,7 +884,7 @@
 @c Emacs 19 feature
 The argument @var{time-value}, if given, specifies a time to format
 instead of the current time.  The argument should be a list whose first
-two elements are integers.  Thus, you can use times obtained from
+two elements are fixnums.  Thus, you can use times obtained from
 @code{current-time} (see below) and from @code{file-attributes}
 (@pxref{File Attributes}).
 
@@ -935,15 +935,15 @@
 
 The argument @var{time-value}, if given, specifies a time to analyze
 instead of the current time.  The argument should be a cons cell
-containing two integers, or a list whose first two elements are
-integers.  Thus, you can use times obtained from @code{current-time}
+containing two fixnums, or a list whose first two elements are
+fixnums.  Thus, you can use times obtained from @code{current-time}
 (see above) and from @code{file-attributes} (@pxref{File Attributes}).
 @end defun
 
 @node Time Conversion
 @section Time Conversion
 
-  These functions convert time values (lists of two or three integers)
+  These functions convert time values (lists of two or three fixnums)
 to strings or to calendrical information.  There is also a function to
 convert calendrical information to a time value.  You can get time
 values from the functions @code{current-time} (@pxref{Time of Day}) and
--- a/man/lispref/positions.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/positions.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -505,7 +505,7 @@
 @var{pixels} is negative.  The optional second argument @var{window} is
 the window to move in, and defaults to the selected window.  The
 optional third argument @var{how} specifies the stopping condition.  A
-negative integer indicates that the motion should be no more
+negative fixnum indicates that the motion should be no more
 than @var{pixels}.  A positive value indicates that the
 motion should be at least @var{pixels}.  Any other value indicates
 that the motion should be as close as possible to @var{pixels}.
--- a/man/lispref/processes.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/processes.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -757,7 +757,7 @@
 @code{process-connection-type} in @ref{Asynchronous Processes}.
 
   Some of the functions below take a @var{signal} argument, which
-identifies a signal to be sent.  It must be either an integer or a
+identifies a signal to be sent.  It must be either a fixnum or a
 symbol which names the signal, like @code{SIGSEGV}.
 
 @defun process-send-signal signal &optional process current-group
--- a/man/lispref/range-tables.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/range-tables.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -7,8 +7,8 @@
 @chapter Range Tables
 @cindex Range Tables
 
-A range table is a table that efficiently associated values with
-ranges of integers.
+A range table is a table that efficiently associates values with
+ranges of fixnums.
 
 Note that range tables have a read syntax, like this:
 
--- a/man/lispref/searching.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/searching.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -80,7 +80,7 @@
 to return the new position of point in that case, but some programs
 may depend on a value of @code{nil}.)
 
-If @var{count} is supplied (it must be an integer), then the search is
+If @var{count} is supplied (it must be a fixnum), then the search is
 repeated that many times (each time starting at the end of the previous
 time's match).  If @var{count} is negative, the search direction is
 backward.  If the successive searches succeed, the function succeeds,
@@ -1039,7 +1039,7 @@
 with.  If it is a string, that string is used.  It can also be a list of
 strings, to be used in cyclic order.
 
-If @var{repeat-count} is non-@code{nil}, it should be an integer.  Then
+If @var{repeat-count} is non-@code{nil}, it should be a fixnum.  Then
 it specifies how many times to use each of the strings in the
 @var{replacements} list before advancing cyclicly to the next one.
 
--- a/man/lispref/strings.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/strings.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -145,7 +145,7 @@
 @defun make-string length character
 This function returns a new string consisting entirely of @var{length}
 successive copies of @var{character}.  @var{length} must be a
-non-negative integer.
+non-negative fixnum.
 
 @example
 (make-string 5 ?x)
@@ -224,7 +224,7 @@
 @xref{Duplicable Extents}.
 
 A @code{wrong-type-argument} error is signaled if either @var{start} or
-@var{end} is not an integer or @code{nil}.  An @code{args-out-of-range}
+@var{end} is not a fixnum or @code{nil}.  An @code{args-out-of-range}
 error is signaled if @var{start} indicates a character following
 @var{end}, or if either integer is out of range for @var{string}.
 
@@ -246,8 +246,8 @@
 @example
 (concat "abc" "-def")
      @result{} "abc-def"
-(concat "abc" (list 120 (+ 256 121)) [122])
-     @result{} "abcxyz"
+(equal (concat "abc" (list 120 (+ 256 121)) [122]) (format "abcx%cz" 377))
+     @result{} t
 ;; @r{@code{nil} is an empty sequence.}
 (concat "abc" nil "-def")
      @result{} "abc-def"
@@ -258,30 +258,9 @@
 @end example
 
 @noindent
-The second example above shows how characters stored in strings are
-taken modulo 256.  In other words, each character in the string is
-stored in one byte.
-
 The @code{concat} function always constructs a new string that is
 not @code{eq} to any existing string.
 
-When an argument is an integer (not a sequence of integers), it is
-converted to a string of digits making up the decimal printed
-representation of the integer.  @strong{Don't use this feature; we plan
-to eliminate it.  If you already use this feature, change your programs
-now!}  The proper way to convert an integer to a decimal number in this
-way is with @code{format} (@pxref{Formatting Strings}) or
-@code{number-to-string} (@pxref{String Conversion}).
-
-@example
-@group
-(concat 137)
-     @result{} "137"
-(concat 54 321)
-     @result{} "54321"
-@end group
-@end example
-
 For information about other concatenation functions, see the description
 of @code{mapconcat} in @ref{Mapping Functions}, @code{vconcat} in
 @ref{Vectors}, @code{bvconcat} in @ref{Bit Vectors}, and @code{append}
@@ -1189,7 +1168,7 @@
 @item syntax
 Used for syntax tables, which specify the syntax of a particular
 character.  Higher-level Lisp functions are provided for
-working with syntax tables.  The valid values are integers.
+working with syntax tables.  The valid values are fixnums.
 @end table
 
 @defun char-table-type char-table
--- a/man/lispref/text.texi	Wed Jan 20 17:30:29 2010 +0000
+++ b/man/lispref/text.texi	Sun Jan 24 15:21:27 2010 +0000
@@ -1679,7 +1679,7 @@
 @var{force} is the special value @code{coerce}, it says to add
 whitespace at the end of the line to reach that column.
 
-If @var{column} is not a non-negative integer, an error is signaled.
+If @var{column} is not a non-negative fixnum, an error is signaled.
 
 The return value is the column number actually moved to.
 @end defun
@@ -2698,7 +2698,7 @@
 @var{contents})}.  Normally, there is one element for each XEmacs
 register that has been used.
 
-The object @var{name} is a character (an integer) identifying the
+The object @var{name} is a character identifying the
 register.  The object @var{contents} is a string, marker, or list
 representing the register contents.  A string represents text stored in
 the register.  A marker represents a position.  A list represents a
--- a/src/ChangeLog	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/ChangeLog	Sun Jan 24 15:21:27 2010 +0000
@@ -1,3 +1,43 @@
+2010-01-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Fix problems with #'eql, extended number types, and the hash table
+	implementation; change the Bintegerp bytecode to fixnump semantics
+	even on bignum builds, since #'integerp can have a fast
+	implementation in terms of #'fixnump for most of its extant uses,
+	but not vice-versa.
+
+	* lisp.h: Always #include number.h; we want the macros provided in
+	it, even if the various number types are not available.
+	* number.h (NON_FIXNUM_NUMBER_P): New macro, giving 1 when its
+	argument is of non-immediate number type.  Equivalent to FLOATP if
+	WITH_NUMBER_TYPES is not defined.
+
+	* elhash.c (lisp_object_eql_equal, lisp_object_eql_hash):
+	Use NON_FIXNUM_NUMBER_P in these functions, instead of FLOATP,
+	giving more correct behaviour in the presence of the extended
+	number types.
+	* bytecode.c (Bfixnump, execute_optimized_program):
+	Rename Bintegerp to Bfixnump; change its semantics to reflect the
+	new name on builds with bignum support.
+
+	* data.c (Ffixnump, Fintegerp, syms_of_data, vars_of_data): 
+	Always make #'fixnump available, even on non-BIGNUM builds;
+	always implement #'integerp in this file, even on BIGNUM builds.
+	Move most-positive-fixnum, most-negative-fixnum here from
+	number.c, so they are Lisp constants even on builds without number
+	types, and attempts to change or bind them error.
+	Use the NUMBERP and INTEGERP macros even on builds without
+	extended number types.
+	* data.c (fixnum_char_or_marker_to_int):
+	Rename this function from integer_char_or_marker_to_int, to better
+	reflect the arguments it accepts.
+
+	* number.c (Fevenp, Foddp, syms_of_number):
+	Never provide #'integerp in this file. Remove #'oddp,
+	#'evenp; their implementations are overridden by those in cl.el.
+	* number.c (vars_of_number):
+	most-positive-fixnum, most-negative-fixnum are no longer here.
+
 2010-01-17  Vin Shelton  <acs@xemacs.org>
 
 	* fileio.c (check_writable): Remove cast from 2010-01-14
--- a/src/bytecode.c	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/bytecode.c	Sun Jan 24 15:21:27 2010 +0000
@@ -232,7 +232,7 @@
   Bquo 		 	= 0245,
   Brem 		 	= 0246,
   Bnumberp 	 	= 0247,
-  Bintegerp 	 	= 0250,
+  Bfixnump 	 	= 0250,	/* Was Bintegerp. */
 
   BRgoto 		= 0252,
   BRgotoifnil 		= 0253,
@@ -1076,12 +1076,8 @@
 #endif
 	  break;
 
-	case Bintegerp:
-#ifdef HAVE_BIGNUM
-	  TOP_LVALUE = INTEGERP (TOP) ? Qt : Qnil;
-#else
+	case Bfixnump:
 	  TOP_LVALUE = INTP (TOP) ? Qt : Qnil;
-#endif
 	  break;
 
 	case Beq:
--- a/src/data.c	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/data.c	Sun Jan 24 15:21:27 2010 +0000
@@ -65,6 +65,8 @@
 Lisp_Object Qerror_lacks_explanatory_string;
 Lisp_Object Qfloatp;
 
+Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
+
 #ifdef DEBUG_XEMACS
 
 int debug_issue_ebola_notices;
@@ -420,7 +422,7 @@
 */
        (integer))
 {
-  CHECK_INT (integer);
+  CHECK_INTEGER (integer);
   if (CHAR_INTP (integer))
     return make_char (XINT (integer));
   else
@@ -456,31 +458,34 @@
   return CHAR_OR_CHAR_INTP (object) || STRINGP (object) ? Qt : Qnil;
 }
 
-#ifdef HAVE_BIGNUM
-/* In this case, integerp is defined in number.c. */
 DEFUN ("fixnump", Ffixnump, 1, 1, 0, /*
 Return t if OBJECT is a fixnum.
+
+In this implementation, a fixnum is an immediate integer, and has a
+maximum value described by the constant `most-positive-fixnum'.  This
+contrasts with bignums, integers where the values are limited by your
+available memory.
 */
        (object))
 {
   return INTP (object) ? Qt : Qnil;
 }
-#else
 DEFUN ("integerp", Fintegerp, 1, 1, 0, /*
-Return t if OBJECT is an integer.
+Return t if OBJECT is an integer, nil otherwise.
+
+On builds without bignum support, this function is identical to `fixnump'.
 */
        (object))
 {
-  return INTP (object) ? Qt : Qnil;
+  return INTEGERP (object) ? Qt : Qnil;
 }
-#endif
 
 DEFUN ("integer-or-marker-p", Finteger_or_marker_p, 1, 1, 0, /*
 Return t if OBJECT is an integer or a marker (editor pointer).
 */
        (object))
 {
-  return INTP (object) || MARKERP (object) ? Qt : Qnil;
+  return INTEGERP (object) || MARKERP (object) ? Qt : Qnil;
 }
 
 DEFUN ("integer-or-char-p", Finteger_or_char_p, 1, 1, 0, /*
@@ -488,7 +493,7 @@
 */
        (object))
 {
-  return INTP (object) || CHARP (object) ? Qt : Qnil;
+  return INTEGERP (object) || CHARP (object) ? Qt : Qnil;
 }
 
 DEFUN ("integer-char-or-marker-p", Finteger_char_or_marker_p, 1, 1, 0, /*
@@ -496,7 +501,7 @@
 */
        (object))
 {
-  return INTP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil;
+  return INTEGERP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil;
 }
 
 DEFUN ("natnump", Fnatnump, 1, 1, 0, /*
@@ -542,11 +547,7 @@
 */
        (object))
 {
-#ifdef WITH_NUMBER_TYPES
   return NUMBERP (object) ? Qt : Qnil;
-#else
-  return INT_OR_FLOATP (object) ? Qt : Qnil;
-#endif
 }
 
 DEFUN ("number-or-marker-p", Fnumber_or_marker_p, 1, 1, 0, /*
@@ -554,7 +555,7 @@
 */
        (object))
 {
-  return INT_OR_FLOATP (object) || MARKERP (object) ? Qt : Qnil;
+  return NUMBERP (object) || MARKERP (object) ? Qt : Qnil;
 }
 
 DEFUN ("number-char-or-marker-p", Fnumber_char_or_marker_p, 1, 1, 0, /*
@@ -562,9 +563,7 @@
 */
        (object))
 {
-  return (INT_OR_FLOATP (object) ||
-	  CHARP         (object) ||
-	  MARKERP       (object))
+  return (NUMBERP (object) || CHARP (object) || MARKERP (object))
     ? Qt : Qnil;
 }
 
@@ -740,6 +739,19 @@
 
   if      (INTP  (index_)) idx = XINT  (index_);
   else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
+#ifdef HAVE_BIGNUM
+  else if (BIGNUMP (index_))
+    {
+      Lisp_Object canon = Fcanonicalize_number (index_);
+      if (EQ (canon, index_))
+	{
+	  /* We don't support non-fixnum indices. */
+	  goto range_error;
+	}
+      index_ = canon;
+      goto retry;
+    }
+#endif
   else
     {
       index_ = wrong_type_argument (Qinteger_or_char_p, index_);
@@ -795,6 +807,19 @@
 
   if      (INTP  (index_)) idx = XINT (index_);
   else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
+#ifdef HAVE_BIGNUM
+  else if (BIGNUMP (index_))
+    {
+      Lisp_Object canon = Fcanonicalize_number (index_);
+      if (EQ (canon, index_))
+	{
+	  /* We don't support non-fixnum indices. */
+	  goto range_error;
+	}
+      index_ = canon;
+      goto retry;
+    }
+#endif
   else
     {
       index_ = wrong_type_argument (Qinteger_or_char_p, index_);
@@ -884,7 +909,7 @@
 #endif /* WITH_NUMBER_TYPES */
 
 static EMACS_INT
-integer_char_or_marker_to_int (Lisp_Object obj)
+fixnum_char_or_marker_to_int (Lisp_Object obj)
 {
  retry:
   if      (INTP    (obj)) return XINT  (obj);
@@ -892,6 +917,9 @@
   else if (MARKERP (obj)) return marker_position (obj);
   else
     {
+      /* On bignum builds, we can only be called from #'lognot, which
+	 protects against this happening: */
+      assert (!BIGNUMP (obj));
       obj = wrong_type_argument (Qinteger_char_or_marker_p, obj);
       goto retry;
     }
@@ -1192,11 +1220,7 @@
 */
        (number))
 {
-#ifdef WITH_NUMBER_TYPES
   CHECK_NUMBER (number);
-#else
-  CHECK_INT_OR_FLOAT (number);
-#endif
 
   if (FLOATP (number))
     {
@@ -2132,7 +2156,7 @@
   Lisp_Object *args_end = args + nargs;
 
   while (args < args_end)
-    bits &= integer_char_or_marker_to_int (*args++);
+    bits &= fixnum_char_or_marker_to_int (*args++);
 
   return make_int (bits);
 #endif /* HAVE_BIGNUM */
@@ -2184,7 +2208,7 @@
   Lisp_Object *args_end = args + nargs;
 
   while (args < args_end)
-    bits |= integer_char_or_marker_to_int (*args++);
+    bits |= fixnum_char_or_marker_to_int (*args++);
 
   return make_int (bits);
 #endif /* HAVE_BIGNUM */
@@ -2206,7 +2230,7 @@
     return make_int (0);
 
   while (!(CHARP (args[0]) || MARKERP (args[0]) || INTEGERP (args[0])))
-    args[0] = wrong_type_argument (Qnumber_char_or_marker_p, args[0]);
+    args[0] = wrong_type_argument (Qinteger_char_or_marker_p, args[0]);
 
   result = args[0];
   if (CHARP (result))
@@ -2216,7 +2240,7 @@
   for (i = 1; i < nargs; i++)
     {
       while (!(CHARP (args[i]) || MARKERP (args[i]) || INTEGERP (args[i])))
-	args[i] = wrong_type_argument (Qnumber_char_or_marker_p, args[i]);
+	args[i] = wrong_type_argument (Qinteger_char_or_marker_p, args[i]);
       other = args[i];
       if (promote_args (&result, &other) == FIXNUM_T)
 	{
@@ -2235,7 +2259,7 @@
   Lisp_Object *args_end = args + nargs;
 
   while (args < args_end)
-    bits ^= integer_char_or_marker_to_int (*args++);
+    bits ^= fixnum_char_or_marker_to_int (*args++);
 
   return make_int (bits);
 #endif /* !HAVE_BIGNUM */
@@ -2247,6 +2271,9 @@
 */
        (number))
 {
+  while (!(CHARP (number) || MARKERP (number) || INTEGERP (number)))
+    number = wrong_type_argument (Qinteger_char_or_marker_p, number);
+
 #ifdef HAVE_BIGNUM
   if (BIGNUMP (number))
     {
@@ -2254,7 +2281,8 @@
       return make_bignum_bg (scratch_bignum);
     }
 #endif /* HAVE_BIGNUM */
-  return make_int (~ integer_char_or_marker_to_int (number));
+
+  return make_int (~ fixnum_char_or_marker_to_int (number));
 }
 
 DEFUN ("%", Frem, 2, 2, 0, /*
@@ -2284,8 +2312,8 @@
       return Fcanonicalize_number (make_bignum_bg (scratch_bignum));
     }
 #else /* !HAVE_BIGNUM */
-  EMACS_INT ival1 = integer_char_or_marker_to_int (number1);
-  EMACS_INT ival2 = integer_char_or_marker_to_int (number2);
+  EMACS_INT ival1 = fixnum_char_or_marker_to_int (number1);
+  EMACS_INT ival2 = fixnum_char_or_marker_to_int (number2);
 
   if (ival2 == 0)
     Fsignal (Qarith_error, Qnil);
@@ -3550,11 +3578,8 @@
   DEFSUBR (Fchar_to_int);
   DEFSUBR (Fint_to_char);
   DEFSUBR (Fchar_or_char_int_p);
-#ifdef HAVE_BIGNUM
   DEFSUBR (Ffixnump);
-#else
   DEFSUBR (Fintegerp);
-#endif
   DEFSUBR (Finteger_or_marker_p);
   DEFSUBR (Finteger_or_char_p);
   DEFSUBR (Finteger_char_or_marker_p);
@@ -3644,6 +3669,16 @@
   Vall_weak_boxes = Qnil;
   dump_add_weak_object_chain (&Vall_weak_boxes);
 
+  DEFVAR_CONST_INT ("most-negative-fixnum", &Vmost_negative_fixnum /*
+The fixnum closest in value to negative infinity.
+*/);
+  Vmost_negative_fixnum = EMACS_INT_MIN;
+
+  DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /*
+The fixnum closest in value to positive infinity.
+*/);
+  Vmost_positive_fixnum = EMACS_INT_MAX;
+
 #ifdef DEBUG_XEMACS
   DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /*
 If non-zero, note when your code may be suffering from char-int confoundance.
--- a/src/elhash.c	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/elhash.c	Sun Jan 24 15:21:27 2010 +0000
@@ -207,13 +207,14 @@
 static int
 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2)
 {
-  return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0));
+  return EQ (obj1, obj2) ||
+    (NON_FIXNUM_NUMBER_P (obj1) && internal_equal (obj1, obj2, 0));
 }
 
 static Hashcode
 lisp_object_eql_hash (Lisp_Object obj)
 {
-  return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj);
+  return NON_FIXNUM_NUMBER_P (obj) ? internal_hash (obj, 0) : LISP_HASH (obj);
 }
 
 static int
--- a/src/lisp.h	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/lisp.h	Sun Jan 24 15:21:27 2010 +0000
@@ -4195,11 +4195,7 @@
 /************************************************************************/
 /*		             Other numeric types      	                */
 /************************************************************************/
-#ifdef WITH_NUMBER_TYPES
 #include "number.h"
-#else
-#define make_integer(x) make_int(x)
-#endif
 
 
 /************************************************************************/
--- a/src/number.c	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/number.c	Sun Jan 24 15:21:27 2010 +0000
@@ -32,7 +32,7 @@
 
 Lisp_Object Qrationalp, Qfloatingp, Qrealp;
 Lisp_Object Vdefault_float_precision;
-Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
+
 static Lisp_Object Qunsupported_type;
 static Lisp_Object Vbigfloat_max_prec;
 static int number_initialized;
@@ -139,38 +139,6 @@
 }
 
 
-/********************************* Integers *********************************/
-DEFUN ("integerp", Fintegerp, 1, 1, 0, /*
-Return t if OBJECT is an integer, nil otherwise.
-*/
-       (object))
-{
-  return INTEGERP (object) ? Qt : Qnil;
-}
-
-DEFUN ("evenp", Fevenp, 1, 1, 0, /*
-Return t if INTEGER is even, nil otherwise.
-*/
-       (integer))
-{
-  CONCHECK_INTEGER (integer);
-  return (BIGNUMP (integer)
-	  ? bignum_evenp (XBIGNUM_DATA (integer))
-	  : XTYPE (integer) == Lisp_Type_Int_Even) ? Qt : Qnil;
-}
-
-DEFUN ("oddp", Foddp, 1, 1, 0, /*
-Return t if INTEGER is odd, nil otherwise.
-*/
-       (integer))
-{
-  CONCHECK_INTEGER (integer);
-  return (BIGNUMP (integer)
-	  ? bignum_oddp (XBIGNUM_DATA (integer))
-	  : XTYPE (integer) == Lisp_Type_Int_Odd) ? Qt : Qnil;
-}
-
-
 /********************************** Ratios **********************************/
 #ifdef HAVE_RATIO
 static void
@@ -268,7 +236,7 @@
     ? make_bignum_bg (XRATIO_DENOMINATOR (rational))
     : make_int (1);
 #else
-  return rational;
+  return make_int (1);
 #endif
 }
 
@@ -808,9 +776,6 @@
 
   /* Functions */
   DEFSUBR (Fbignump);
-  DEFSUBR (Fintegerp);
-  DEFSUBR (Fevenp);
-  DEFSUBR (Foddp);
   DEFSUBR (Fratiop);
   DEFSUBR (Frationalp);
   DEFSUBR (Fnumerator);
@@ -853,16 +818,6 @@
   Vbigfloat_max_prec = make_int (0);
 #endif /* HAVE_BIGFLOAT */
 
-  DEFVAR_CONST_INT ("most-negative-fixnum", &Vmost_negative_fixnum /*
-The fixnum closest in value to negative infinity.
-*/);
-  Vmost_negative_fixnum = EMACS_INT_MIN;
-
-  DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /*
-The fixnum closest in value to positive infinity.
-*/);
-  Vmost_positive_fixnum = EMACS_INT_MAX;
-
   Fprovide (intern ("number-types"));
 #ifdef HAVE_BIGNUM
   Fprovide (intern ("bignum"));
--- a/src/number.h	Wed Jan 20 17:30:29 2010 +0000
+++ b/src/number.h	Sun Jan 24 15:21:27 2010 +0000
@@ -338,4 +338,35 @@
 extern enum number_type get_number_type (Lisp_Object);
 extern enum number_type promote_args (Lisp_Object *, Lisp_Object *);
 
+#ifdef WITH_NUMBER_TYPES
+DECLARE_INLINE_HEADER (
+int
+non_fixnum_number_p (Lisp_Object object))
+{
+  if (LRECORDP (object))
+    {
+      switch (XRECORD_LHEADER (object)->type)
+        {
+        case lrecord_type_float:
+#ifdef HAVE_BIGNUM
+        case lrecord_type_bignum:
+#endif
+#ifdef HAVE_RATIO
+        case lrecord_type_ratio:
+#endif
+#ifdef HAVE_BIGFLOAT
+        case lrecord_type_bigfloat:
+#endif
+          return 1;
+        }
+    }
+  return 0;
+}
+#define NON_FIXNUM_NUMBER_P(X) non_fixnum_number_p (X)
+
+#else
+#define NON_FIXNUM_NUMBER_P FLOATP
+#endif
+
+
 #endif /* INCLUDED_number_h_ */
--- a/tests/automated/lisp-tests.el	Wed Jan 20 17:30:29 2010 +0000
+++ b/tests/automated/lisp-tests.el	Sun Jan 24 15:21:27 2010 +0000
@@ -2181,4 +2181,52 @@
   do (Assert (functionp real-function)
 	     (format "checking %S is a function" real-function)))
 
+;; #'member, #'assoc tests.
+
+(when (featurep 'bignum)
+  (let* ((member*-list `(0 9 342 [hi there] ,(1+ most-positive-fixnum) 0
+			 0.0 ,(1- most-negative-fixnum) nil))
+	 (assoc*-list (loop
+			for elt in member*-list
+			collect (cons elt (random))))
+	 (hashing (make-hash-table :test 'eql))
+	 hashed-bignum)
+    (macrolet
+	((1+most-positive-fixnum ()
+	   (1+ most-positive-fixnum))
+	 (1-most-negative-fixnum ()
+	   (1- most-negative-fixnum))
+	 (*-2-most-positive-fixnum ()
+	   (* 2 most-positive-fixnum))) 
+      (Assert-eq
+       (member* (1+ most-positive-fixnum) member*-list)
+       (member* (1+ most-positive-fixnum) member*-list :test #'eql)
+       "checking #'member* correct if #'eql not explicitly specified")
+      (Assert-eq
+       (assoc* (1+ most-positive-fixnum) assoc*-list)
+       (assoc* (1+ most-positive-fixnum) assoc*-list :test #'eql)
+       "checking #'assoc* correct if #'eql not explicitly specified")
+      (Assert-eq
+       (rassoc* (1- most-negative-fixnum) assoc*-list)
+       (rassoc* (1- most-negative-fixnum) assoc*-list :test #'eql)
+       "checking #'rassoc* correct if #'eql not explicitly specified")
+      (Assert-eq
+       (eql (1+most-positive-fixnum) (1+ most-positive-fixnum))
+       t
+       "checking #'eql handles a bignum literal properly.")
+      (Assert-eq 
+       (member* (1+most-positive-fixnum) member*-list)
+       (member* (1+ most-positive-fixnum) member*-list :test #'equal)
+       "checking #'member* compiler macro correct with literal bignum")
+      (Assert-eq
+       (assoc* (1+most-positive-fixnum) assoc*-list)
+       (assoc* (1+ most-positive-fixnum) assoc*-list :test #'equal)
+       "checking #'assoc* compiler macro correct with literal bignum")
+      (puthash (setq hashed-bignum (*-2-most-positive-fixnum)) 
+	       (gensym) hashing)
+      (Assert-eq
+       (gethash (* 2 most-positive-fixnum) hashing)
+       (gethash hashed-bignum hashing)
+       "checking hashing works correctly with #'eql tests and bignums"))))
+
 ;;; end of lisp-tests.el