From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 04:44:31 2011 Received: (at submit) by debbugs.gnu.org; 3 Jun 2011 08:44:31 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSPzX-0002yM-Ta for submit@debbugs.gnu.org; Fri, 03 Jun 2011 04:44:31 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSPzR-0002y6-Ur for submit@debbugs.gnu.org; Fri, 03 Jun 2011 04:44:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QSPzH-0005O3-KV for submit@debbugs.gnu.org; Fri, 03 Jun 2011 04:44:16 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:60386) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSPzG-0005Nw-RC for submit@debbugs.gnu.org; Fri, 03 Jun 2011 04:44:11 -0400 Received: from eggs.gnu.org ([140.186.70.92]:33897) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSPz7-0000x7-F1 for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 04:44:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QSPyx-0005KZ-En for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 04:44:01 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:57597) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSPyw-0005KR-E5 for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2011 04:43:51 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 1F9F039E80FA for ; Fri, 3 Jun 2011 01:43:49 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id scJ-RQ4q8G+1 for ; Fri, 3 Jun 2011 01:43:42 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 1CB6A39E80F7 for ; Fri, 3 Jun 2011 01:43:42 -0700 (PDT) Message-ID: <4DE89EB8.9020202@cs.ucla.edu> Date: Fri, 03 Jun 2011 01:43:36 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: bug-gnu-emacs@gnu.org Subject: cons_to_long fixes; making 64-bit EMACS_INT the default Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -4.7 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.7 (----) I found several problems in the Emacs code that converts large C integers to Emacs conses-of-integers and back again. I wrote some code to fix them systematically, and found that it was simpler and more reliable if I could assume that EMACS_INT was 64-bit even on 32-bit hosts. So here's a patch to do all that. I plan to test this a bit more before committing. # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: eggert@cs.ucla.edu-20110603052422-jleodvo6pg0bsrpk # target_branch: bzr+ssh://eggert@bzr.savannah.gnu.org/emacs/trunk # testament_sha1: 76b360c210c60c75ddc564f61f5ead41553b62f4 # timestamp: 2011-06-03 01:33:08 -0700 # base_revision_id: monnier@iro.umontreal.ca-20110602180444-\ # lbjc3q55bwdn2fs5 # # Begin patch === modified file 'doc/emacs/ChangeLog' --- doc/emacs/ChangeLog 2011-05-28 18:22:08 +0000 +++ doc/emacs/ChangeLog 2011-06-03 05:24:22 +0000 @@ -1,3 +1,9 @@ +2011-06-02 Paul Eggert + + Document wide integers better. + * buffers.texi (Buffers): + * files.texi (Visiting): Default buffer maximum is now 2 EiB typically. + 2011-05-28 Chong Yidong * custom.texi (Hooks): Reorganize. Mention Prog mode. === modified file 'doc/emacs/buffers.texi' --- doc/emacs/buffers.texi 2011-01-25 04:08:28 +0000 +++ doc/emacs/buffers.texi 2011-06-03 05:24:22 +0000 @@ -43,8 +43,11 @@ A buffer's size cannot be larger than some maximum, which is defined by the largest buffer position representable by the @dfn{Emacs integer} data type. This is because Emacs tracks buffer positions -using that data type. For 32-bit machines, the largest buffer size is -512 megabytes. +using that data type. For most machines, the maximum buffer size +enforced by the data types is @math{2^61 - 2} bytes, or about 2 EiB. +For some older machines, the maximum is @math{2^29 - 2} bytes, or +about 512 MiB. Buffer sizes are also limited by the size of Emacs's +virtual memory. @menu * Select Buffer:: Creating a new buffer or reselecting an old one. === modified file 'doc/emacs/files.texi' --- doc/emacs/files.texi 2011-01-31 23:54:50 +0000 +++ doc/emacs/files.texi 2011-06-03 05:24:22 +0000 @@ -209,7 +209,7 @@ about 10 megabytes), Emacs asks you for confirmation first. You can answer @kbd{y} to proceed with visiting the file. Note, however, that Emacs cannot visit files that are larger than the maximum Emacs buffer -size, which is around 512 megabytes on 32-bit machines +size, which is around 512 MiB on 32-bit machines and 2 EiB on 64-bit machines (@pxref{Buffers}). If you try, Emacs will display an error message saying that the maximum buffer size has been exceeded. === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2011-05-31 18:40:00 +0000 +++ doc/lispref/ChangeLog 2011-06-03 05:24:22 +0000 @@ -1,3 +1,12 @@ +2011-06-03 Paul Eggert + + Document wide integers better. + * files.texi (File Attributes): Document ino_t values better. + * numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations): + (Bitwise Operations): + * objects.texi (Integer Type): Integers are typically 62 bits now. + * os.texi (Time Conversion): Document time_t values better. + 2011-05-31 Lars Magne Ingebrigtsen * processes.texi (Process Information): Document === modified file 'doc/lispref/files.texi' --- doc/lispref/files.texi 2011-05-12 07:07:06 +0000 +++ doc/lispref/files.texi 2011-06-03 05:24:22 +0000 @@ -1236,12 +1236,13 @@ @item The file's inode number. If possible, this is an integer. If the -inode number is too large to be represented as an integer in Emacs -Lisp, but still fits into a 32-bit integer, then the value has the -form @code{(@var{high} . @var{low})}, where @var{low} holds the low 16 -bits. If the inode is wider than 32 bits, the value is of the form +inode number @math{N} is too large to be represented as an integer in +Emacs Lisp, but @math{N / 2^16} is representable, then the value has +the form @code{(@var{high} . @var{low})}, where @var{high} holds the +high bits (i.e., excluding the low-order bits) and @var{low} the low +16 bits. If the inode number is even larger, the value is of the form @code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds -the high 24 bits, @var{middle} the next 24 bits, and @var{low} the low +the high bits, @var{middle} the next 24 bits, and @var{low} the low 16 bits. @item === modified file 'doc/lispref/numbers.texi' --- doc/lispref/numbers.texi 2011-05-05 06:31:14 +0000 +++ doc/lispref/numbers.texi 2011-06-03 05:24:22 +0000 @@ -36,22 +36,24 @@ @section Integer Basics The range of values for an integer depends on the machine. The -minimum range is @minus{}536870912 to 536870911 (30 bits; i.e., +typical range is @minus{}2305843009213693952 to 2305843009213693951 +(62 bits; i.e., @ifnottex --2**29 +-2**61 @end ifnottex @tex -@math{-2^{29}} +@math{-2^{61}} @end tex to @ifnottex -2**29 - 1), +2**61 - 1) @end ifnottex @tex -@math{2^{29}-1}), +@math{2^{61}-1}) @end tex -but some machines may provide a wider range. Many examples in this -chapter assume an integer has 30 bits. +but some older machines provide only 30 bits. Many examples in this +chapter assume that an integer has 62 bits and that floating point +numbers are IEEE double precision. @cindex overflow The Lisp reader reads an integer as a sequence of digits with optional @@ -63,7 +65,8 @@ 1. ; @r{The integer 1.} +1 ; @r{Also the integer 1.} -1 ; @r{The integer @minus{}1.} - 1073741825 ; @r{The floating point number 1073741825.0.} + 4611686018427387904 + ; @r{The floating point number 4.611686018427388e+18.} 0 ; @r{The integer 0.} -0 ; @r{The integer 0.} @end example @@ -94,25 +97,21 @@ bitwise operators (@pxref{Bitwise Operations}), it is often helpful to view the numbers in their binary form. - In 30-bit binary, the decimal integer 5 looks like this: + In 62-bit binary, the decimal integer 5 looks like this: @example -00 0000 0000 0000 0000 0000 0000 0101 +0000...000101 (62 bits total) @end example -@noindent -(We have inserted spaces between groups of 4 bits, and two spaces -between groups of 8 bits, to make the binary integer easier to read.) - The integer @minus{}1 looks like this: @example -11 1111 1111 1111 1111 1111 1111 1111 +1111...111111 (62 bits total) @end example @noindent @cindex two's complement -@minus{}1 is represented as 30 ones. (This is called @dfn{two's +@minus{}1 is represented as 62 ones. (This is called @dfn{two's complement} notation.) The negative integer, @minus{}5, is creating by subtracting 4 from @@ -120,24 +119,24 @@ @minus{}5 looks like this: @example -11 1111 1111 1111 1111 1111 1111 1011 +1111...111011 (62 bits total) @end example - In this implementation, the largest 30-bit binary integer value is -536,870,911 in decimal. In binary, it looks like this: + In this implementation, the largest 62-bit binary integer value is +2,305,843,009,213,693,951 in decimal. In binary, it looks like this: @example -01 1111 1111 1111 1111 1111 1111 1111 +0111...111111 (62 bits total) @end example Since the arithmetic functions do not check whether integers go -outside their range, when you add 1 to 536,870,911, the value is the -negative integer @minus{}536,870,912: +outside their range, when you add 1 to 2,305,843,009,213,693,951, the value is the +negative integer @minus{}2,305,843,009,213,693,952: @example -(+ 1 536870911) - @result{} -536870912 - @result{} 10 0000 0000 0000 0000 0000 0000 0000 +(+ 1 2305843009213693951) + @result{} -2305843009213693952 + @result{} 1000...000000 (62 bits total) @end example Many of the functions described in this chapter accept markers for @@ -508,8 +507,8 @@ if any argument is floating. It is important to note that in Emacs Lisp, arithmetic functions -do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to -@minus{}268435456, depending on your hardware. +do not check for overflow. Thus @code{(1+ 2305843009213693951)} may +evaluate to @minus{}2305843009213693952, depending on your hardware. @defun 1+ number-or-marker This function returns @var{number-or-marker} plus 1. @@ -829,19 +828,19 @@ The function @code{lsh}, like all Emacs Lisp arithmetic functions, does not check for overflow, so shifting left can discard significant bits and change the sign of the number. For example, left shifting -536,870,911 produces @minus{}2 on a 30-bit machine: +2,305,843,009,213,693,951 produces @minus{}2 on a typical machine: @example -(lsh 536870911 1) ; @r{left shift} +(lsh 2305843009213693951 1) ; @r{left shift} @result{} -2 @end example -In binary, in the 30-bit implementation, the argument looks like this: +In binary, in the 62-bit implementation, the argument looks like this: @example @group -;; @r{Decimal 536,870,911} -01 1111 1111 1111 1111 1111 1111 1111 +;; @r{Decimal 2,305,843,009,213,693,951} +0111...111111 (62 bits total) @end group @end example @@ -851,7 +850,7 @@ @example @group ;; @r{Decimal @minus{}2} -11 1111 1111 1111 1111 1111 1111 1110 +1111...111110 (62 bits total) @end group @end example @end defun @@ -874,9 +873,9 @@ @group (ash -6 -1) @result{} -3 ;; @r{Decimal @minus{}6 becomes decimal @minus{}3.} -11 1111 1111 1111 1111 1111 1111 1010 +1111...111010 (62 bits total) @result{} -11 1111 1111 1111 1111 1111 1111 1101 +1111...111101 (62 bits total) @end group @end example @@ -885,11 +884,11 @@ @example @group -(lsh -6 -1) @result{} 536870909 -;; @r{Decimal @minus{}6 becomes decimal 536,870,909.} -11 1111 1111 1111 1111 1111 1111 1010 +(lsh -6 -1) @result{} 2305843009213693949 +;; @r{Decimal @minus{}6 becomes decimal 2,305,843,009,213,693,949.} +1111...111010 (62 bits total) @result{} -01 1111 1111 1111 1111 1111 1111 1101 +0111...111101 (62 bits total) @end group @end example @@ -899,34 +898,35 @@ @c with smallbook but not with regular book! --rjc 16mar92 @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(lsh 5 2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 20 ; = @r{00 0000 0000 0000 0000 0000 0001 0100} +(lsh 5 2) ; 5 = @r{0000...000101} + @result{} 20 ; = @r{0000...010100} @end group @group (ash 5 2) @result{} 20 -(lsh -5 2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} -20 ; = @r{11 1111 1111 1111 1111 1111 1110 1100} +(lsh -5 2) ; -5 = @r{1111...111011} + @result{} -20 ; = @r{1111...101100} (ash -5 2) @result{} -20 @end group @group -(lsh 5 -2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 1 ; = @r{00 0000 0000 0000 0000 0000 0000 0001} +(lsh 5 -2) ; 5 = @r{0000...000101} + @result{} 1 ; = @r{0000...000001} @end group @group (ash 5 -2) @result{} 1 @end group @group -(lsh -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} 268435454 ; = @r{00 0111 1111 1111 1111 1111 1111 1110} +(lsh -5 -2) ; -5 = @r{1111...111011} + @result{} 1152921504606846974 + ; = @r{0011...111110} @end group @group -(ash -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} -2 ; = @r{11 1111 1111 1111 1111 1111 1111 1110} +(ash -5 -2) ; -5 = @r{1111...111011} + @result{} -2 ; = @r{1111...111110} @end group @end smallexample @end defun @@ -961,23 +961,23 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logand 14 13) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} - @result{} 12 ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} +(logand 14 13) ; 14 = @r{0000...001110} + ; 13 = @r{0000...001101} + @result{} 12 ; 12 = @r{0000...001100} @end group @group -(logand 14 13 4) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} - ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} - @result{} 4 ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} +(logand 14 13 4) ; 14 = @r{0000...001110} + ; 13 = @r{0000...001101} + ; 4 = @r{0000...000100} + @result{} 4 ; 4 = @r{0000...000100} @end group @group (logand) - @result{} -1 ; -1 = @r{11 1111 1111 1111 1111 1111 1111 1111} + @result{} -1 ; -1 = @r{1111...111111} @end group @end smallexample @end defun @@ -991,18 +991,18 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logior 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 13 ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} +(logior 12 5) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + @result{} 13 ; 13 = @r{0000...001101} @end group @group -(logior 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} - @result{} 15 ; 15 = @r{00 0000 0000 0000 0000 0000 0000 1111} +(logior 12 5 7) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + ; 7 = @r{0000...000111} + @result{} 15 ; 15 = @r{0000...001111} @end group @end smallexample @end defun @@ -1016,18 +1016,18 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logxor 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 9 ; 9 = @r{00 0000 0000 0000 0000 0000 0000 1001} +(logxor 12 5) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + @result{} 9 ; 9 = @r{0000...001001} @end group @group -(logxor 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} - @result{} 14 ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} +(logxor 12 5 7) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + ; 7 = @r{0000...000111} + @result{} 14 ; 14 = @r{0000...001110} @end group @end smallexample @end defun @@ -1040,9 +1040,9 @@ @example (lognot 5) @result{} -6 -;; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} +;; 5 = @r{0000...000101} (62 bits total) ;; @r{becomes} -;; -6 = @r{11 1111 1111 1111 1111 1111 1111 1010} +;; -6 = @r{1111...111010} (62 bits total) @end example @end defun === modified file 'doc/lispref/objects.texi' --- doc/lispref/objects.texi 2011-05-05 06:31:14 +0000 +++ doc/lispref/objects.texi 2011-06-03 05:24:22 +0000 @@ -164,25 +164,25 @@ @node Integer Type @subsection Integer Type - The range of values for integers in Emacs Lisp is @minus{}536870912 to -536870911 (30 bits; i.e., + The range of values for integers in Emacs Lisp is +@minus{}2305843009213693952 to 2305843009213693951 (62 bits; i.e., @ifnottex --2**29 +-2**61 @end ifnottex @tex -@math{-2^{29}} +@math{-2^{61}} @end tex to @ifnottex -2**29 - 1) +2**61 - 1) @end ifnottex @tex -@math{2^{29}-1}) +@math{2^{61}-1}) @end tex -on most machines. (Some machines may provide a wider range.) It is -important to note that the Emacs Lisp arithmetic functions do not check -for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most -machines. +on most machines. Some older machines may provide a narrower or wider +range; all machines provide at least 30 bits. Emacs Lisp arithmetic +functions do not check for overflow. Thus @code{(1+ +2305843009213693951)} is @minus{}2305843009213693952 on most machines. The read syntax for integers is a sequence of (base ten) digits with an optional sign at the beginning and an optional period at the end. The @@ -195,7 +195,6 @@ 1 ; @r{The integer 1.} 1. ; @r{Also the integer 1.} +1 ; @r{Also the integer 1.} -1073741825 ; @r{Also the integer 1 on a 30-bit implementation.} @end group @end example @@ -203,8 +202,8 @@ As a special exception, if a sequence of digits specifies an integer too large or too small to be a valid integer object, the Lisp reader reads it as a floating-point number (@pxref{Floating Point Type}). -For instance, on most machines @code{536870912} is read as the -floating-point number @code{536870912.0}. +For instance, on most machines @code{2305843009213693952} is read as the +floating-point number @code{2.305843009213694e+18}. @xref{Numbers}, for more information. === modified file 'doc/lispref/os.texi' --- doc/lispref/os.texi 2011-02-01 07:23:48 +0000 +++ doc/lispref/os.texi 2011-06-03 05:24:22 +0000 @@ -1193,11 +1193,11 @@ from the functions @code{current-time} (@pxref{Time of Day}) and @code{file-attributes} (@pxref{Definition of file-attributes}). - Many operating systems are limited to time values that contain 32 bits + Many 32-bit operating systems are limited to time values that contain 32 bits of information; these systems typically handle only the times from -1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, some -operating systems have larger time values, and can represent times far -in the past or future. +1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, 64-bit +and some 32-bit operating systems have larger time values, and can +represent times far in the past or future. Time conversion functions always use the Gregorian calendar, even for dates before the Gregorian calendar was introduced. Year numbers === modified file 'etc/ChangeLog' --- etc/ChangeLog 2011-05-24 14:22:44 +0000 +++ etc/ChangeLog 2011-06-03 05:24:22 +0000 @@ -1,3 +1,7 @@ +2011-06-03 Paul Eggert + + * NEWS: 62-bit integers are typical now. + 2011-05-24 Leo Liu * NEWS: Mention the new primitive sha1 and the removal of sha1.el. === modified file 'etc/NEWS' --- etc/NEWS 2011-06-01 15:34:41 +0000 +++ etc/NEWS 2011-06-03 05:24:22 +0000 @@ -902,6 +902,13 @@ *** New function `special-variable-p' to check whether a variable is declared as dynamically bound. +** Emacs integers have a wider range on typical 32-bit hosts. +Previously, they were limited to a 30-bit range (-2**29 .. 2**29-1). +Now, they are limited to a 62-bit range (-2**61 .. 2**61-1), the +same as on 64-bit hosts. This increased range comes from the Emacs +interpreter using 64-bit native integer types that are available +on typical modern 32-bit platforms. + ** pre/post-command-hook are not reset to nil upon error. Instead, the offending function is removed. === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-02 08:40:41 +0000 +++ src/ChangeLog 2011-06-03 05:24:22 +0000 @@ -1,5 +1,71 @@ 2011-06-02 Paul Eggert + Check for overflow when converting integer to cons and back. + * charset.c (Fdefine_charset_internal, Fdecode_char): + Use cons_to_unsigned to catch overflow. + (Fencode_char): Use INTEGER_TO_CONS. + * composite.h (LGLYPH_CODE): Use cons_to_unsigned. + (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. + * data.c (long_to_cons, cons_to_long): Remove. + (cons_to_unsigned, cons_to_signed): New functions. These signal an + error for invalid or out-of-range values. + * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. + (Ffile_attributes): Document inode number handling more accurately. + * termhooks.h: Fix comment for inode number handling. + + * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. + * font.c (Ffont_variation_glyphs): + * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. + * lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. + (cons_to_signed, cons_to_unsigned): New decls. + (long_to_cons, cons_to_long): Remove decls. + * undo.c (record_first_change): Use INTEGER_TO_CONS. + (Fprimitive_undo): Use CONS_TO_INTEGER. + * xfns.c (Fx_window_property): Likewise. + * xselect.c (x_own_selection, selection_data_to_lisp_data): + Use INTEGER_TO_CONS. + (x_handle_selection_request, x_handle_selection_clear) + (x_get_foreign_selection, Fx_disown_selection_internal) + (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. + (lisp_data_to_selection_data): Use cons_to_unsigned. + (x_fill_property_data): Use cons_to_signed. Report values out of range. + + * xselect.c (selection_data_to_lisp_data): Use 'unsigned' consistently + when computing sizes of unsigned objects. + (lisp_data_to_selection_data): Likewise. + + * lisp.h (WIDE_EMACS_INT): Now defaults to 1. + + * fileio.c (Fverify_visited_file_modtime): Avoid time overflow + if b->modtime has its maximal value. + + * dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits. + + * lisp.h: Include , as it'll useful in later changes. + * character.c, data.c, editfns.c, insdel.c, intervals.c: + Don't include , since lisp.h does. + + Don't assume time_t can fit into int. + * buffer.h (struct buffer.modtime): Now time_t, not int. + * fileio.c (Fvisited_file_modtime): No need for time_t cast now. + * undo.c (Fprimitive_undo): Use time_t, not int, for time_t value. + + Minor fixes for signed vs unsigned integers. + * character.h (MAYBE_UNIFY_CHAR): + * charset.c (maybe_unify_char): + * keyboard.c (read_char, reorder_modifiers): + XINT -> XFASTINT, since the integer must be nonnegative. + * ftfont.c (ftfont_spec_pattern): + * keymap.c (access_keymap, silly_event_symbol_error): + XUINT -> XFASTINT, since the integer must be nonnegative. + (Fsingle_key_description, preferred_sequence_p): XUINT -> XINT, + since it makes no difference and we prefer signed. + * keyboard.c (record_char): Use XUINT when all the neighbors do. + (access_keymap): NATNUMP -> INTEGERP, since the integer must be + nonnegative. + +2011-06-02 Paul Eggert + Malloc failure behavior now depends on size of allocation. * alloc.c (buffer_memory_full, memory_full): New arg NBYTES. * lisp.h: Change signatures accordingly. === modified file 'src/buffer.h' --- src/buffer.h 2011-05-12 07:07:06 +0000 +++ src/buffer.h 2011-06-02 06:15:15 +0000 @@ -545,7 +545,7 @@ -1 means visited file was nonexistent. 0 means visited file modtime unknown; in no case complain about any mismatch on next save attempt. */ - int modtime; + time_t modtime; /* Size of the file when modtime was set. This is used to detect the case where the file grew while we were reading it, so the modtime is still the same (since it's rounded up to seconds) but we're actually === modified file 'src/character.c' --- src/character.c 2011-05-21 04:33:23 +0000 +++ src/character.c 2011-06-02 06:17:35 +0000 @@ -35,7 +35,7 @@ #include #include -#include + #include "lisp.h" #include "character.h" #include "buffer.h" === modified file 'src/character.h' --- src/character.h 2011-05-21 04:33:23 +0000 +++ src/character.h 2011-06-01 02:49:12 +0000 @@ -544,7 +544,7 @@ Lisp_Object val; \ val = CHAR_TABLE_REF (Vchar_unify_table, c); \ if (INTEGERP (val)) \ - c = XINT (val); \ + c = XFASTINT (val); \ else if (! NILP (val)) \ c = maybe_unify_char (c, val); \ } \ === modified file 'src/charset.c' --- src/charset.c 2011-05-31 06:05:00 +0000 +++ src/charset.c 2011-06-02 18:35:30 +0000 @@ -932,17 +932,8 @@ val = args[charset_arg_min_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -954,17 +945,8 @@ val = args[charset_arg_max_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -1637,7 +1619,7 @@ struct charset *charset; if (INTEGERP (val)) - return XINT (val); + return XFASTINT (val); if (NILP (val)) return c; @@ -1647,7 +1629,7 @@ { val = CHAR_TABLE_REF (Vchar_unify_table, c); if (! NILP (val)) - c = XINT (val); + c = XFASTINT (val); } else { @@ -1865,17 +1847,7 @@ struct charset *charsetp; CHECK_CHARSET_GET_ID (charset, id); - if (CONSP (code_point)) - { - CHECK_NATNUM_CAR (code_point); - CHECK_NATNUM_CDR (code_point); - code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); - } - else - { - CHECK_NATNUM (code_point); - code = XINT (code_point); - } + code = cons_to_unsigned (code_point, UINT_MAX); charsetp = CHARSET_FROM_ID (id); c = DECODE_CHAR (charsetp, code); return (c >= 0 ? make_number (c) : Qnil); @@ -1900,9 +1872,7 @@ code = ENCODE_CHAR (charsetp, XINT (ch)); if (code == CHARSET_INVALID_CODE (charsetp)) return Qnil; - if (code > 0x7FFFFFF) - return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); - return make_number (code); + return INTEGER_TO_CONS (code); } === modified file 'src/composite.h' --- src/composite.h 2011-05-31 06:05:00 +0000 +++ src/composite.h 2011-06-02 18:54:35 +0000 @@ -265,10 +265,7 @@ #define LGLYPH_CODE(g) \ (NILP (AREF ((g), LGLYPH_IX_CODE)) \ ? FONT_INVALID_CODE \ - : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ - ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ - | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ - : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) + : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) @@ -280,15 +277,8 @@ #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) /* Callers must assure that VAL is not negative! */ #define LGLYPH_SET_CODE(g, val) \ - do { \ - if (val == FONT_INVALID_CODE) \ - ASET ((g), LGLYPH_IX_CODE, Qnil); \ - else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ - ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ - make_number ((val) & 0xFFFF))); \ - else \ - ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ - } while (0) + ASET (g, LGLYPH_IX_CODE, \ + val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) === modified file 'src/data.c' --- src/data.c 2011-05-31 14:57:53 +0000 +++ src/data.c 2011-06-02 07:38:44 +0000 @@ -23,8 +23,6 @@ #include #include -#include - #include "lisp.h" #include "puresize.h" #include "character.h" @@ -2326,33 +2324,89 @@ return Qnil; } -/* Convert between long values and pairs of Lisp integers. - Note that long_to_cons returns a single Lisp integer - when the value fits in one. */ +/* Convert the cons-of-integers, integer, or float value C to an + unsigned value with maximum value MAX. Signal an error if C does not + have a valid format or is out of range. */ +uintmax_t +cons_to_unsigned (Lisp_Object c, uintmax_t max) +{ + int valid = 0; + uintmax_t val IF_LINT (= 0); + if (INTEGERP (c)) + { + valid = 0 <= XINT (c); + val = XINT (c); + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (0 <= d + && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bot)) + { + uintmax_t utop = XFASTINT (top); + val = (utop << 16) | XFASTINT (bot); + valid = 1; + } + } -Lisp_Object -long_to_cons (long unsigned int i) -{ - unsigned long top = i >> 16; - unsigned int bot = i & 0xFFFF; - if (top == 0) - return make_number (bot); - if (top == (unsigned long)-1 >> 16) - return Fcons (make_number (-1), make_number (bot)); - return Fcons (make_number (top), make_number (bot)); + if (! (valid && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } -unsigned long -cons_to_long (Lisp_Object c) +/* Convert the cons-of-integers, integer, or float value C to a signed + value with extrema MIN and MAX. Signal an error if C does not have + a valid format or is out of range. */ +intmax_t +cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { - Lisp_Object top, bot; + int valid = 0; + intmax_t val IF_LINT (= 0); if (INTEGERP (c)) - return XINT (c); - top = XCAR (c); - bot = XCDR (c); - if (CONSP (bot)) - bot = XCAR (bot); - return ((XINT (top) << 16) | XINT (bot)); + { + val = XINT (c); + valid = 1; + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (min <= d + && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (INTEGERP (top) && INTMAX_MIN >> 16 <= XINT (top) + && XINT (top) <= INTMAX_MAX >> 16 && INTEGERP (bot)) + { + intmax_t itop = XINT (top); + val = (itop << 16) | XINT (bot); + valid = 1; + } + } + + if (! (valid && min <= val && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, === modified file 'src/dired.c' --- src/dired.c 2011-04-14 19:34:42 +0000 +++ src/dired.c 2011-06-03 05:24:22 +0000 @@ -901,10 +901,10 @@ 8. File modes, as a string of ten letters or dashes as in ls -l. 9. t if file's gid would change if file were deleted and recreated. 10. inode number. If inode number is larger than what Emacs integer - can hold, but still fits into a 32-bit number, this is a cons cell + can hold, but all but the bottom 16 bits still fits, this is a cons cell containing two integers: first the high part, then the low 16 bits. - If the inode number is wider than 32 bits, this is of the form - (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits, + If the inode number is still wider, this is of the form + (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, and finally the low 16 bits. 11. Filesystem device number. If it is larger than what the Emacs integer can hold, this is a cons cell, similar to the inode number. @@ -998,35 +998,24 @@ #else /* file gid will be egid */ values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; #endif /* not BSD4_2 */ - if (!FIXNUM_OVERFLOW_P (s.st_ino)) - /* Keep the most common cases as integers. */ - values[10] = make_number (s.st_ino); - else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) - /* To allow inode numbers larger than VALBITS, separate the bottom - 16 bits. */ - values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), - make_number ((EMACS_INT)(s.st_ino & 0xffff))); + if (! FIXNUM_OVERFLOW_P ((s.st_ino) >> 16)) + values[10] = INTEGER_TO_CONS (s.st_ino); else { - /* To allow inode numbers beyond 32 bits, separate into 2 24-bit - high parts and a 16-bit bottom part. + /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, + separate into 2 24-bit high parts and a 16-bit bottom part. The code on the next line avoids a compiler warning on systems where st_ino is 32 bit wide. (bug#766). */ EMACS_INT high_ino = s.st_ino >> 31 >> 1; - EMACS_INT low_ino = s.st_ino & 0xffffffff; values[10] = Fcons (make_number (high_ino >> 8), Fcons (make_number (((high_ino & 0xff) << 16) - + (low_ino >> 16)), - make_number (low_ino & 0xffff))); + + (s.st_ino >> 16 & 0xffff)), + make_number (s.st_ino & 0xffff))); } /* Likewise for device. */ - if (FIXNUM_OVERFLOW_P (s.st_dev)) - values[11] = Fcons (make_number (s.st_dev >> 16), - make_number (s.st_dev & 0xffff)); - else - values[11] = make_number (s.st_dev); + values[11] = INTEGER_TO_CONS (s.st_dev); return Flist (sizeof(values) / sizeof(values[0]), values); } === modified file 'src/editfns.c' --- src/editfns.c 2011-05-30 16:47:35 +0000 +++ src/editfns.c 2011-06-02 18:35:30 +0000 @@ -47,7 +47,6 @@ #include #include #include -#include #include #include === modified file 'src/fileio.c' --- src/fileio.c 2011-04-29 19:47:29 +0000 +++ src/fileio.c 2011-06-02 07:38:44 +0000 @@ -4960,7 +4960,7 @@ if ((st.st_mtime == b->modtime /* If both are positive, accept them if they are off by one second. */ || (st.st_mtime > 0 && b->modtime > 0 - && (st.st_mtime == b->modtime + 1 + && (st.st_mtime - 1 == b->modtime || st.st_mtime == b->modtime - 1))) && (st.st_size == b->modtime_size || b->modtime_size < 0)) @@ -4990,7 +4990,7 @@ { if (! current_buffer->modtime) return make_number (0); - return make_time ((time_t) current_buffer->modtime); + return make_time (current_buffer->modtime); } DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, @@ -5005,7 +5005,7 @@ { if (!NILP (time_list)) { - current_buffer->modtime = cons_to_long (time_list); + CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); current_buffer->modtime_size = -1; } else === modified file 'src/font.c' --- src/font.c 2011-05-29 19:04:01 +0000 +++ src/font.c 2011-06-02 07:38:44 +0000 @@ -4388,16 +4388,8 @@ for (i = 0; i < 255; i++) if (variations[i]) { - Lisp_Object code; int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); - /* Stops GCC whining about limited range of data type. */ - EMACS_INT var = variations[i]; - - if (var > MOST_POSITIVE_FIXNUM) - code = Fcons (make_number ((variations[i]) >> 16), - make_number ((variations[i]) & 0xFFFF)); - else - code = make_number (variations[i]); + Lisp_Object code = INTEGER_TO_CONS (variations[i]); val = Fcons (Fcons (make_number (vs), code), val); } return val; === modified file 'src/fontset.c' --- src/fontset.c 2011-05-28 22:39:39 +0000 +++ src/fontset.c 2011-06-02 07:38:44 +0000 @@ -1859,17 +1859,11 @@ { unsigned code = face->font->driver->encode_char (face->font, c); Lisp_Object font_object; - /* Assignment to EMACS_INT stops GCC whining about limited range - of data type. */ - EMACS_INT cod = code; if (code == FONT_INVALID_CODE) return Qnil; XSETFONT (font_object, face->font); - if (cod <= MOST_POSITIVE_FIXNUM) - return Fcons (font_object, make_number (code)); - return Fcons (font_object, Fcons (make_number (code >> 16), - make_number (code & 0xFFFF))); + return Fcons (font_object, INTEGER_TO_CONS (code)); } return Qnil; } === modified file 'src/ftfont.c' --- src/ftfont.c 2011-04-11 03:39:45 +0000 +++ src/ftfont.c 2011-06-01 02:49:12 +0000 @@ -815,7 +815,7 @@ goto err; for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) if (CHARACTERP (XCAR (chars)) - && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) + && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars)))) goto err; } } === modified file 'src/insdel.c' --- src/insdel.c 2011-05-21 04:33:23 +0000 +++ src/insdel.c 2011-06-02 06:17:35 +0000 @@ -21,8 +21,6 @@ #include #include -#include - #include "lisp.h" #include "intervals.h" #include "buffer.h" === modified file 'src/intervals.c' --- src/intervals.c 2011-05-28 22:39:39 +0000 +++ src/intervals.c 2011-06-02 06:17:35 +0000 @@ -39,7 +39,7 @@ #include #include -#include + #include "lisp.h" #include "intervals.h" #include "buffer.h" === modified file 'src/keyboard.c' --- src/keyboard.c 2011-05-28 22:39:39 +0000 +++ src/keyboard.c 2011-06-01 02:49:12 +0000 @@ -2395,8 +2395,8 @@ c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index)); if (STRINGP (Vexecuting_kbd_macro) - && (XINT (c) & 0x80) && (XUINT (c) <= 0xff)) - XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80)); + && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff)) + XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80)); executing_kbd_macro_index++; @@ -3321,7 +3321,7 @@ if (INTEGERP (c)) { if (XUINT (c) < 0x100) - putc (XINT (c), dribble); + putc (XUINT (c), dribble); else fprintf (dribble, " 0x%"pI"x", XUINT (c)); } @@ -6370,7 +6370,7 @@ Lisp_Object parsed; parsed = parse_modifiers (symbol); - return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))), + return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))), XCAR (parsed)); } === modified file 'src/keymap.c' --- src/keymap.c 2011-05-12 07:07:06 +0000 +++ src/keymap.c 2011-06-01 02:49:12 +0000 @@ -462,7 +462,7 @@ XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); /* Handle the special meta -> esc mapping. */ - if (INTEGERP (idx) && XUINT (idx) & meta_modifier) + if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) { /* See if there is a meta-map. If there's none, there is no binding for IDX, unless a default binding exists in MAP. */ @@ -480,7 +480,7 @@ if (CONSP (event_meta_map)) { map = event_meta_map; - idx = make_number (XUINT (idx) & ~meta_modifier); + idx = make_number (XFASTINT (idx) & ~meta_modifier); } else if (t_ok) /* Set IDX to t, so that we only find a default binding. */ @@ -529,7 +529,7 @@ } else if (VECTORP (binding)) { - if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding)) + if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding)) val = AREF (binding, XFASTINT (idx)); } else if (CHAR_TABLE_P (binding)) @@ -537,7 +537,7 @@ /* Character codes with modifiers are not included in a char-table. All character codes without modifiers are included. */ - if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) + if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) { val = Faref (binding, idx); /* `nil' has a special meaning for char-tables, so @@ -1357,7 +1357,7 @@ int modifiers; parsed = parse_modifiers (c); - modifiers = (int) XUINT (XCAR (XCDR (parsed))); + modifiers = XFASTINT (XCAR (XCDR (parsed))); base = XCAR (parsed); name = Fsymbol_name (base); /* This alist includes elements such as ("RET" . "\\r"). */ @@ -2416,7 +2416,7 @@ { char tem[KEY_DESCRIPTION_SIZE]; - *push_key_description (XUINT (key), tem, 1) = 0; + *push_key_description (XINT (key), tem, 1) = 0; return build_string (tem); } else if (SYMBOLP (key)) /* Function key or event-symbol */ @@ -2515,7 +2515,7 @@ return 0; else { - int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); + int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); if (modifiers == where_is_preferred_modifier) result = 2; else if (modifiers) === modified file 'src/lisp.h' --- src/lisp.h 2011-06-02 08:25:28 +0000 +++ src/lisp.h 2011-06-02 18:35:30 +0000 @@ -24,6 +24,8 @@ #include #include +#include + /* Use the configure flag --enable-checking[=LIST] to enable various types of run time checks for Lisp objects. */ @@ -34,13 +36,14 @@ #define CHECK_CONS_LIST() ((void) 0) #endif -/* Temporarily disable wider-than-pointer integers until they're tested more. - Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ -/* #undef WIDE_EMACS_INT */ +/* To disable wider-than-pointer integers, build with -DWIDE_EMACS_INT=0. */ +#ifndef WIDE_EMACS_INT +#define WIDE_EMACS_INT 1 +#endif /* These are default choices for the types to use. */ #ifndef EMACS_INT -# if BITS_PER_LONG < BITS_PER_LONG_LONG && defined WIDE_EMACS_INT +# if BITS_PER_LONG < BITS_PER_LONG_LONG && WIDE_EMACS_INT # define EMACS_INT long long # define BITS_PER_EMACS_INT BITS_PER_LONG_LONG # define pI "ll" @@ -2402,9 +2405,33 @@ EXFUN (Fsub1, 1); EXFUN (Fmake_variable_buffer_local, 1); +/* Convert the integer I to an Emacs representation, either the integer + itself, or a cons of two integers, or if all else fails a float. + The float might lose information; this happens only in extreme cases + such as 32-bit EMACS_INT and 64-bit time_t with outlandish time values, + and these aren't worth complicating the interface. + + I should not have side effects. */ +#define INTEGER_TO_CONS(i) \ + (! FIXNUM_OVERFLOW_P (i) \ + ? make_number (i) \ + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ + && FIXNUM_OVERFLOW_P ((i) >> 16)) \ + ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ + : make_float (i)) + +/* Convert the Emacs representation CONS back to an integer of type + TYPE, storing the result the variable VAR. Signal an error if CONS + is not a valid representation or is out of range for TYPE. */ +#define CONS_TO_INTEGER(cons, type, var) \ + (TYPE_SIGNED (type) \ + ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ + : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) +extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); +extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); + extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); -extern Lisp_Object long_to_cons (unsigned long); -extern unsigned long cons_to_long (Lisp_Object); extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; === modified file 'src/termhooks.h' --- src/termhooks.h 2011-05-27 16:17:59 +0000 +++ src/termhooks.h 2011-06-03 05:24:22 +0000 @@ -342,8 +342,8 @@ SELECTION-VALUE is the value that emacs owns for that selection. It may be any kind of Lisp object. SELECTION-TIMESTAMP is the time at which emacs began owning this - selection, as a cons of two 16-bit numbers (making a 32 bit - time.) + selection, as an Emacs integer; or if that doesn't fit, as a + cons of two 16-bit integers (making a 32 bit time.) FRAME is the frame for which we made the selection. If there is an entry in this alist, then it can be assumed that Emacs owns that selection. === modified file 'src/undo.c' --- src/undo.c 2011-04-14 05:04:02 +0000 +++ src/undo.c 2011-06-02 07:38:44 +0000 @@ -212,7 +212,6 @@ void record_first_change (void) { - Lisp_Object high, low; struct buffer *base_buffer = current_buffer; if (EQ (BVAR (current_buffer, undo_list), Qt)) @@ -225,9 +224,9 @@ if (base_buffer->base_buffer) base_buffer = base_buffer->base_buffer; - XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); - XSETFASTINT (low, base_buffer->modtime & 0xffff); - BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); + BVAR (current_buffer, undo_list) = + Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), + BVAR (current_buffer, undo_list)); } /* Record a change in property PROP (whose old value was VAL) @@ -499,13 +498,9 @@ if (EQ (car, Qt)) { /* Element (t high . low) records previous modtime. */ - Lisp_Object high, low; - int mod_time; struct buffer *base_buffer = current_buffer; - - high = Fcar (cdr); - low = Fcdr (cdr); - mod_time = (XFASTINT (high) << 16) + XFASTINT (low); + time_t mod_time; + CONS_TO_INTEGER (cdr, time_t, mod_time); if (current_buffer->base_buffer) base_buffer = current_buffer->base_buffer; === modified file 'src/xfns.c' --- src/xfns.c 2011-04-19 06:34:43 +0000 +++ src/xfns.c 2011-06-02 07:38:44 +0000 @@ -4295,18 +4295,9 @@ if (! NILP (source)) { - if (NUMBERP (source)) - { - if (FLOATP (source)) - target_window = (Window) XFLOAT (source); - else - target_window = XFASTINT (source); - - if (target_window == 0) - target_window = FRAME_X_DISPLAY_INFO (f)->root_window; - } - else if (CONSP (source)) - target_window = cons_to_long (source); + CONS_TO_INTEGER (source, Window, target_window); + if (! target_window) + target_window = FRAME_X_DISPLAY_INFO (f)->root_window; } BLOCK_INPUT; === modified file 'src/xselect.c' --- src/xselect.c 2011-05-29 05:23:24 +0000 +++ src/xselect.c 2011-06-02 07:38:44 +0000 @@ -335,7 +335,7 @@ Lisp_Object prev_value; selection_data = list4 (selection_name, selection_value, - long_to_cons (timestamp), frame); + INTEGER_TO_CONS (timestamp), frame); prev_value = LOCAL_SELECTION (selection_name, dpyinfo); dpyinfo->terminal->Vselection_alist @@ -419,7 +419,7 @@ || INTEGERP (check) || NILP (value)) return value; - /* Check for a value that cons_to_long could handle. */ + /* Check for a value that CONS_TO_INTEGER could handle. */ else if (CONSP (check) && INTEGERP (XCAR (check)) && (INTEGERP (XCDR (check)) @@ -782,8 +782,8 @@ if (NILP (local_selection_data)) goto DONE; /* Decline requests issued prior to our acquiring the selection. */ - local_selection_time - = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); if (SELECTION_EVENT_TIME (event) != CurrentTime && local_selection_time > SELECTION_EVENT_TIME (event)) goto DONE; @@ -950,8 +950,8 @@ /* Well, we already believe that we don't own it, so that's just fine. */ if (NILP (local_selection_data)) return; - local_selection_time = (Time) - cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); /* We have reasserted the selection since this SelectionClear was generated, so we can disregard it. */ @@ -1213,16 +1213,7 @@ return Qnil; if (! NILP (time_stamp)) - { - if (CONSP (time_stamp)) - requestor_time = (Time) cons_to_long (time_stamp); - else if (INTEGERP (time_stamp)) - requestor_time = (Time) XUINT (time_stamp); - else if (FLOATP (time_stamp)) - requestor_time = (Time) XFLOAT_DATA (time_stamp); - else - error ("TIME_STAMP must be cons or number"); - } + CONS_TO_INTEGER (time_stamp, Time, requestor_time); BLOCK_INPUT; @@ -1651,9 +1642,9 @@ If the number is 32 bits and won't fit in a Lisp_Int, convert it to a cons of integers, 16 bits in each half. */ - else if (format == 32 && size == sizeof (int)) - return long_to_cons (((unsigned int *) data) [0]); - else if (format == 16 && size == sizeof (short)) + else if (format == 32 && size == sizeof (unsigned int)) + return INTEGER_TO_CONS (((unsigned int *) data) [0]); + else if (format == 16 && size == sizeof (unsigned short)) return make_number ((int) (((unsigned short *) data) [0])); /* Convert any other kind of data to a vector of numbers, represented @@ -1678,7 +1669,7 @@ for (i = 0; i < size / 4; i++) { unsigned int j = ((unsigned int *) data) [i]; - Faset (v, make_number (i), long_to_cons (j)); + Faset (v, make_number (i), INTEGER_TO_CONS (j)); } return v; } @@ -1753,9 +1744,9 @@ { *format_ret = 32; *size_ret = 1; - *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); - (*data_ret) [sizeof (long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_long (obj); + *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); + (*data_ret) [sizeof (unsigned long)] = 0; + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1803,11 +1794,11 @@ *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); for (i = 0; i < *size_ret; i++) if (*format_ret == 32) - (*((unsigned long **) data_ret)) [i] - = cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned long **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); else - (*((unsigned short **) data_ret)) [i] - = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned short **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); } } else @@ -2025,8 +2016,10 @@ selection_atom = symbol_to_x_atom (dpyinfo, selection); BLOCK_INPUT; - timestamp = (NILP (time_object) ? last_event_timestamp - : cons_to_long (time_object)); + if (NILP (time_object)) + timestamp = last_event_timestamp; + else + CONS_TO_INTEGER (time_object, Time, timestamp); XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); UNBLOCK_INPUT; @@ -2232,12 +2225,8 @@ { Lisp_Object o = XCAR (iter); - if (INTEGERP (o)) - val = (long) XFASTINT (o); - else if (FLOATP (o)) - val = (long) XFLOAT_DATA (o); - else if (CONSP (o)) - val = (long) cons_to_long (o); + if (INTEGERP (o) || FLOATP (o) || CONSP (o)) + val = cons_to_signed (o, LONG_MIN, LONG_MAX); else if (STRINGP (o)) { BLOCK_INPUT; @@ -2248,9 +2237,19 @@ error ("Wrong type, must be string, number or cons"); if (format == 8) - *d08++ = (char) val; + { + if (CHAR_MIN <= val && val <= CHAR_MAX) + *d08++ = val; + else + error ("Out of 'char' range"); + } else if (format == 16) - *d16++ = (short) val; + { + if (SHRT_MIN <= val && val <= SHRT_MAX) + *d16++ = val; + else + error ("Out of 'short' range"); + } else *d32++ = val; } @@ -2334,14 +2333,7 @@ Atom atom; int had_errors; - if (INTEGERP (value)) - atom = (Atom) XUINT (value); - else if (FLOATP (value)) - atom = (Atom) XFLOAT_DATA (value); - else if (CONSP (value)) - atom = (Atom) cons_to_long (value); - else - error ("Wrong type, value must be number or cons"); + CONS_TO_INTEGER (value, Atom, atom); BLOCK_INPUT; x_catch_errors (dpy); @@ -2531,17 +2523,8 @@ else error ("DEST as a string must be one of PointerWindow or InputFocus"); } - else if (INTEGERP (dest)) - wdest = (Window) XFASTINT (dest); - else if (FLOATP (dest)) - wdest = (Window) XFLOAT_DATA (dest); - else if (CONSP (dest)) - { - if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) - error ("Both car and cdr for DEST must be numbers"); - else - wdest = (Window) cons_to_long (dest); - } + else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) + CONS_TO_INTEGER (dest, Window, wdest); else error ("DEST must be a frame, nil, string, number or cons"); # Begin bundle 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 L8P0Q+RsqHg521AOYL/8XckU4UJBF6/74A== From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 06:52:49 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 10:52:50 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSRzl-0006E9-Bx for submit@debbugs.gnu.org; Fri, 03 Jun 2011 06:52:49 -0400 Received: from mtaout20.012.net.il ([80.179.55.166]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSRzi-0006Dw-17 for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 06:52:47 -0400 Received: from conversion-daemon.a-mtaout20.012.net.il by a-mtaout20.012.net.il (HyperSendmail v2007.08) id <0LM700900NJAWC00@a-mtaout20.012.net.il> for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 13:52:39 +0300 (IDT) Received: from HOME-C4E4A596F7 ([84.229.223.140]) by a-mtaout20.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0LM700925NJQGU30@a-mtaout20.012.net.il>; Fri, 03 Jun 2011 13:52:39 +0300 (IDT) Date: Fri, 03 Jun 2011 13:52:50 +0300 From: Eli Zaretskii Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default In-reply-to: <4DE89EB8.9020202@cs.ucla.edu> X-012-Sender: halo1@inter.net.il To: Paul Eggert Message-id: <83oc2fdw59.fsf@gnu.org> References: <4DE89EB8.9020202@cs.ucla.edu> X-Spam-Score: -2.0 (--) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: Eli Zaretskii List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.0 (--) > Date: Fri, 03 Jun 2011 01:43:36 -0700 > From: Paul Eggert > > I found several problems in the Emacs code that converts > large C integers to Emacs conses-of-integers and back again. > I wrote some code to fix them systematically, and found that > it was simpler and more reliable if I could assume that EMACS_INT > was 64-bit even on 32-bit hosts. So here's a patch to do all that. I don't think we agreed to make that the only configurations on 32-bit machines. Did we? > +using that data type. For most machines, the maximum buffer size > +enforced by the data types is @math{2^61 - 2} bytes, or about 2 EiB. > +For some older machines, the maximum is @math{2^29 - 2} bytes, or > +about 512 MiB. Buffer sizes are also limited by the size of Emacs's > +virtual memory. Can 32-bit hosts really support buffers and strings larger than 2GB, even if EMACS_INT is a 64-bit type? I thought the largest object on a 32-but machine cannot exceed 2GB due to pointer arithmetics, which will wrap around after that. What am I missing? > Emacs cannot visit files that are larger than the maximum Emacs buffer > -size, which is around 512 megabytes on 32-bit machines > +size, which is around 512 MiB on 32-bit machines and 2 EiB on 64-bit machines > (@pxref{Buffers}). If you try, Emacs will display an error message > saying that the maximum buffer size has been exceeded. This seems to contradict what you said about buffers, doesn't it? > === modified file 'src/data.c' > --- src/data.c 2011-05-31 14:57:53 +0000 > +++ src/data.c 2011-06-02 07:38:44 +0000 > @@ -23,8 +23,6 @@ > [...] > + else if (FLOATP (c)) > + { > + double d = XFLOAT_DATA (c); > + if (0 <= d > + && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) > + { > + val = d; > + valid = 1; > + } > + } > + else if (CONSP (c)) > + { > + Lisp_Object top = XCAR (c); > + Lisp_Object bot = XCDR (c); > + if (CONSP (bot)) > + bot = XCAR (bot); > + if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bot)) > + { > + uintmax_t utop = XFASTINT (top); > + val = (utop << 16) | XFASTINT (bot); > + valid = 1; > + } > + } The *_MAX macros need limits.h, but I don't see it being included by data.c. Did I miss something? > +#define INTEGER_TO_CONS(i) \ > + (! FIXNUM_OVERFLOW_P (i) \ > + ? make_number (i) \ > + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ > + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ > + && FIXNUM_OVERFLOW_P ((i) >> 16)) \ > + ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ > + : make_float (i)) Same here (this is from lisp.h). But since every C file includes lisp.h, it looks like we need to include limits.h in lisp.h. From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 11:54:38 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 15:54:38 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSWhp-0006NQ-K7 for submit@debbugs.gnu.org; Fri, 03 Jun 2011 11:54:37 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSWhm-0006N9-TE for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 11:54:35 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:50028 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QSWhf-0001LE-L2; Fri, 03 Jun 2011 11:54:27 -0400 Received: by ceviche.home (Postfix, from userid 20848) id AE937660DD; Fri, 3 Jun 2011 12:54:23 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> Date: Fri, 03 Jun 2011 12:54:23 -0300 In-Reply-To: <4DE89EB8.9020202@cs.ucla.edu> (Paul Eggert's message of "Fri, 03 Jun 2011 01:43:36 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) > I found several problems in the Emacs code that converts > large C integers to Emacs conses-of-integers and back again. > I wrote some code to fix them systematically, and found that > it was simpler and more reliable if I could assume that EMACS_INT > was 64-bit even on 32-bit hosts. So here's a patch to do all that. > I plan to test this a bit more before committing. So, there are 3 parts: - fix the cons<->int conversions. - add a 64bit-on-32bit compilation option. - make that option the default. Please split it into those three parts. I'd rather keep the "change the default" for later, after we've gotten some experience with it. Stefan From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 13:54:11 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 17:54:11 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSYZW-0000ga-NI for submit@debbugs.gnu.org; Fri, 03 Jun 2011 13:54:11 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSYZU-0000gK-4T for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 13:54:09 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6F6C139E80F8; Fri, 3 Jun 2011 10:54:02 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8fVnGOZ6chlc; Fri, 3 Jun 2011 10:54:01 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 6A56239E80FF; Fri, 3 Jun 2011 10:54:01 -0700 (PDT) Message-ID: <4DE91FB3.80601@cs.ucla.edu> Date: Fri, 03 Jun 2011 10:53:55 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Eli Zaretskii Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default References: <4DE89EB8.9020202@cs.ucla.edu> <83oc2fdw59.fsf@gnu.org> In-Reply-To: <83oc2fdw59.fsf@gnu.org> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.2 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.2 (---) >> I wrote some code to fix them systematically, and found that >> it was simpler and more reliable if I could assume that EMACS_INT >> was 64-bit even on 32-bit hosts. > > I don't think we agreed to make that the only configurations on 32-bit > machines. Sorry, I should have explained more clearly. If there is a system integer type (such as ino_t or time_t) that is 64 bits, it's cleaner if EMACS_INT is also 64 bits. And in practice this requirement is not a problem, as any 32-bit host where some standard system types are 64 bits supports 64-bit integers quite well. On an old-fashioned host where all the system types are 32 bits, EMACS_INT can still be 32 bits. > Can 32-bit hosts really support buffers and strings larger than 2GB, > even if EMACS_INT is a 64-bit type? Yes, absolutely. For example: #include #include #include int main (void) { int big = 536870913; int *p = malloc (big * sizeof *p); if (!p) return 1; memset (p, 0xef, big * sizeof *p); printf ("%x %x\n", p[0], p[big - 1]); return 0; } On my RHEL 5.6 host, built as a 32-bit executable, this outputs: $ gcc -m32 t.c $ ./a.out efefefef efefefef even though the array's size does not fit in 'int' or 'long'. The same behavior can be observed on pure 32-bit systems; it's quite common and has been for years. > I thought the largest object on a > 32-but machine cannot exceed 2GB due to pointer arithmetics, No, but as shown above one can often allocate objects larger than 2 GiB on such machines. Perhaps you're thinking of pointer subtraction? That often stops working on arrays larger than 2 GiB. But this is easy to program around. And anyway, even if we assume buffers and strings are all smaller than 2 GiB, an EMACS_INT wider than 32 bits is still needed for large buffers and strings, due to the tag bits. >> Emacs cannot visit files that are larger than the maximum Emacs buffer >> -size, which is around 512 megabytes on 32-bit machines >> +size, which is around 512 MiB on 32-bit machines and 2 EiB on 64-bit machines >> (@pxref{Buffers}). If you try, Emacs will display an error message >> saying that the maximum buffer size has been exceeded. > > This seems to contradict what you said about buffers, doesn't it? Yes, thanks, I messed that up; I'll fix that part of the documentation. >> + if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bo> > The *_MAX macros need limits.h, but I don't see it being included by > data.c. Did I miss something? Those are OK because lisp.h includes inttypes.h. INTMAX_MAX and UINTMAX_MAX are defined by inttypes.h (actually, stdint.h, but inttypes.h includes stdint.h). Like you, I would have put all the _MIN and _MAX macros into limits.h, but I wasn't part of that design decision. From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 15:29:04 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:29:04 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3M-0002wP-10 for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:04 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3J-0002vx-PW for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:02 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 68A7539E80F8; Fri, 3 Jun 2011 12:28:55 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l67cP5sGReqh; Fri, 3 Jun 2011 12:28:55 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id F28C339E80F7; Fri, 3 Jun 2011 12:28:54 -0700 (PDT) Message-ID: <4DE935F6.2080802@cs.ucla.edu> Date: Fri, 03 Jun 2011 12:28:54 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default References: <4DE89EB8.9020202@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) On 06/03/11 08:54, Stefan Monnier wrote: > So, there are 3 parts: > - fix the cons<->int conversions. > - add a 64bit-on-32bit compilation option. > - make that option the default. > Please split it into those three parts. OK. The 2nd part is already done: just compile the Emacs trunk with -DWIDE_EMACS_INT. But I see the need for another part, containing some prerequisite fixes. So I'll send three followup emails: (a) straightforward fixes that I assume are uncontroversial (b) make 64bit-on-32bit the default (on 32bit systems that support it) (c) fix the cons<->int conversions Each part is a prerequisite for the next. Some of the fixes in (a) are not actually prerequisites, so if you want me to explode (a) into the dozen or so patches that it contains, then I can do that, but I'd rather not bother unless it's needed. From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 15:29:13 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:29:13 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3V-0002wl-7v for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:13 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3S-0002wW-JD for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:11 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 1DBCE39E80F8; Fri, 3 Jun 2011 12:29:05 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dPWuDtwuJxYX; Fri, 3 Jun 2011 12:29:04 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id E9AD639E80F7; Fri, 3 Jun 2011 12:29:03 -0700 (PDT) Message-ID: <4DE935FF.3020408@cs.ucla.edu> Date: Fri, 03 Jun 2011 12:29:03 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (a) straightforward prerequisite fixes References: <4DE89EB8.9020202@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-02 08:40:41 +0000 +++ src/ChangeLog 2011-06-03 18:22:12 +0000 @@ -1,3 +1,37 @@ +2011-06-03 Paul Eggert + + * xselect.c: Use 'unsigned' more consistently. + (selection_data_to_lisp_data, lisp_data_to_selection_data): + Use 'unsigned' consistently when computing sizes of unsigned objects. + + * fileio.c (Fverify_visited_file_modtime): Avoid time overflow + if b->modtime has its maximal value. + + * dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits. + + * lisp.h: Include , as it'll useful in later changes. + * character.c, data.c, editfns.c, insdel.c, intervals.c: + Don't include , since lisp.h does. + + Don't assume time_t can fit into int. + * buffer.h (struct buffer.modtime): Now time_t, not int. + * fileio.c (Fvisited_file_modtime): No need for time_t cast now. + * undo.c (Fprimitive_undo): Use time_t, not int, for time_t value. + + Minor fixes for signed vs unsigned integers. + * character.h (MAYBE_UNIFY_CHAR): + * charset.c (maybe_unify_char): + * keyboard.c (read_char, reorder_modifiers): + XINT -> XFASTINT, since the integer must be nonnegative. + * ftfont.c (ftfont_spec_pattern): + * keymap.c (access_keymap, silly_event_symbol_error): + XUINT -> XFASTINT, since the integer must be nonnegative. + (Fsingle_key_description, preferred_sequence_p): XUINT -> XINT, + since it makes no difference and we prefer signed. + * keyboard.c (record_char): Use XUINT when all the neighbors do. + (access_keymap): NATNUMP -> INTEGERP, since the integer must be + nonnegative. + 2011-06-02 Paul Eggert Malloc failure behavior now depends on size of allocation. === modified file 'src/buffer.h' --- src/buffer.h 2011-05-12 07:07:06 +0000 +++ src/buffer.h 2011-06-02 06:15:15 +0000 @@ -545,7 +545,7 @@ -1 means visited file was nonexistent. 0 means visited file modtime unknown; in no case complain about any mismatch on next save attempt. */ - int modtime; + time_t modtime; /* Size of the file when modtime was set. This is used to detect the case where the file grew while we were reading it, so the modtime is still the same (since it's rounded up to seconds) but we're actually === modified file 'src/character.c' --- src/character.c 2011-05-21 04:33:23 +0000 +++ src/character.c 2011-06-02 06:17:35 +0000 @@ -35,7 +35,7 @@ #include #include -#include + #include "lisp.h" #include "character.h" #include "buffer.h" === modified file 'src/character.h' --- src/character.h 2011-05-21 04:33:23 +0000 +++ src/character.h 2011-06-01 02:49:12 +0000 @@ -544,7 +544,7 @@ Lisp_Object val; \ val = CHAR_TABLE_REF (Vchar_unify_table, c); \ if (INTEGERP (val)) \ - c = XINT (val); \ + c = XFASTINT (val); \ else if (! NILP (val)) \ c = maybe_unify_char (c, val); \ } \ === modified file 'src/charset.c' --- src/charset.c 2011-05-31 06:05:00 +0000 +++ src/charset.c 2011-06-03 18:11:17 +0000 @@ -1637,7 +1637,7 @@ struct charset *charset; if (INTEGERP (val)) - return XINT (val); + return XFASTINT (val); if (NILP (val)) return c; @@ -1647,7 +1647,7 @@ { val = CHAR_TABLE_REF (Vchar_unify_table, c); if (! NILP (val)) - c = XINT (val); + c = XFASTINT (val); } else { === modified file 'src/data.c' --- src/data.c 2011-05-31 14:57:53 +0000 +++ src/data.c 2011-06-02 06:17:35 +0000 @@ -23,8 +23,6 @@ #include #include -#include - #include "lisp.h" #include "puresize.h" #include "character.h" === modified file 'src/dired.c' --- src/dired.c 2011-04-14 19:34:42 +0000 +++ src/dired.c 2011-06-02 06:21:13 +0000 @@ -1013,12 +1013,11 @@ The code on the next line avoids a compiler warning on systems where st_ino is 32 bit wide. (bug#766). */ EMACS_INT high_ino = s.st_ino >> 31 >> 1; - EMACS_INT low_ino = s.st_ino & 0xffffffff; values[10] = Fcons (make_number (high_ino >> 8), Fcons (make_number (((high_ino & 0xff) << 16) - + (low_ino >> 16)), - make_number (low_ino & 0xffff))); + + (s.st_ino >> 16 & 0xffff)), + make_number (s.st_ino & 0xffff))); } /* Likewise for device. */ === modified file 'src/editfns.c' --- src/editfns.c 2011-05-30 16:47:35 +0000 +++ src/editfns.c 2011-06-03 18:14:49 +0000 @@ -47,7 +47,6 @@ #include #include #include -#include #include #include === modified file 'src/fileio.c' --- src/fileio.c 2011-04-29 19:47:29 +0000 +++ src/fileio.c 2011-06-02 06:23:20 +0000 @@ -4960,7 +4960,7 @@ if ((st.st_mtime == b->modtime /* If both are positive, accept them if they are off by one second. */ || (st.st_mtime > 0 && b->modtime > 0 - && (st.st_mtime == b->modtime + 1 + && (st.st_mtime - 1 == b->modtime || st.st_mtime == b->modtime - 1))) && (st.st_size == b->modtime_size || b->modtime_size < 0)) @@ -4990,7 +4990,7 @@ { if (! current_buffer->modtime) return make_number (0); - return make_time ((time_t) current_buffer->modtime); + return make_time (current_buffer->modtime); } DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, === modified file 'src/ftfont.c' --- src/ftfont.c 2011-04-11 03:39:45 +0000 +++ src/ftfont.c 2011-06-01 02:49:12 +0000 @@ -815,7 +815,7 @@ goto err; for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) if (CHARACTERP (XCAR (chars)) - && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) + && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars)))) goto err; } } === modified file 'src/insdel.c' --- src/insdel.c 2011-05-21 04:33:23 +0000 +++ src/insdel.c 2011-06-02 06:17:35 +0000 @@ -21,8 +21,6 @@ #include #include -#include - #include "lisp.h" #include "intervals.h" #include "buffer.h" === modified file 'src/intervals.c' --- src/intervals.c 2011-05-28 22:39:39 +0000 +++ src/intervals.c 2011-06-02 06:17:35 +0000 @@ -39,7 +39,7 @@ #include #include -#include + #include "lisp.h" #include "intervals.h" #include "buffer.h" === modified file 'src/keyboard.c' --- src/keyboard.c 2011-05-28 22:39:39 +0000 +++ src/keyboard.c 2011-06-01 02:49:12 +0000 @@ -2395,8 +2395,8 @@ c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index)); if (STRINGP (Vexecuting_kbd_macro) - && (XINT (c) & 0x80) && (XUINT (c) <= 0xff)) - XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80)); + && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff)) + XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80)); executing_kbd_macro_index++; @@ -3321,7 +3321,7 @@ if (INTEGERP (c)) { if (XUINT (c) < 0x100) - putc (XINT (c), dribble); + putc (XUINT (c), dribble); else fprintf (dribble, " 0x%"pI"x", XUINT (c)); } @@ -6370,7 +6370,7 @@ Lisp_Object parsed; parsed = parse_modifiers (symbol); - return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))), + return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))), XCAR (parsed)); } === modified file 'src/keymap.c' --- src/keymap.c 2011-05-12 07:07:06 +0000 +++ src/keymap.c 2011-06-01 02:49:12 +0000 @@ -462,7 +462,7 @@ XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); /* Handle the special meta -> esc mapping. */ - if (INTEGERP (idx) && XUINT (idx) & meta_modifier) + if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) { /* See if there is a meta-map. If there's none, there is no binding for IDX, unless a default binding exists in MAP. */ @@ -480,7 +480,7 @@ if (CONSP (event_meta_map)) { map = event_meta_map; - idx = make_number (XUINT (idx) & ~meta_modifier); + idx = make_number (XFASTINT (idx) & ~meta_modifier); } else if (t_ok) /* Set IDX to t, so that we only find a default binding. */ @@ -529,7 +529,7 @@ } else if (VECTORP (binding)) { - if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding)) + if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding)) val = AREF (binding, XFASTINT (idx)); } else if (CHAR_TABLE_P (binding)) @@ -537,7 +537,7 @@ /* Character codes with modifiers are not included in a char-table. All character codes without modifiers are included. */ - if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) + if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) { val = Faref (binding, idx); /* `nil' has a special meaning for char-tables, so @@ -1357,7 +1357,7 @@ int modifiers; parsed = parse_modifiers (c); - modifiers = (int) XUINT (XCAR (XCDR (parsed))); + modifiers = XFASTINT (XCAR (XCDR (parsed))); base = XCAR (parsed); name = Fsymbol_name (base); /* This alist includes elements such as ("RET" . "\\r"). */ @@ -2416,7 +2416,7 @@ { char tem[KEY_DESCRIPTION_SIZE]; - *push_key_description (XUINT (key), tem, 1) = 0; + *push_key_description (XINT (key), tem, 1) = 0; return build_string (tem); } else if (SYMBOLP (key)) /* Function key or event-symbol */ @@ -2515,7 +2515,7 @@ return 0; else { - int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); + int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); if (modifiers == where_is_preferred_modifier) result = 2; else if (modifiers) === modified file 'src/lisp.h' --- src/lisp.h 2011-06-02 08:25:28 +0000 +++ src/lisp.h 2011-06-03 18:14:49 +0000 @@ -24,6 +24,8 @@ #include #include +#include + /* Use the configure flag --enable-checking[=LIST] to enable various types of run time checks for Lisp objects. */ === modified file 'src/undo.c' --- src/undo.c 2011-04-14 05:04:02 +0000 +++ src/undo.c 2011-06-02 06:15:15 +0000 @@ -500,7 +500,7 @@ { /* Element (t high . low) records previous modtime. */ Lisp_Object high, low; - int mod_time; + time_t mod_time; struct buffer *base_buffer = current_buffer; high = Fcar (cdr); === modified file 'src/xselect.c' --- src/xselect.c 2011-05-29 05:23:24 +0000 +++ src/xselect.c 2011-06-03 18:22:12 +0000 @@ -1651,9 +1651,9 @@ If the number is 32 bits and won't fit in a Lisp_Int, convert it to a cons of integers, 16 bits in each half. */ - else if (format == 32 && size == sizeof (int)) + else if (format == 32 && size == sizeof (unsigned int)) return long_to_cons (((unsigned int *) data) [0]); - else if (format == 16 && size == sizeof (short)) + else if (format == 16 && size == sizeof (unsigned short)) return make_number ((int) (((unsigned short *) data) [0])); /* Convert any other kind of data to a vector of numbers, represented @@ -1753,8 +1753,8 @@ { *format_ret = 32; *size_ret = 1; - *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); - (*data_ret) [sizeof (long)] = 0; + *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); + (*data_ret) [sizeof (unsigned long)] = 0; (*(unsigned long **) data_ret) [0] = cons_to_long (obj); if (NILP (type)) type = QINTEGER; } From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 15:29:35 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:29:35 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3q-0002xP-UM for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:35 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa3n-0002xB-AR for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:29:33 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id DE1B739E80F8; Fri, 3 Jun 2011 12:29:25 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8MigPAC6uDJk; Fri, 3 Jun 2011 12:29:20 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id BC89839E80F7; Fri, 3 Jun 2011 12:29:20 -0700 (PDT) Message-ID: <4DE93610.4040209@cs.ucla.edu> Date: Fri, 03 Jun 2011 12:29:20 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (b) make the 64bit-on-32bit the default (if supported) References: <4DE89EB8.9020202@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) Almost all of this is documentation change. The only code change is the lisp.h change to the default. === modified file 'doc/emacs/ChangeLog' --- doc/emacs/ChangeLog 2011-05-28 18:22:08 +0000 +++ doc/emacs/ChangeLog 2011-06-03 18:47:14 +0000 @@ -1,3 +1,9 @@ +2011-06-02 Paul Eggert + + Document wide integers better. + * buffers.texi (Buffers): + * files.texi (Visiting): Default buffer maximum is now 2 EiB typically. + 2011-05-28 Chong Yidong * custom.texi (Hooks): Reorganize. Mention Prog mode. === modified file 'doc/emacs/buffers.texi' --- doc/emacs/buffers.texi 2011-01-25 04:08:28 +0000 +++ doc/emacs/buffers.texi 2011-06-03 18:47:14 +0000 @@ -43,8 +43,11 @@ A buffer's size cannot be larger than some maximum, which is defined by the largest buffer position representable by the @dfn{Emacs integer} data type. This is because Emacs tracks buffer positions -using that data type. For 32-bit machines, the largest buffer size is -512 megabytes. +using that data type. For most machines, the maximum buffer size +enforced by the data types is @math{2^61 - 2} bytes, or about 2 EiB. +For some older machines, the maximum is @math{2^29 - 2} bytes, or +about 512 MiB. Buffer sizes are also limited by the size of Emacs's +virtual memory. @menu * Select Buffer:: Creating a new buffer or reselecting an old one. === modified file 'doc/emacs/files.texi' --- doc/emacs/files.texi 2011-01-31 23:54:50 +0000 +++ doc/emacs/files.texi 2011-06-03 18:47:14 +0000 @@ -209,7 +209,8 @@ about 10 megabytes), Emacs asks you for confirmation first. You can answer @kbd{y} to proceed with visiting the file. Note, however, that Emacs cannot visit files that are larger than the maximum Emacs buffer -size, which is around 512 megabytes on 32-bit machines +size, which is limited by the amount of memory Emacs can allocate +and by the integers that Emacs can represent (@pxref{Buffers}). If you try, Emacs will display an error message saying that the maximum buffer size has been exceeded. === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2011-05-31 18:40:00 +0000 +++ doc/lispref/ChangeLog 2011-06-03 18:49:33 +0000 @@ -1,3 +1,12 @@ +2011-06-03 Paul Eggert + + Document wide integers better. + * files.texi (File Attributes): Document ino_t values better. + * numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations): + (Bitwise Operations): + * objects.texi (Integer Type): Integers are typically 62 bits now. + * os.texi (Time Conversion): Document time_t values better. + 2011-05-31 Lars Magne Ingebrigtsen * processes.texi (Process Information): Document === modified file 'doc/lispref/files.texi' --- doc/lispref/files.texi 2011-05-12 07:07:06 +0000 +++ doc/lispref/files.texi 2011-06-03 18:49:33 +0000 @@ -1236,12 +1236,13 @@ @item The file's inode number. If possible, this is an integer. If the -inode number is too large to be represented as an integer in Emacs -Lisp, but still fits into a 32-bit integer, then the value has the -form @code{(@var{high} . @var{low})}, where @var{low} holds the low 16 -bits. If the inode is wider than 32 bits, the value is of the form +inode number @math{N} is too large to be represented as an integer in +Emacs Lisp, but @math{N / 2^16} is representable, then the value has +the form @code{(@var{high} . @var{low})}, where @var{high} holds the +high bits (i.e., excluding the low-order bits) and @var{low} the low +16 bits. If the inode number is even larger, the value is of the form @code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds -the high 24 bits, @var{middle} the next 24 bits, and @var{low} the low +the high bits, @var{middle} the next 24 bits, and @var{low} the low 16 bits. @item === modified file 'doc/lispref/numbers.texi' --- doc/lispref/numbers.texi 2011-05-05 06:31:14 +0000 +++ doc/lispref/numbers.texi 2011-06-03 18:49:33 +0000 @@ -36,22 +36,24 @@ @section Integer Basics The range of values for an integer depends on the machine. The -minimum range is @minus{}536870912 to 536870911 (30 bits; i.e., +typical range is @minus{}2305843009213693952 to 2305843009213693951 +(62 bits; i.e., @ifnottex --2**29 +-2**61 @end ifnottex @tex -@math{-2^{29}} +@math{-2^{61}} @end tex to @ifnottex -2**29 - 1), +2**61 - 1) @end ifnottex @tex -@math{2^{29}-1}), +@math{2^{61}-1}) @end tex -but some machines may provide a wider range. Many examples in this -chapter assume an integer has 30 bits. +but some older machines provide only 30 bits. Many examples in this +chapter assume that an integer has 62 bits and that floating point +numbers are IEEE double precision. @cindex overflow The Lisp reader reads an integer as a sequence of digits with optional @@ -63,7 +65,8 @@ 1. ; @r{The integer 1.} +1 ; @r{Also the integer 1.} -1 ; @r{The integer @minus{}1.} - 1073741825 ; @r{The floating point number 1073741825.0.} + 4611686018427387904 + ; @r{The floating point number 4.611686018427388e+18.} 0 ; @r{The integer 0.} -0 ; @r{The integer 0.} @end example @@ -94,25 +97,21 @@ bitwise operators (@pxref{Bitwise Operations}), it is often helpful to view the numbers in their binary form. - In 30-bit binary, the decimal integer 5 looks like this: + In 62-bit binary, the decimal integer 5 looks like this: @example -00 0000 0000 0000 0000 0000 0000 0101 +0000...000101 (62 bits total) @end example -@noindent -(We have inserted spaces between groups of 4 bits, and two spaces -between groups of 8 bits, to make the binary integer easier to read.) - The integer @minus{}1 looks like this: @example -11 1111 1111 1111 1111 1111 1111 1111 +1111...111111 (62 bits total) @end example @noindent @cindex two's complement -@minus{}1 is represented as 30 ones. (This is called @dfn{two's +@minus{}1 is represented as 62 ones. (This is called @dfn{two's complement} notation.) The negative integer, @minus{}5, is creating by subtracting 4 from @@ -120,24 +119,24 @@ @minus{}5 looks like this: @example -11 1111 1111 1111 1111 1111 1111 1011 +1111...111011 (62 bits total) @end example - In this implementation, the largest 30-bit binary integer value is -536,870,911 in decimal. In binary, it looks like this: + In this implementation, the largest 62-bit binary integer value is +2,305,843,009,213,693,951 in decimal. In binary, it looks like this: @example -01 1111 1111 1111 1111 1111 1111 1111 +0111...111111 (62 bits total) @end example Since the arithmetic functions do not check whether integers go -outside their range, when you add 1 to 536,870,911, the value is the -negative integer @minus{}536,870,912: +outside their range, when you add 1 to 2,305,843,009,213,693,951, the value is the +negative integer @minus{}2,305,843,009,213,693,952: @example -(+ 1 536870911) - @result{} -536870912 - @result{} 10 0000 0000 0000 0000 0000 0000 0000 +(+ 1 2305843009213693951) + @result{} -2305843009213693952 + @result{} 1000...000000 (62 bits total) @end example Many of the functions described in this chapter accept markers for @@ -508,8 +507,8 @@ if any argument is floating. It is important to note that in Emacs Lisp, arithmetic functions -do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to -@minus{}268435456, depending on your hardware. +do not check for overflow. Thus @code{(1+ 2305843009213693951)} may +evaluate to @minus{}2305843009213693952, depending on your hardware. @defun 1+ number-or-marker This function returns @var{number-or-marker} plus 1. @@ -829,19 +828,19 @@ The function @code{lsh}, like all Emacs Lisp arithmetic functions, does not check for overflow, so shifting left can discard significant bits and change the sign of the number. For example, left shifting -536,870,911 produces @minus{}2 on a 30-bit machine: +2,305,843,009,213,693,951 produces @minus{}2 on a typical machine: @example -(lsh 536870911 1) ; @r{left shift} +(lsh 2305843009213693951 1) ; @r{left shift} @result{} -2 @end example -In binary, in the 30-bit implementation, the argument looks like this: +In binary, in the 62-bit implementation, the argument looks like this: @example @group -;; @r{Decimal 536,870,911} -01 1111 1111 1111 1111 1111 1111 1111 +;; @r{Decimal 2,305,843,009,213,693,951} +0111...111111 (62 bits total) @end group @end example @@ -851,7 +850,7 @@ @example @group ;; @r{Decimal @minus{}2} -11 1111 1111 1111 1111 1111 1111 1110 +1111...111110 (62 bits total) @end group @end example @end defun @@ -874,9 +873,9 @@ @group (ash -6 -1) @result{} -3 ;; @r{Decimal @minus{}6 becomes decimal @minus{}3.} -11 1111 1111 1111 1111 1111 1111 1010 +1111...111010 (62 bits total) @result{} -11 1111 1111 1111 1111 1111 1111 1101 +1111...111101 (62 bits total) @end group @end example @@ -885,11 +884,11 @@ @example @group -(lsh -6 -1) @result{} 536870909 -;; @r{Decimal @minus{}6 becomes decimal 536,870,909.} -11 1111 1111 1111 1111 1111 1111 1010 +(lsh -6 -1) @result{} 2305843009213693949 +;; @r{Decimal @minus{}6 becomes decimal 2,305,843,009,213,693,949.} +1111...111010 (62 bits total) @result{} -01 1111 1111 1111 1111 1111 1111 1101 +0111...111101 (62 bits total) @end group @end example @@ -899,34 +898,35 @@ @c with smallbook but not with regular book! --rjc 16mar92 @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(lsh 5 2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 20 ; = @r{00 0000 0000 0000 0000 0000 0001 0100} +(lsh 5 2) ; 5 = @r{0000...000101} + @result{} 20 ; = @r{0000...010100} @end group @group (ash 5 2) @result{} 20 -(lsh -5 2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} -20 ; = @r{11 1111 1111 1111 1111 1111 1110 1100} +(lsh -5 2) ; -5 = @r{1111...111011} + @result{} -20 ; = @r{1111...101100} (ash -5 2) @result{} -20 @end group @group -(lsh 5 -2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 1 ; = @r{00 0000 0000 0000 0000 0000 0000 0001} +(lsh 5 -2) ; 5 = @r{0000...000101} + @result{} 1 ; = @r{0000...000001} @end group @group (ash 5 -2) @result{} 1 @end group @group -(lsh -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} 268435454 ; = @r{00 0111 1111 1111 1111 1111 1111 1110} +(lsh -5 -2) ; -5 = @r{1111...111011} + @result{} 1152921504606846974 + ; = @r{0011...111110} @end group @group -(ash -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} - @result{} -2 ; = @r{11 1111 1111 1111 1111 1111 1111 1110} +(ash -5 -2) ; -5 = @r{1111...111011} + @result{} -2 ; = @r{1111...111110} @end group @end smallexample @end defun @@ -961,23 +961,23 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logand 14 13) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} - @result{} 12 ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} +(logand 14 13) ; 14 = @r{0000...001110} + ; 13 = @r{0000...001101} + @result{} 12 ; 12 = @r{0000...001100} @end group @group -(logand 14 13 4) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} - ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} - @result{} 4 ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} +(logand 14 13 4) ; 14 = @r{0000...001110} + ; 13 = @r{0000...001101} + ; 4 = @r{0000...000100} + @result{} 4 ; 4 = @r{0000...000100} @end group @group (logand) - @result{} -1 ; -1 = @r{11 1111 1111 1111 1111 1111 1111 1111} + @result{} -1 ; -1 = @r{1111...111111} @end group @end smallexample @end defun @@ -991,18 +991,18 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logior 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 13 ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} +(logior 12 5) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + @result{} 13 ; 13 = @r{0000...001101} @end group @group -(logior 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} - @result{} 15 ; 15 = @r{00 0000 0000 0000 0000 0000 0000 1111} +(logior 12 5 7) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + ; 7 = @r{0000...000111} + @result{} 15 ; 15 = @r{0000...001111} @end group @end smallexample @end defun @@ -1016,18 +1016,18 @@ @smallexample @group - ; @r{ 30-bit binary values} + ; @r{ 62-bit binary values} -(logxor 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - @result{} 9 ; 9 = @r{00 0000 0000 0000 0000 0000 0000 1001} +(logxor 12 5) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + @result{} 9 ; 9 = @r{0000...001001} @end group @group -(logxor 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} - @result{} 14 ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} +(logxor 12 5 7) ; 12 = @r{0000...001100} + ; 5 = @r{0000...000101} + ; 7 = @r{0000...000111} + @result{} 14 ; 14 = @r{0000...001110} @end group @end smallexample @end defun @@ -1040,9 +1040,9 @@ @example (lognot 5) @result{} -6 -;; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} +;; 5 = @r{0000...000101} (62 bits total) ;; @r{becomes} -;; -6 = @r{11 1111 1111 1111 1111 1111 1111 1010} +;; -6 = @r{1111...111010} (62 bits total) @end example @end defun === modified file 'doc/lispref/objects.texi' --- doc/lispref/objects.texi 2011-05-05 06:31:14 +0000 +++ doc/lispref/objects.texi 2011-06-03 18:49:33 +0000 @@ -164,25 +164,25 @@ @node Integer Type @subsection Integer Type - The range of values for integers in Emacs Lisp is @minus{}536870912 to -536870911 (30 bits; i.e., + The range of values for integers in Emacs Lisp is +@minus{}2305843009213693952 to 2305843009213693951 (62 bits; i.e., @ifnottex --2**29 +-2**61 @end ifnottex @tex -@math{-2^{29}} +@math{-2^{61}} @end tex to @ifnottex -2**29 - 1) +2**61 - 1) @end ifnottex @tex -@math{2^{29}-1}) +@math{2^{61}-1}) @end tex -on most machines. (Some machines may provide a wider range.) It is -important to note that the Emacs Lisp arithmetic functions do not check -for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most -machines. +on most machines. Some machines may provide a narrower or wider +range; all machines provide at least 30 bits. Emacs Lisp arithmetic +functions do not check for overflow. Thus @code{(1+ +2305843009213693951)} is @minus{}2305843009213693952 on most machines. The read syntax for integers is a sequence of (base ten) digits with an optional sign at the beginning and an optional period at the end. The @@ -195,7 +195,6 @@ 1 ; @r{The integer 1.} 1. ; @r{Also the integer 1.} +1 ; @r{Also the integer 1.} -1073741825 ; @r{Also the integer 1 on a 30-bit implementation.} @end group @end example @@ -203,8 +202,8 @@ As a special exception, if a sequence of digits specifies an integer too large or too small to be a valid integer object, the Lisp reader reads it as a floating-point number (@pxref{Floating Point Type}). -For instance, on most machines @code{536870912} is read as the -floating-point number @code{536870912.0}. +For instance, on most machines @code{2305843009213693952} is read as the +floating-point number @code{2.305843009213694e+18}. @xref{Numbers}, for more information. === modified file 'doc/lispref/os.texi' --- doc/lispref/os.texi 2011-02-01 07:23:48 +0000 +++ doc/lispref/os.texi 2011-06-03 18:49:33 +0000 @@ -1193,11 +1193,11 @@ from the functions @code{current-time} (@pxref{Time of Day}) and @code{file-attributes} (@pxref{Definition of file-attributes}). - Many operating systems are limited to time values that contain 32 bits + Many 32-bit operating systems are limited to time values that contain 32 bits of information; these systems typically handle only the times from -1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, some -operating systems have larger time values, and can represent times far -in the past or future. +1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, 64-bit +and some 32-bit operating systems have larger time values, and can +represent times far in the past or future. Time conversion functions always use the Gregorian calendar, even for dates before the Gregorian calendar was introduced. Year numbers === modified file 'etc/ChangeLog' --- etc/ChangeLog 2011-05-24 14:22:44 +0000 +++ etc/ChangeLog 2011-06-03 18:42:04 +0000 @@ -1,3 +1,7 @@ +2011-06-03 Paul Eggert + + * NEWS: 62-bit integers are typical now. + 2011-05-24 Leo Liu * NEWS: Mention the new primitive sha1 and the removal of sha1.el. === modified file 'etc/NEWS' --- etc/NEWS 2011-06-01 15:34:41 +0000 +++ etc/NEWS 2011-06-03 18:42:04 +0000 @@ -902,6 +902,14 @@ *** New function `special-variable-p' to check whether a variable is declared as dynamically bound. +** Emacs integers have a wider range on typical 32-bit hosts. +Previously, they were limited to a 30-bit range (-2**29 .. 2**29-1). +Now, they are limited to a 62-bit range (-2**61 .. 2**61-1), the +same as on 64-bit hosts. This increased range comes from the Emacs +interpreter using 64-bit native integer types that are available +on typical modern 32-bit platforms. Older 32-bit hosts that lack +64-bit integers have the same 30-bit range as before. + ** pre/post-command-hook are not reset to nil upon error. Instead, the offending function is removed. === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-03 18:22:12 +0000 +++ src/ChangeLog 2011-06-03 18:42:59 +0000 @@ -1,5 +1,14 @@ 2011-06-03 Paul Eggert + Fix doc for machines with wider system times such as time_t. + On such machines, it's now safe to assume that EMACS_INT is as + wide as the system times, so that shifting right by 16 will + result in an integer that always fits in EMACS_INT. + * dired.c (Ffile_attributes): Document large inode number handling. + * termhooks.h: Fix comment for large time stamp handling. + + * lisp.h (WIDE_EMACS_INT): Now defaults to 1. + * xselect.c: Use 'unsigned' more consistently. (selection_data_to_lisp_data, lisp_data_to_selection_data): Use 'unsigned' consistently when computing sizes of unsigned objects. === modified file 'src/dired.c' --- src/dired.c 2011-06-02 06:21:13 +0000 +++ src/dired.c 2011-06-03 18:42:59 +0000 @@ -901,10 +901,10 @@ 8. File modes, as a string of ten letters or dashes as in ls -l. 9. t if file's gid would change if file were deleted and recreated. 10. inode number. If inode number is larger than what Emacs integer - can hold, but still fits into a 32-bit number, this is a cons cell + can hold, but all but the bottom 16 bits still fits, this is a cons cell containing two integers: first the high part, then the low 16 bits. - If the inode number is wider than 32 bits, this is of the form - (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits, + If the inode number is still wider, this is of the form + (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, and finally the low 16 bits. 11. Filesystem device number. If it is larger than what the Emacs integer can hold, this is a cons cell, similar to the inode number. @@ -1008,8 +1008,8 @@ make_number ((EMACS_INT)(s.st_ino & 0xffff))); else { - /* To allow inode numbers beyond 32 bits, separate into 2 24-bit - high parts and a 16-bit bottom part. + /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, + separate into 2 24-bit high parts and a 16-bit bottom part. The code on the next line avoids a compiler warning on systems where st_ino is 32 bit wide. (bug#766). */ EMACS_INT high_ino = s.st_ino >> 31 >> 1; === modified file 'src/lisp.h' --- src/lisp.h 2011-06-03 18:14:49 +0000 +++ src/lisp.h 2011-06-03 18:28:20 +0000 @@ -36,13 +36,14 @@ #define CHECK_CONS_LIST() ((void) 0) #endif -/* Temporarily disable wider-than-pointer integers until they're tested more. - Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ -/* #undef WIDE_EMACS_INT */ +/* To disable wider-than-pointer integers, build with -DWIDE_EMACS_INT=0. */ +#ifndef WIDE_EMACS_INT +#define WIDE_EMACS_INT 1 +#endif /* These are default choices for the types to use. */ #ifndef EMACS_INT -# if BITS_PER_LONG < BITS_PER_LONG_LONG && defined WIDE_EMACS_INT +# if BITS_PER_LONG < BITS_PER_LONG_LONG && WIDE_EMACS_INT # define EMACS_INT long long # define BITS_PER_EMACS_INT BITS_PER_LONG_LONG # define pI "ll" === modified file 'src/termhooks.h' --- src/termhooks.h 2011-05-27 16:17:59 +0000 +++ src/termhooks.h 2011-06-03 18:42:59 +0000 @@ -342,8 +342,8 @@ SELECTION-VALUE is the value that emacs owns for that selection. It may be any kind of Lisp object. SELECTION-TIMESTAMP is the time at which emacs began owning this - selection, as a cons of two 16-bit numbers (making a 32 bit - time.) + selection, as an Emacs integer; or if that doesn't fit, as a + cons of two 16-bit integers (making a 32 bit time.) FRAME is the frame for which we made the selection. If there is an entry in this alist, then it can be assumed that Emacs owns that selection. From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 15:30:15 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:30:15 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa4T-0002z6-TR for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:30:15 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSa4R-0002yt-40 for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:30:13 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6B74739E80F8; Fri, 3 Jun 2011 12:30:05 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MjuL-x4+4Dsv; Fri, 3 Jun 2011 12:30:03 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 9996B39E80F7; Fri, 3 Jun 2011 12:30:03 -0700 (PDT) Message-ID: <4DE9363B.7090504@cs.ucla.edu> Date: Fri, 03 Jun 2011 12:30:03 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (c) fix the cons<->int conversions References: <4DE89EB8.9020202@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2011-06-03 18:49:33 +0000 +++ doc/lispref/ChangeLog 2011-06-03 19:04:41 +0000 @@ -2,6 +2,8 @@ Document wide integers better. * files.texi (File Attributes): Document ino_t values better. + ino_t values no longer map to anything larger than a single cons. + * numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations): (Bitwise Operations): * objects.texi (Integer Type): Integers are typically 62 bits now. === modified file 'doc/lispref/files.texi' --- doc/lispref/files.texi 2011-06-03 18:49:33 +0000 +++ doc/lispref/files.texi 2011-06-03 19:04:41 +0000 @@ -1237,13 +1237,9 @@ @item The file's inode number. If possible, this is an integer. If the inode number @math{N} is too large to be represented as an integer in -Emacs Lisp, but @math{N / 2^16} is representable, then the value has -the form @code{(@var{high} . @var{low})}, where @var{high} holds the -high bits (i.e., excluding the low-order bits) and @var{low} the low -16 bits. If the inode number is even larger, the value is of the form -@code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds -the high bits, @var{middle} the next 24 bits, and @var{low} the low -16 bits. +Emacs Lisp, then the value has the form @code{(@var{high} +. @var{low})}, where @var{high} holds the high bits (i.e., all but the +low 16 bits) and @var{low} the low 16 bits. @item The filesystem number of the device that the file is on. Depending on === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-03 18:42:59 +0000 +++ src/ChangeLog 2011-06-03 19:02:25 +0000 @@ -1,5 +1,32 @@ 2011-06-03 Paul Eggert + Check for overflow when converting integer to cons and back. + * charset.c (Fdefine_charset_internal, Fdecode_char): + Use cons_to_unsigned to catch overflow. + (Fencode_char): Use INTEGER_TO_CONS. + * composite.h (LGLYPH_CODE): Use cons_to_unsigned. + (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. + * data.c (long_to_cons, cons_to_long): Remove. + (cons_to_unsigned, cons_to_signed): New functions. + These signal an error for invalid or out-of-range values. + * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. + * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. + * font.c (Ffont_variation_glyphs): + * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. + * lisp.h (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. + (cons_to_signed, cons_to_unsigned): New decls. + (long_to_cons, cons_to_long): Remove decls. + * undo.c (record_first_change): Use INTEGER_TO_CONS. + (Fprimitive_undo): Use CONS_TO_INTEGER. + * xfns.c (Fx_window_property): Likewise. + * xselect.c (x_own_selection, selection_data_to_lisp_data): + Use INTEGER_TO_CONS. + (x_handle_selection_request, x_handle_selection_clear) + (x_get_foreign_selection, Fx_disown_selection_internal) + (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. + (lisp_data_to_selection_data): Use cons_to_unsigned. + (x_fill_property_data): Use cons_to_signed. Report values out of range. + Fix doc for machines with wider system times such as time_t. On such machines, it's now safe to assume that EMACS_INT is as wide as the system times, so that shifting right by 16 will === modified file 'src/charset.c' --- src/charset.c 2011-06-03 18:11:17 +0000 +++ src/charset.c 2011-06-03 19:02:25 +0000 @@ -932,17 +932,8 @@ val = args[charset_arg_min_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -954,17 +945,8 @@ val = args[charset_arg_max_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -1865,17 +1847,7 @@ struct charset *charsetp; CHECK_CHARSET_GET_ID (charset, id); - if (CONSP (code_point)) - { - CHECK_NATNUM_CAR (code_point); - CHECK_NATNUM_CDR (code_point); - code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); - } - else - { - CHECK_NATNUM (code_point); - code = XINT (code_point); - } + code = cons_to_unsigned (code_point, UINT_MAX); charsetp = CHARSET_FROM_ID (id); c = DECODE_CHAR (charsetp, code); return (c >= 0 ? make_number (c) : Qnil); @@ -1900,9 +1872,7 @@ code = ENCODE_CHAR (charsetp, XINT (ch)); if (code == CHARSET_INVALID_CODE (charsetp)) return Qnil; - if (code > 0x7FFFFFF) - return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); - return make_number (code); + return INTEGER_TO_CONS (code); } === modified file 'src/composite.h' --- src/composite.h 2011-05-31 06:05:00 +0000 +++ src/composite.h 2011-06-03 19:02:25 +0000 @@ -265,10 +265,7 @@ #define LGLYPH_CODE(g) \ (NILP (AREF ((g), LGLYPH_IX_CODE)) \ ? FONT_INVALID_CODE \ - : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ - ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ - | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ - : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) + : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) @@ -280,15 +277,8 @@ #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) /* Callers must assure that VAL is not negative! */ #define LGLYPH_SET_CODE(g, val) \ - do { \ - if (val == FONT_INVALID_CODE) \ - ASET ((g), LGLYPH_IX_CODE, Qnil); \ - else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ - ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ - make_number ((val) & 0xFFFF))); \ - else \ - ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ - } while (0) + ASET (g, LGLYPH_IX_CODE, \ + val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) === modified file 'src/data.c' --- src/data.c 2011-06-02 06:17:35 +0000 +++ src/data.c 2011-06-03 19:02:25 +0000 @@ -2324,33 +2324,89 @@ return Qnil; } -/* Convert between long values and pairs of Lisp integers. - Note that long_to_cons returns a single Lisp integer - when the value fits in one. */ +/* Convert the cons-of-integers, integer, or float value C to an + unsigned value with maximum value MAX. Signal an error if C does not + have a valid format or is out of range. */ +uintmax_t +cons_to_unsigned (Lisp_Object c, uintmax_t max) +{ + int valid = 0; + uintmax_t val IF_LINT (= 0); + if (INTEGERP (c)) + { + valid = 0 <= XINT (c); + val = XINT (c); + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (0 <= d + && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (NATNUMP (top) && XFASTINT (top) <= UINTMAX_MAX >> 16 && NATNUMP (bot)) + { + uintmax_t utop = XFASTINT (top); + val = (utop << 16) | XFASTINT (bot); + valid = 1; + } + } -Lisp_Object -long_to_cons (long unsigned int i) -{ - unsigned long top = i >> 16; - unsigned int bot = i & 0xFFFF; - if (top == 0) - return make_number (bot); - if (top == (unsigned long)-1 >> 16) - return Fcons (make_number (-1), make_number (bot)); - return Fcons (make_number (top), make_number (bot)); + if (! (valid && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } -unsigned long -cons_to_long (Lisp_Object c) +/* Convert the cons-of-integers, integer, or float value C to a signed + value with extrema MIN and MAX. Signal an error if C does not have + a valid format or is out of range. */ +intmax_t +cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { - Lisp_Object top, bot; + int valid = 0; + intmax_t val IF_LINT (= 0); if (INTEGERP (c)) - return XINT (c); - top = XCAR (c); - bot = XCDR (c); - if (CONSP (bot)) - bot = XCAR (bot); - return ((XINT (top) << 16) | XINT (bot)); + { + val = XINT (c); + valid = 1; + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (min <= d + && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c)) + { + Lisp_Object top = XCAR (c); + Lisp_Object bot = XCDR (c); + if (CONSP (bot)) + bot = XCAR (bot); + if (INTEGERP (top) && INTMAX_MIN >> 16 <= XINT (top) + && XINT (top) <= INTMAX_MAX >> 16 && INTEGERP (bot)) + { + intmax_t itop = XINT (top); + val = (itop << 16) | XINT (bot); + valid = 1; + } + } + + if (! (valid && min <= val && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, === modified file 'src/dired.c' --- src/dired.c 2011-06-03 18:42:59 +0000 +++ src/dired.c 2011-06-03 19:02:25 +0000 @@ -900,12 +900,9 @@ This is a floating point number if the size is too large for an integer. 8. File modes, as a string of ten letters or dashes as in ls -l. 9. t if file's gid would change if file were deleted and recreated. -10. inode number. If inode number is larger than what Emacs integer - can hold, but all but the bottom 16 bits still fits, this is a cons cell - containing two integers: first the high part, then the low 16 bits. - If the inode number is still wider, this is of the form - (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, - and finally the low 16 bits. +10. inode number. If it is larger than what the Emacs integer + can hold, this is a cons cell containing two integers: first the + high part, then the low 16 bits. 11. Filesystem device number. If it is larger than what the Emacs integer can hold, this is a cons cell, similar to the inode number. @@ -998,34 +995,8 @@ #else /* file gid will be egid */ values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; #endif /* not BSD4_2 */ - if (!FIXNUM_OVERFLOW_P (s.st_ino)) - /* Keep the most common cases as integers. */ - values[10] = make_number (s.st_ino); - else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) - /* To allow inode numbers larger than VALBITS, separate the bottom - 16 bits. */ - values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), - make_number ((EMACS_INT)(s.st_ino & 0xffff))); - else - { - /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, - separate into 2 24-bit high parts and a 16-bit bottom part. - The code on the next line avoids a compiler warning on - systems where st_ino is 32 bit wide. (bug#766). */ - EMACS_INT high_ino = s.st_ino >> 31 >> 1; - - values[10] = Fcons (make_number (high_ino >> 8), - Fcons (make_number (((high_ino & 0xff) << 16) - + (s.st_ino >> 16 & 0xffff)), - make_number (s.st_ino & 0xffff))); - } - - /* Likewise for device. */ - if (FIXNUM_OVERFLOW_P (s.st_dev)) - values[11] = Fcons (make_number (s.st_dev >> 16), - make_number (s.st_dev & 0xffff)); - else - values[11] = make_number (s.st_dev); + values[10] = INTEGER_TO_CONS (s.st_ino); + values[11] = INTEGER_TO_CONS (s.st_dev); return Flist (sizeof(values) / sizeof(values[0]), values); } === modified file 'src/fileio.c' --- src/fileio.c 2011-06-02 06:23:20 +0000 +++ src/fileio.c 2011-06-03 19:02:25 +0000 @@ -5005,7 +5005,7 @@ { if (!NILP (time_list)) { - current_buffer->modtime = cons_to_long (time_list); + CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); current_buffer->modtime_size = -1; } else === modified file 'src/font.c' --- src/font.c 2011-05-29 19:04:01 +0000 +++ src/font.c 2011-06-03 19:02:25 +0000 @@ -4388,16 +4388,8 @@ for (i = 0; i < 255; i++) if (variations[i]) { - Lisp_Object code; int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); - /* Stops GCC whining about limited range of data type. */ - EMACS_INT var = variations[i]; - - if (var > MOST_POSITIVE_FIXNUM) - code = Fcons (make_number ((variations[i]) >> 16), - make_number ((variations[i]) & 0xFFFF)); - else - code = make_number (variations[i]); + Lisp_Object code = INTEGER_TO_CONS (variations[i]); val = Fcons (Fcons (make_number (vs), code), val); } return val; === modified file 'src/fontset.c' --- src/fontset.c 2011-05-28 22:39:39 +0000 +++ src/fontset.c 2011-06-03 19:02:25 +0000 @@ -1859,17 +1859,11 @@ { unsigned code = face->font->driver->encode_char (face->font, c); Lisp_Object font_object; - /* Assignment to EMACS_INT stops GCC whining about limited range - of data type. */ - EMACS_INT cod = code; if (code == FONT_INVALID_CODE) return Qnil; XSETFONT (font_object, face->font); - if (cod <= MOST_POSITIVE_FIXNUM) - return Fcons (font_object, make_number (code)); - return Fcons (font_object, Fcons (make_number (code >> 16), - make_number (code & 0xFFFF))); + return Fcons (font_object, INTEGER_TO_CONS (code)); } return Qnil; } === modified file 'src/lisp.h' --- src/lisp.h 2011-06-03 18:28:20 +0000 +++ src/lisp.h 2011-06-03 19:02:25 +0000 @@ -2405,9 +2405,33 @@ EXFUN (Fsub1, 1); EXFUN (Fmake_variable_buffer_local, 1); +/* Convert the integer I to an Emacs representation, either the integer + itself, or a cons of two integers, or if all else fails a float. + The float might lose information; this happens only in extreme cases + such as 32-bit EMACS_INT and 64-bit time_t with outlandish time values, + and these aren't worth complicating the interface. + + I should not have side effects. */ +#define INTEGER_TO_CONS(i) \ + (! FIXNUM_OVERFLOW_P (i) \ + ? make_number (i) \ + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ + && FIXNUM_OVERFLOW_P ((i) >> 16)) \ + ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ + : make_float (i)) + +/* Convert the Emacs representation CONS back to an integer of type + TYPE, storing the result the variable VAR. Signal an error if CONS + is not a valid representation or is out of range for TYPE. */ +#define CONS_TO_INTEGER(cons, type, var) \ + (TYPE_SIGNED (type) \ + ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ + : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) +extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); +extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); + extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); -extern Lisp_Object long_to_cons (unsigned long); -extern unsigned long cons_to_long (Lisp_Object); extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; === modified file 'src/undo.c' --- src/undo.c 2011-06-02 06:15:15 +0000 +++ src/undo.c 2011-06-03 19:02:25 +0000 @@ -212,7 +212,6 @@ void record_first_change (void) { - Lisp_Object high, low; struct buffer *base_buffer = current_buffer; if (EQ (BVAR (current_buffer, undo_list), Qt)) @@ -225,9 +224,9 @@ if (base_buffer->base_buffer) base_buffer = base_buffer->base_buffer; - XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); - XSETFASTINT (low, base_buffer->modtime & 0xffff); - BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); + BVAR (current_buffer, undo_list) = + Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), + BVAR (current_buffer, undo_list)); } /* Record a change in property PROP (whose old value was VAL) @@ -499,13 +498,9 @@ if (EQ (car, Qt)) { /* Element (t high . low) records previous modtime. */ - Lisp_Object high, low; + struct buffer *base_buffer = current_buffer; time_t mod_time; - struct buffer *base_buffer = current_buffer; - - high = Fcar (cdr); - low = Fcdr (cdr); - mod_time = (XFASTINT (high) << 16) + XFASTINT (low); + CONS_TO_INTEGER (cdr, time_t, mod_time); if (current_buffer->base_buffer) base_buffer = current_buffer->base_buffer; === modified file 'src/xfns.c' --- src/xfns.c 2011-04-19 06:34:43 +0000 +++ src/xfns.c 2011-06-03 19:02:25 +0000 @@ -4295,18 +4295,9 @@ if (! NILP (source)) { - if (NUMBERP (source)) - { - if (FLOATP (source)) - target_window = (Window) XFLOAT (source); - else - target_window = XFASTINT (source); - - if (target_window == 0) - target_window = FRAME_X_DISPLAY_INFO (f)->root_window; - } - else if (CONSP (source)) - target_window = cons_to_long (source); + CONS_TO_INTEGER (source, Window, target_window); + if (! target_window) + target_window = FRAME_X_DISPLAY_INFO (f)->root_window; } BLOCK_INPUT; === modified file 'src/xselect.c' --- src/xselect.c 2011-06-03 18:22:12 +0000 +++ src/xselect.c 2011-06-03 19:02:25 +0000 @@ -335,7 +335,7 @@ Lisp_Object prev_value; selection_data = list4 (selection_name, selection_value, - long_to_cons (timestamp), frame); + INTEGER_TO_CONS (timestamp), frame); prev_value = LOCAL_SELECTION (selection_name, dpyinfo); dpyinfo->terminal->Vselection_alist @@ -419,7 +419,7 @@ || INTEGERP (check) || NILP (value)) return value; - /* Check for a value that cons_to_long could handle. */ + /* Check for a value that CONS_TO_INTEGER could handle. */ else if (CONSP (check) && INTEGERP (XCAR (check)) && (INTEGERP (XCDR (check)) @@ -782,8 +782,8 @@ if (NILP (local_selection_data)) goto DONE; /* Decline requests issued prior to our acquiring the selection. */ - local_selection_time - = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); if (SELECTION_EVENT_TIME (event) != CurrentTime && local_selection_time > SELECTION_EVENT_TIME (event)) goto DONE; @@ -950,8 +950,8 @@ /* Well, we already believe that we don't own it, so that's just fine. */ if (NILP (local_selection_data)) return; - local_selection_time = (Time) - cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); /* We have reasserted the selection since this SelectionClear was generated, so we can disregard it. */ @@ -1213,16 +1213,7 @@ return Qnil; if (! NILP (time_stamp)) - { - if (CONSP (time_stamp)) - requestor_time = (Time) cons_to_long (time_stamp); - else if (INTEGERP (time_stamp)) - requestor_time = (Time) XUINT (time_stamp); - else if (FLOATP (time_stamp)) - requestor_time = (Time) XFLOAT_DATA (time_stamp); - else - error ("TIME_STAMP must be cons or number"); - } + CONS_TO_INTEGER (time_stamp, Time, requestor_time); BLOCK_INPUT; @@ -1652,7 +1643,7 @@ convert it to a cons of integers, 16 bits in each half. */ else if (format == 32 && size == sizeof (unsigned int)) - return long_to_cons (((unsigned int *) data) [0]); + return INTEGER_TO_CONS (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (unsigned short)) return make_number ((int) (((unsigned short *) data) [0])); @@ -1678,7 +1669,7 @@ for (i = 0; i < size / 4; i++) { unsigned int j = ((unsigned int *) data) [i]; - Faset (v, make_number (i), long_to_cons (j)); + Faset (v, make_number (i), INTEGER_TO_CONS (j)); } return v; } @@ -1755,7 +1746,7 @@ *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); (*data_ret) [sizeof (unsigned long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_long (obj); + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1803,11 +1794,11 @@ *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); for (i = 0; i < *size_ret; i++) if (*format_ret == 32) - (*((unsigned long **) data_ret)) [i] - = cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned long **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); else - (*((unsigned short **) data_ret)) [i] - = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned short **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); } } else @@ -2025,8 +2016,10 @@ selection_atom = symbol_to_x_atom (dpyinfo, selection); BLOCK_INPUT; - timestamp = (NILP (time_object) ? last_event_timestamp - : cons_to_long (time_object)); + if (NILP (time_object)) + timestamp = last_event_timestamp; + else + CONS_TO_INTEGER (time_object, Time, timestamp); XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); UNBLOCK_INPUT; @@ -2232,12 +2225,8 @@ { Lisp_Object o = XCAR (iter); - if (INTEGERP (o)) - val = (long) XFASTINT (o); - else if (FLOATP (o)) - val = (long) XFLOAT_DATA (o); - else if (CONSP (o)) - val = (long) cons_to_long (o); + if (INTEGERP (o) || FLOATP (o) || CONSP (o)) + val = cons_to_signed (o, LONG_MIN, LONG_MAX); else if (STRINGP (o)) { BLOCK_INPUT; @@ -2248,9 +2237,19 @@ error ("Wrong type, must be string, number or cons"); if (format == 8) - *d08++ = (char) val; + { + if (CHAR_MIN <= val && val <= CHAR_MAX) + *d08++ = val; + else + error ("Out of 'char' range"); + } else if (format == 16) - *d16++ = (short) val; + { + if (SHRT_MIN <= val && val <= SHRT_MAX) + *d16++ = val; + else + error ("Out of 'short' range"); + } else *d32++ = val; } @@ -2334,14 +2333,7 @@ Atom atom; int had_errors; - if (INTEGERP (value)) - atom = (Atom) XUINT (value); - else if (FLOATP (value)) - atom = (Atom) XFLOAT_DATA (value); - else if (CONSP (value)) - atom = (Atom) cons_to_long (value); - else - error ("Wrong type, value must be number or cons"); + CONS_TO_INTEGER (value, Atom, atom); BLOCK_INPUT; x_catch_errors (dpy); @@ -2531,17 +2523,8 @@ else error ("DEST as a string must be one of PointerWindow or InputFocus"); } - else if (INTEGERP (dest)) - wdest = (Window) XFASTINT (dest); - else if (FLOATP (dest)) - wdest = (Window) XFLOAT_DATA (dest); - else if (CONSP (dest)) - { - if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) - error ("Both car and cdr for DEST must be numbers"); - else - wdest = (Window) cons_to_long (dest); - } + else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) + CONS_TO_INTEGER (dest, Window, wdest); else error ("DEST must be a frame, nil, string, number or cons"); From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 15:43:52 2011 Received: (at 8794) by debbugs.gnu.org; 3 Jun 2011 19:43:52 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSaHg-0003I2-5O for submit@debbugs.gnu.org; Fri, 03 Jun 2011 15:43:52 -0400 Received: from mtaout20.012.net.il ([80.179.55.166]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QSaHd-0003Hq-MU for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 15:43:51 -0400 Received: from conversion-daemon.a-mtaout20.012.net.il by a-mtaout20.012.net.il (HyperSendmail v2007.08) id <0LM800E00BH6Q000@a-mtaout20.012.net.il> for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 22:43:43 +0300 (IDT) Received: from HOME-C4E4A596F7 ([84.229.223.140]) by a-mtaout20.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0LM800E3NC4UOV40@a-mtaout20.012.net.il>; Fri, 03 Jun 2011 22:43:43 +0300 (IDT) Date: Fri, 03 Jun 2011 22:43:55 +0300 From: Eli Zaretskii Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default In-reply-to: <4DE91FB3.80601@cs.ucla.edu> X-012-Sender: halo1@inter.net.il To: Paul Eggert Message-id: <83hb86em4k.fsf@gnu.org> References: <4DE89EB8.9020202@cs.ucla.edu> <83oc2fdw59.fsf@gnu.org> <4DE91FB3.80601@cs.ucla.edu> X-Spam-Score: -2.0 (--) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: Eli Zaretskii List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.0 (--) > Date: Fri, 03 Jun 2011 10:53:55 -0700 > From: Paul Eggert > CC: 8794@debbugs.gnu.org > > int > main (void) > { > int big = 536870913; > int *p = malloc (big * sizeof *p); > if (!p) > return 1; > memset (p, 0xef, big * sizeof *p); > printf ("%x %x\n", p[0], p[big - 1]); > return 0; > } > > On my RHEL 5.6 host, built as a 32-bit executable, this outputs: > > $ gcc -m32 t.c > $ ./a.out > efefefef efefefef How does this work on the machine code level? Doesn't the code need to load a pointer to p into a 32-bit register, in order to reference the array? On Windows, I see that the GCC-produced code does this: movl $0x20000001,0xfffffffc(%ebp) ... mov 0xfffffffc(%ebp),%eax shl $0x2,%eax and then uses EAX to reference the array elements. That last left shift by 2 bits will surely overflow for values of `big' that are larger that 0x3fffffff (not 0x20000001, the value you used). So maybe 2GB is not the limit, but 4GB surely is. You promise much more. > Perhaps you're thinking of pointer subtraction? That often stops working on > arrays larger than 2 GiB. But this is easy to program around. Well, then we need to program around that, _before_ we promise buffers larger than 2GB on 32-bit hosts. E.g., look how we address characters in buffers: /* Address of beginning of buffer. */ #define BUF_BEG_ADDR(buf) ((buf)->text->beg) /* Return character code of multi-byte form at byte position POS in BUF. If POS doesn't point the head of valid multi-byte form, only the byte at POS is returned. No range checking. */ #define BUF_FETCH_MULTIBYTE_CHAR(buf, pos) \ (_fetch_multibyte_char_p \ = (((pos) >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0) \ + (pos) + BUF_BEG_ADDR (buf) - BEG_BYTE), \ STRING_CHAR (_fetch_multibyte_char_p)) The pointer arithmetics will wrap around on 32-bit hosts here, because a pointer is loaded into a 32-bit register before it's dereferenced. Am I missing something? > And anyway, even if we assume buffers and strings are all smaller > than 2 GiB, an EMACS_INT wider than 32 bits is still needed for > large buffers and strings, due to the tag bits. I wasn't saying a 64-bit EMACS_INT wasn't an advantage. It is. But I very much doubt that we could have buffers and strings larger than 4GB on 32-bit hosts. Your changes to the docs seem to promise much larger buffers, which I don't think is feasible. > > The *_MAX macros need limits.h, but I don't see it being included by > > data.c. Did I miss something? > > Those are OK because lisp.h includes inttypes.h. INTMAX_MAX and > UINTMAX_MAX are defined by inttypes.h (actually, stdint.h, but > inttypes.h includes stdint.h). What about ULONG_MAX in this patch to xselect.c: > - *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); > - (*data_ret) [sizeof (long)] = 0; > - (*(unsigned long **) data_ret) [0] = cons_to_long (obj); > + *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); > + (*data_ret) [sizeof (unsigned long)] = 0; > + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); ? There are also USHRT_MAX, LONG_MAX, CHAR_MAX, and SHRT_MAX there, but I see no limits.h being included. How did that compile for you? From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 03 23:05:19 2011 Received: (at 8794) by debbugs.gnu.org; 4 Jun 2011 03:05:19 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QShAt-0004t5-03 for submit@debbugs.gnu.org; Fri, 03 Jun 2011 23:05:19 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QShAp-0004st-V5 for 8794@debbugs.gnu.org; Fri, 03 Jun 2011 23:05:17 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 38A3C39E80FF; Fri, 3 Jun 2011 20:05:10 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8-ulA0Xmndm8; Fri, 3 Jun 2011 20:05:08 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 5EF8639E80F0; Fri, 3 Jun 2011 20:05:08 -0700 (PDT) Message-ID: <4DE9A0DF.2030801@cs.ucla.edu> Date: Fri, 03 Jun 2011 20:05:03 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: Eli Zaretskii Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default References: <4DE89EB8.9020202@cs.ucla.edu> <83oc2fdw59.fsf@gnu.org> <4DE91FB3.80601@cs.ucla.edu> <83hb86em4k.fsf@gnu.org> In-Reply-To: <83hb86em4k.fsf@gnu.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) On 06/03/11 12:43, Eli Zaretskii wrote: > maybe 2GB is not the limit, but 4GB surely is. Yes, that's right. A host with 32-bit addresses can address at most 4 GiB. >> Perhaps you're thinking of pointer subtraction? That often stops working on >> arrays larger than 2 GiB. But this is easy to program around. > > Well, then we need to program around that, _before_ we promise buffers > larger than 2GB on 32-bit hosts. OK, good point. Rather than embark on that further fix, let's just get this one done. The further patches below fix the documentation so that it talks about the 2 GiB limit on typical 32-bit hosts, and fix the code to enforce this limit. > What about ULONG_MAX in this patch to xselect.c: > ... > ? There are also USHRT_MAX, LONG_MAX, CHAR_MAX, and SHRT_MAX there, > but I see no limits.h being included. How did that compile for you? Thanks for catching that. It worked for me because my platform needed a replacement inttypes.h, which in turn included limits.h. More up-to-date platforms would use the system inttypes.h, which wouldn't do that. The patches below fix that too. One more patch (also below) catches a similar problem with 32-bit integer overflow that I noticed in image.c while I was fixing the other problems. It has no dependencies on the other patches. Thanks for the review. :::::::::::::: diff1 :::::::::::::: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-03 19:02:25 +0000 +++ src/ChangeLog 2011-06-03 20:14:12 +0000 @@ -19,7 +19,8 @@ * undo.c (record_first_change): Use INTEGER_TO_CONS. (Fprimitive_undo): Use CONS_TO_INTEGER. * xfns.c (Fx_window_property): Likewise. - * xselect.c (x_own_selection, selection_data_to_lisp_data): + * xselect.c: Include . + (x_own_selection, selection_data_to_lisp_data): Use INTEGER_TO_CONS. (x_handle_selection_request, x_handle_selection_clear) (x_get_foreign_selection, Fx_disown_selection_internal) === modified file 'src/xselect.c' --- src/xselect.c 2011-06-03 19:02:25 +0000 +++ src/xselect.c 2011-06-03 20:14:12 +0000 @@ -20,6 +20,7 @@ /* Rewritten by jwz */ #include +#include #include /* termhooks.h needs this */ #include :::::::::::::: diff2 :::::::::::::: === modified file 'doc/emacs/buffers.texi' --- doc/emacs/buffers.texi 2011-06-03 18:47:14 +0000 +++ doc/emacs/buffers.texi 2011-06-03 23:21:13 +0000 @@ -43,8 +43,9 @@ A buffer's size cannot be larger than some maximum, which is defined by the largest buffer position representable by the @dfn{Emacs integer} data type. This is because Emacs tracks buffer positions -using that data type. For most machines, the maximum buffer size +using that data type. For 64-bit machines, the maximum buffer size enforced by the data types is @math{2^61 - 2} bytes, or about 2 EiB. +For most 32-bit machines, the maximum is @math{2^31 - 1} bytes, or about 2 GiB. For some older machines, the maximum is @math{2^29 - 2} bytes, or about 512 MiB. Buffer sizes are also limited by the size of Emacs's virtual memory. :::::::::::::: diff3 :::::::::::::: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-03 20:14:12 +0000 +++ src/ChangeLog 2011-06-04 02:02:36 +0000 @@ -1,3 +1,11 @@ +2011-06-04 Paul Eggert + + Use ptrdiff_t, not int, for sizes. + * image.c (slurp_file): Switch from int to ptrdiff_t. + All uses changed. + (slurp_file, svg_load): Check that file size fits in both + size_t (for malloc) and ptrdiff_t (for sanity and safety). + 2011-06-03 Paul Eggert Check for overflow when converting integer to cons and back. === modified file 'src/image.c' --- src/image.c 2011-05-31 06:05:00 +0000 +++ src/image.c 2011-06-04 02:02:36 +0000 @@ -2112,9 +2112,6 @@ File Handling ***********************************************************************/ -static unsigned char *slurp_file (char *, int *); - - /* Find image file FILE. Look in data-directory/images, then x-bitmap-file-path. Value is the encoded full name of the file found, or nil if not found. */ @@ -2151,7 +2148,7 @@ occurred. *SIZE is set to the size of the file. */ static unsigned char * -slurp_file (char *file, int *size) +slurp_file (char *file, ptrdiff_t *size) { FILE *fp = NULL; unsigned char *buf = NULL; @@ -2159,6 +2156,7 @@ if (stat (file, &st) == 0 && (fp = fopen (file, "rb")) != NULL + && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) && (buf = (unsigned char *) xmalloc (st.st_size), fread (buf, 1, st.st_size, fp) == st.st_size)) { @@ -2814,7 +2812,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -4039,7 +4037,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -5021,6 +5019,7 @@ if (stat (SDATA (file), &st) == 0 && (fp = fopen (SDATA (file), "rb")) != NULL + && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) && (buf = (char *) xmalloc (st.st_size), fread (buf, 1, st.st_size, fp) == st.st_size)) { @@ -5055,7 +5054,7 @@ enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; unsigned char *contents = NULL; unsigned char *end, *p; - int size; + ptrdiff_t size; specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -7869,7 +7868,7 @@ static int svg_load (struct frame *f, struct image *img); static int svg_load_image (struct frame *, struct image *, - unsigned char *, unsigned int); + unsigned char *, ptrdiff_t); /* The symbol `svg' identifying images of this type. */ @@ -8047,7 +8046,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -8074,7 +8073,7 @@ Lisp_Object data; data = image_spec_value (img->spec, QCdata, NULL); - if (!STRINGP (data)) + if (! (STRINGP (data) && SBYTES (data) <= min (PTRDIFF_MAX, SIZE_MAX))) { image_error ("Invalid image data `%s'", data, Qnil); return 0; @@ -8096,7 +8095,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ struct image *img, /* Pointer to emacs image structure. */ unsigned char *contents, /* String containing the SVG XML data to be parsed. */ - unsigned int size) /* Size of data in bytes. */ + ptrdiff_t size) /* Size of data in bytes. */ { RsvgHandle *rsvg_handle; RsvgDimensionData dimension_data; :::::::::::::: diff4 :::::::::::::: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-04 02:02:36 +0000 +++ src/ChangeLog 2011-06-04 02:49:51 +0000 @@ -1,5 +1,20 @@ 2011-06-04 Paul Eggert + Check for buffer and string overflow more precisely. + * buffer.h (BUF_BYTES_MAX): New macro. + * lisp.h (STRING_BYTES_MAX): New macro. + * alloc.c (Fmake_string): + * character.c (string_escape_byte8): + * coding.c (coding_alloc_by_realloc): + * doprnt.c (doprnt): + * editfns.c (Fformat): + * eval.c (verror): + Use STRING_BYTES_MAX, not MOST_POSITIVE_FIXNUM, + since they may not be the same number. + * editfns.c (Finsert_char): + * fileio.c (Finsert_file_contents): + Likewise for BUF_BYTES_MAX. + Use ptrdiff_t, not int, for sizes. * image.c (slurp_file): Switch from int to ptrdiff_t. All uses changed. === modified file 'src/alloc.c' --- src/alloc.c 2011-06-02 08:35:28 +0000 +++ src/alloc.c 2011-06-04 02:49:51 +0000 @@ -2205,7 +2205,7 @@ int len = CHAR_STRING (c, str); EMACS_INT string_len = XINT (length); - if (string_len > MOST_POSITIVE_FIXNUM / len) + if (string_len > STRING_BYTES_MAX / len) string_overflow (); nbytes = len * string_len; val = make_uninit_multibyte_string (string_len, nbytes); === modified file 'src/buffer.h' --- src/buffer.h 2011-06-02 06:15:15 +0000 +++ src/buffer.h 2011-06-04 02:49:51 +0000 @@ -306,6 +306,11 @@ } \ while (0) +/* Maximum number of bytes in a buffer. + A buffer cannot contain more bytes than a 1-origin fixnum can represent, + nor can it be so large that C pointer arithmetic stops working. */ +#define BUF_BYTES_MAX min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX)) + /* Return the address of byte position N in current buffer. */ #define BYTE_POS_ADDR(n) \ === modified file 'src/character.c' --- src/character.c 2011-06-02 06:17:35 +0000 +++ src/character.c 2011-06-04 02:49:51 +0000 @@ -838,7 +838,7 @@ if (multibyte) { if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count - || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count) + || (STRING_BYTES_MAX - nbytes) / 2 < byte8_count) string_overflow (); /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ @@ -847,7 +847,7 @@ } else { - if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count) + if ((STRING_BYTES_MAX - nchars) / 3 < byte8_count) string_overflow (); /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ === modified file 'src/coding.c' --- src/coding.c 2011-05-30 01:12:12 +0000 +++ src/coding.c 2011-06-04 02:49:51 +0000 @@ -1071,8 +1071,8 @@ static void coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes) { - if (coding->dst_bytes >= MOST_POSITIVE_FIXNUM - bytes) - error ("Maximum size of buffer or string exceeded"); + if (STRING_BYTES_MAX - coding->dst_bytes < bytes) + string_overflow (); coding->destination = (unsigned char *) xrealloc (coding->destination, coding->dst_bytes + bytes); coding->dst_bytes += bytes; === modified file 'src/doprnt.c' --- src/doprnt.c 2011-04-30 20:05:43 +0000 +++ src/doprnt.c 2011-06-04 02:49:51 +0000 @@ -329,7 +329,7 @@ minlen = atoi (&fmtcpy[1]); string = va_arg (ap, char *); tem = strlen (string); - if (tem > MOST_POSITIVE_FIXNUM) + if (tem > STRING_BYTES_MAX) error ("String for %%s or %%S format is too long"); width = strwidth (string, tem); goto doit1; @@ -338,7 +338,7 @@ doit: /* Coming here means STRING contains ASCII only. */ tem = strlen (string); - if (tem > MOST_POSITIVE_FIXNUM) + if (tem > STRING_BYTES_MAX) error ("Format width or precision too large"); width = tem; doit1: === modified file 'src/editfns.c' --- src/editfns.c 2011-06-03 18:14:49 +0000 +++ src/editfns.c 2011-06-04 02:49:51 +0000 @@ -2341,7 +2341,7 @@ len = CHAR_STRING (XFASTINT (character), str); else str[0] = XFASTINT (character), len = 1; - if (MOST_POSITIVE_FIXNUM / len < XINT (count)) + if (BUF_BYTES_MAX / len < XINT (count)) error ("Maximum buffer size would be exceeded"); n = XINT (count) * len; if (n <= 0) @@ -3588,7 +3588,7 @@ char initial_buffer[4000]; char *buf = initial_buffer; EMACS_INT bufsize = sizeof initial_buffer; - EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); + EMACS_INT max_bufsize = STRING_BYTES_MAX + 1; char *p; Lisp_Object buf_save_value IF_LINT (= {0}); register char *format, *end, *format_start; === modified file 'src/eval.c' --- src/eval.c 2011-05-30 05:39:59 +0000 +++ src/eval.c 2011-06-04 02:49:51 +0000 @@ -1994,7 +1994,7 @@ { char buf[4000]; size_t size = sizeof buf; - size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); + size_t size_max = STRING_BYTES_MAX + 1; size_t mlen = strlen (m); char *buffer = buf; size_t used; === modified file 'src/fileio.c' --- src/fileio.c 2011-06-03 19:02:25 +0000 +++ src/fileio.c 2011-06-04 02:49:51 +0000 @@ -3248,7 +3248,7 @@ /* Check whether the size is too large or negative, which can happen on a platform that allows file sizes greater than the maximum off_t value. */ if (! not_regular - && ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM)) + && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX)) error ("Maximum buffer size exceeded"); /* Prevent redisplay optimizations. */ === modified file 'src/lisp.h' --- src/lisp.h 2011-06-03 19:02:25 +0000 +++ src/lisp.h 2011-06-04 02:49:51 +0000 @@ -766,6 +766,12 @@ #endif /* not GC_CHECK_STRING_BYTES */ +/* A string cannot contain more bytes than a fixnum can represent, + nor can it be so long that C pointer arithmetic stops working on + the string plus a terminating null. */ +#define STRING_BYTES_MAX \ + min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1) + /* Mark STR as a unibyte string. */ #define STRING_SET_UNIBYTE(STR) \ do { if (EQ (STR, empty_multibyte_string)) \ From debbugs-submit-bounces@debbugs.gnu.org Sun Jun 05 08:00:18 2011 Received: (at 8794) by debbugs.gnu.org; 5 Jun 2011 12:00:18 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTC09-0003OL-W3 for submit@debbugs.gnu.org; Sun, 05 Jun 2011 08:00:18 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTC08-0003Nu-D6 for 8794@debbugs.gnu.org; Sun, 05 Jun 2011 08:00:17 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:51336 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QTC01-0008Fl-Gm; Sun, 05 Jun 2011 08:00:10 -0400 Received: by ceviche.home (Postfix, from userid 20848) id 5340E66349; Sun, 5 Jun 2011 09:00:05 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> Date: Sun, 05 Jun 2011 09:00:05 -0300 In-Reply-To: <4DE935F6.2080802@cs.ucla.edu> (Paul Eggert's message of "Fri, 03 Jun 2011 12:28:54 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) > (a) straightforward fixes that I assume are uncontroversial > (b) make 64bit-on-32bit the default (on 32bit systems that support it) > (c) fix the cons<->int conversions > Each part is a prerequisite for the next. That's a problem for (c) because I don't want to install (b) for now. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 04:39:20 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 08:39:20 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVL8-00081f-Oj for submit@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:20 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVL4-00081Q-Tr for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:11 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 99CFA39E80FA; Mon, 6 Jun 2011 01:39:04 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r9bu8e4POXHU; Mon, 6 Jun 2011 01:39:04 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 11E6739E80F0; Mon, 6 Jun 2011 01:39:04 -0700 (PDT) Message-ID: <4DEC9227.5060000@cs.ucla.edu> Date: Mon, 06 Jun 2011 01:39:03 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) On 06/05/11 05:00, Stefan Monnier wrote: >> (a) straightforward fixes that I assume are uncontroversial >> (b) make 64bit-on-32bit the default (on 32bit systems that support it) >> (c) fix the cons<->int conversions > >> Each part is a prerequisite for the next. > > That's a problem for (c) because I don't want to install (b) for now. OK, I have revamped (c) so that it does two conses for large integers on 32-bit hosts; this removes its dependency on (b). I'll send the revised (c) in a followup email. The uncontroversial changes (a) have some changes too, based on later discussion with Eli, so I'll send a revised (a) too. What else needs to be done before it's reasonable to install something like (b)? From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 04:39:27 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 08:39:27 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVLK-000823-BA for submit@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:27 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVLG-00081i-3B for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:24 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id A443439E80FA; Mon, 6 Jun 2011 01:39:16 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DeP-mbkEnMAN; Mon, 6 Jun 2011 01:39:14 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 50D7139E80F0; Mon, 6 Jun 2011 01:39:14 -0700 (PDT) Message-ID: <4DEC9232.6040200@cs.ucla.edu> Date: Mon, 06 Jun 2011 01:39:14 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (a) uncontroversial fixes (2011-06-06 version) References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: eggert@cs.ucla.edu-20110606061612-wzv4dvdtnh828yk3 # target_branch: bzr+ssh://eggert@bzr.savannah.gnu.org/emacs/trunk # testament_sha1: c8b36cc2ea7b3f5a15360443ec4a0832655a629c # timestamp: 2011-06-06 01:28:12 -0700 # base_revision_id: eggert@cs.ucla.edu-20110606045423-zu70kvdqb6987ptx # # Begin patch === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-06 04:54:23 +0000 +++ src/ChangeLog 2011-06-06 06:16:12 +0000 @@ -1,5 +1,52 @@ 2011-06-06 Paul Eggert + Check for buffer and string overflow more precisely. + * buffer.h (BUF_BYTES_MAX): New macro. + * lisp.h (STRING_BYTES_MAX): New macro. + * alloc.c (Fmake_string): + * character.c (string_escape_byte8): + * coding.c (coding_alloc_by_realloc): + * doprnt.c (doprnt): + * editfns.c (Fformat): + * eval.c (verror): + Use STRING_BYTES_MAX, not MOST_POSITIVE_FIXNUM, + since they may not be the same number. + * editfns.c (Finsert_char): + * fileio.c (Finsert_file_contents): + Likewise for BUF_BYTES_MAX. + + * image.c: Use ptrdiff_t, not int, for sizes. + (slurp_file): Switch from int to ptrdiff_t. + All uses changed. + (slurp_file): Check that file size fits in both size_t (for + malloc) and ptrdiff_t (for sanity and safety). + + * fileio.c (Fverify_visited_file_modtime): Avoid time overflow + if b->modtime has its maximal value. + + * dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits. + + Don't assume time_t can fit into int. + * buffer.h (struct buffer.modtime): Now time_t, not int. + * fileio.c (Fvisited_file_modtime): No need for time_t cast now. + * undo.c (Fprimitive_undo): Use time_t, not int, for time_t value. + + Minor fixes for signed vs unsigned integers. + * character.h (MAYBE_UNIFY_CHAR): + * charset.c (maybe_unify_char): + * keyboard.c (read_char, reorder_modifiers): + XINT -> XFASTINT, since the integer must be nonnegative. + * ftfont.c (ftfont_spec_pattern): + * keymap.c (access_keymap, silly_event_symbol_error): + XUINT -> XFASTINT, since the integer must be nonnegative. + (Fsingle_key_description, preferred_sequence_p): XUINT -> XINT, + since it makes no difference and we prefer signed. + * keyboard.c (record_char): Use XUINT when all the neighbors do. + (access_keymap): NATNUMP -> INTEGERP, since the integer must be + nonnegative. + +2011-06-06 Paul Eggert + * alloc.c (memory_full) [SYSTEM_MALLOC]: Port to MacOS (Bug#8800). Do not assume that spare memory exists; that assumption is valid only if SYSTEM_MALLOC. === modified file 'src/alloc.c' --- src/alloc.c 2011-06-06 04:54:23 +0000 +++ src/alloc.c 2011-06-06 06:16:12 +0000 @@ -2211,7 +2211,7 @@ int len = CHAR_STRING (c, str); EMACS_INT string_len = XINT (length); - if (string_len > MOST_POSITIVE_FIXNUM / len) + if (string_len > STRING_BYTES_MAX / len) string_overflow (); nbytes = len * string_len; val = make_uninit_multibyte_string (string_len, nbytes); === modified file 'src/buffer.h' --- src/buffer.h 2011-05-12 07:07:06 +0000 +++ src/buffer.h 2011-06-06 06:16:12 +0000 @@ -306,6 +306,11 @@ } \ while (0) +/* Maximum number of bytes in a buffer. + A buffer cannot contain more bytes than a 1-origin fixnum can represent, + nor can it be so large that C pointer arithmetic stops working. */ +#define BUF_BYTES_MAX min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX)) + /* Return the address of byte position N in current buffer. */ #define BYTE_POS_ADDR(n) \ @@ -545,7 +550,7 @@ -1 means visited file was nonexistent. 0 means visited file modtime unknown; in no case complain about any mismatch on next save attempt. */ - int modtime; + time_t modtime; /* Size of the file when modtime was set. This is used to detect the case where the file grew while we were reading it, so the modtime is still the same (since it's rounded up to seconds) but we're actually === modified file 'src/character.c' --- src/character.c 2011-05-21 04:33:23 +0000 +++ src/character.c 2011-06-06 06:16:12 +0000 @@ -838,7 +838,7 @@ if (multibyte) { if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count - || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count) + || (STRING_BYTES_MAX - nbytes) / 2 < byte8_count) string_overflow (); /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ @@ -847,7 +847,7 @@ } else { - if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count) + if ((STRING_BYTES_MAX - nchars) / 3 < byte8_count) string_overflow (); /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ === modified file 'src/character.h' --- src/character.h 2011-05-21 04:33:23 +0000 +++ src/character.h 2011-06-01 02:49:12 +0000 @@ -544,7 +544,7 @@ Lisp_Object val; \ val = CHAR_TABLE_REF (Vchar_unify_table, c); \ if (INTEGERP (val)) \ - c = XINT (val); \ + c = XFASTINT (val); \ else if (! NILP (val)) \ c = maybe_unify_char (c, val); \ } \ === modified file 'src/charset.c' --- src/charset.c 2011-05-31 06:05:00 +0000 +++ src/charset.c 2011-06-03 18:11:17 +0000 @@ -1637,7 +1637,7 @@ struct charset *charset; if (INTEGERP (val)) - return XINT (val); + return XFASTINT (val); if (NILP (val)) return c; @@ -1647,7 +1647,7 @@ { val = CHAR_TABLE_REF (Vchar_unify_table, c); if (! NILP (val)) - c = XINT (val); + c = XFASTINT (val); } else { === modified file 'src/coding.c' --- src/coding.c 2011-05-30 01:12:12 +0000 +++ src/coding.c 2011-06-06 06:16:12 +0000 @@ -1071,8 +1071,8 @@ static void coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes) { - if (coding->dst_bytes >= MOST_POSITIVE_FIXNUM - bytes) - error ("Maximum size of buffer or string exceeded"); + if (STRING_BYTES_MAX - coding->dst_bytes < bytes) + string_overflow (); coding->destination = (unsigned char *) xrealloc (coding->destination, coding->dst_bytes + bytes); coding->dst_bytes += bytes; === modified file 'src/dired.c' --- src/dired.c 2011-04-14 19:34:42 +0000 +++ src/dired.c 2011-06-06 05:55:38 +0000 @@ -1013,12 +1013,11 @@ The code on the next line avoids a compiler warning on systems where st_ino is 32 bit wide. (bug#766). */ EMACS_INT high_ino = s.st_ino >> 31 >> 1; - EMACS_INT low_ino = s.st_ino & 0xffffffff; values[10] = Fcons (make_number (high_ino >> 8), Fcons (make_number (((high_ino & 0xff) << 16) - + (low_ino >> 16)), - make_number (low_ino & 0xffff))); + + (s.st_ino >> 16 & 0xffff)), + make_number (s.st_ino & 0xffff))); } /* Likewise for device. */ === modified file 'src/doprnt.c' --- src/doprnt.c 2011-04-30 20:05:43 +0000 +++ src/doprnt.c 2011-06-06 06:16:12 +0000 @@ -329,7 +329,7 @@ minlen = atoi (&fmtcpy[1]); string = va_arg (ap, char *); tem = strlen (string); - if (tem > MOST_POSITIVE_FIXNUM) + if (tem > STRING_BYTES_MAX) error ("String for %%s or %%S format is too long"); width = strwidth (string, tem); goto doit1; @@ -338,7 +338,7 @@ doit: /* Coming here means STRING contains ASCII only. */ tem = strlen (string); - if (tem > MOST_POSITIVE_FIXNUM) + if (tem > STRING_BYTES_MAX) error ("Format width or precision too large"); width = tem; doit1: === modified file 'src/editfns.c' --- src/editfns.c 2011-06-05 22:46:26 +0000 +++ src/editfns.c 2011-06-06 06:16:12 +0000 @@ -2342,7 +2342,7 @@ len = CHAR_STRING (XFASTINT (character), str); else str[0] = XFASTINT (character), len = 1; - if (MOST_POSITIVE_FIXNUM / len < XINT (count)) + if (BUF_BYTES_MAX / len < XINT (count)) error ("Maximum buffer size would be exceeded"); n = XINT (count) * len; if (n <= 0) @@ -3589,7 +3589,7 @@ char initial_buffer[4000]; char *buf = initial_buffer; EMACS_INT bufsize = sizeof initial_buffer; - EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); + EMACS_INT max_bufsize = STRING_BYTES_MAX + 1; char *p; Lisp_Object buf_save_value IF_LINT (= {0}); register char *format, *end, *format_start; === modified file 'src/eval.c' --- src/eval.c 2011-05-30 05:39:59 +0000 +++ src/eval.c 2011-06-06 06:16:12 +0000 @@ -1994,7 +1994,7 @@ { char buf[4000]; size_t size = sizeof buf; - size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); + size_t size_max = STRING_BYTES_MAX + 1; size_t mlen = strlen (m); char *buffer = buf; size_t used; === modified file 'src/fileio.c' --- src/fileio.c 2011-04-29 19:47:29 +0000 +++ src/fileio.c 2011-06-06 06:16:12 +0000 @@ -3248,7 +3248,7 @@ /* Check whether the size is too large or negative, which can happen on a platform that allows file sizes greater than the maximum off_t value. */ if (! not_regular - && ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM)) + && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX)) error ("Maximum buffer size exceeded"); /* Prevent redisplay optimizations. */ @@ -4960,7 +4960,7 @@ if ((st.st_mtime == b->modtime /* If both are positive, accept them if they are off by one second. */ || (st.st_mtime > 0 && b->modtime > 0 - && (st.st_mtime == b->modtime + 1 + && (st.st_mtime - 1 == b->modtime || st.st_mtime == b->modtime - 1))) && (st.st_size == b->modtime_size || b->modtime_size < 0)) @@ -4990,7 +4990,7 @@ { if (! current_buffer->modtime) return make_number (0); - return make_time ((time_t) current_buffer->modtime); + return make_time (current_buffer->modtime); } DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, === modified file 'src/ftfont.c' --- src/ftfont.c 2011-04-11 03:39:45 +0000 +++ src/ftfont.c 2011-06-01 02:49:12 +0000 @@ -815,7 +815,7 @@ goto err; for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) if (CHARACTERP (XCAR (chars)) - && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) + && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars)))) goto err; } } === modified file 'src/image.c' --- src/image.c 2011-05-31 06:05:00 +0000 +++ src/image.c 2011-06-06 06:10:06 +0000 @@ -2112,9 +2112,6 @@ File Handling ***********************************************************************/ -static unsigned char *slurp_file (char *, int *); - - /* Find image file FILE. Look in data-directory/images, then x-bitmap-file-path. Value is the encoded full name of the file found, or nil if not found. */ @@ -2151,7 +2148,7 @@ occurred. *SIZE is set to the size of the file. */ static unsigned char * -slurp_file (char *file, int *size) +slurp_file (char *file, ptrdiff_t *size) { FILE *fp = NULL; unsigned char *buf = NULL; @@ -2159,6 +2156,7 @@ if (stat (file, &st) == 0 && (fp = fopen (file, "rb")) != NULL + && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) && (buf = (unsigned char *) xmalloc (st.st_size), fread (buf, 1, st.st_size, fp) == st.st_size)) { @@ -2814,7 +2812,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -4039,7 +4037,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -5021,6 +5019,7 @@ if (stat (SDATA (file), &st) == 0 && (fp = fopen (SDATA (file), "rb")) != NULL + && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) && (buf = (char *) xmalloc (st.st_size), fread (buf, 1, st.st_size, fp) == st.st_size)) { @@ -5055,7 +5054,7 @@ enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; unsigned char *contents = NULL; unsigned char *end, *p; - int size; + ptrdiff_t size; specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -7869,7 +7868,7 @@ static int svg_load (struct frame *f, struct image *img); static int svg_load_image (struct frame *, struct image *, - unsigned char *, unsigned int); + unsigned char *, ptrdiff_t); /* The symbol `svg' identifying images of this type. */ @@ -8047,7 +8046,7 @@ { Lisp_Object file; unsigned char *contents; - int size; + ptrdiff_t size; file = x_find_image_file (file_name); if (!STRINGP (file)) @@ -8096,7 +8095,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ struct image *img, /* Pointer to emacs image structure. */ unsigned char *contents, /* String containing the SVG XML data to be parsed. */ - unsigned int size) /* Size of data in bytes. */ + ptrdiff_t size) /* Size of data in bytes. */ { RsvgHandle *rsvg_handle; RsvgDimensionData dimension_data; === modified file 'src/keyboard.c' --- src/keyboard.c 2011-06-04 07:41:44 +0000 +++ src/keyboard.c 2011-06-06 05:48:28 +0000 @@ -2395,8 +2395,8 @@ c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index)); if (STRINGP (Vexecuting_kbd_macro) - && (XINT (c) & 0x80) && (XUINT (c) <= 0xff)) - XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80)); + && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff)) + XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80)); executing_kbd_macro_index++; @@ -3321,7 +3321,7 @@ if (INTEGERP (c)) { if (XUINT (c) < 0x100) - putc (XINT (c), dribble); + putc (XUINT (c), dribble); else fprintf (dribble, " 0x%"pI"x", XUINT (c)); } @@ -6370,7 +6370,7 @@ Lisp_Object parsed; parsed = parse_modifiers (symbol); - return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))), + return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))), XCAR (parsed)); } === modified file 'src/keymap.c' --- src/keymap.c 2011-05-12 07:07:06 +0000 +++ src/keymap.c 2011-06-01 02:49:12 +0000 @@ -462,7 +462,7 @@ XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); /* Handle the special meta -> esc mapping. */ - if (INTEGERP (idx) && XUINT (idx) & meta_modifier) + if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) { /* See if there is a meta-map. If there's none, there is no binding for IDX, unless a default binding exists in MAP. */ @@ -480,7 +480,7 @@ if (CONSP (event_meta_map)) { map = event_meta_map; - idx = make_number (XUINT (idx) & ~meta_modifier); + idx = make_number (XFASTINT (idx) & ~meta_modifier); } else if (t_ok) /* Set IDX to t, so that we only find a default binding. */ @@ -529,7 +529,7 @@ } else if (VECTORP (binding)) { - if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding)) + if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding)) val = AREF (binding, XFASTINT (idx)); } else if (CHAR_TABLE_P (binding)) @@ -537,7 +537,7 @@ /* Character codes with modifiers are not included in a char-table. All character codes without modifiers are included. */ - if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) + if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) { val = Faref (binding, idx); /* `nil' has a special meaning for char-tables, so @@ -1357,7 +1357,7 @@ int modifiers; parsed = parse_modifiers (c); - modifiers = (int) XUINT (XCAR (XCDR (parsed))); + modifiers = XFASTINT (XCAR (XCDR (parsed))); base = XCAR (parsed); name = Fsymbol_name (base); /* This alist includes elements such as ("RET" . "\\r"). */ @@ -2416,7 +2416,7 @@ { char tem[KEY_DESCRIPTION_SIZE]; - *push_key_description (XUINT (key), tem, 1) = 0; + *push_key_description (XINT (key), tem, 1) = 0; return build_string (tem); } else if (SYMBOLP (key)) /* Function key or event-symbol */ @@ -2515,7 +2515,7 @@ return 0; else { - int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); + int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); if (modifiers == where_is_preferred_modifier) result = 2; else if (modifiers) === modified file 'src/lisp.h' --- src/lisp.h 2011-06-02 08:25:28 +0000 +++ src/lisp.h 2011-06-06 06:16:12 +0000 @@ -763,6 +763,12 @@ #endif /* not GC_CHECK_STRING_BYTES */ +/* A string cannot contain more bytes than a fixnum can represent, + nor can it be so long that C pointer arithmetic stops working on + the string plus a terminating null. */ +#define STRING_BYTES_MAX \ + min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1) + /* Mark STR as a unibyte string. */ #define STRING_SET_UNIBYTE(STR) \ do { if (EQ (STR, empty_multibyte_string)) \ === modified file 'src/undo.c' --- src/undo.c 2011-04-14 05:04:02 +0000 +++ src/undo.c 2011-06-02 06:15:15 +0000 @@ -500,7 +500,7 @@ { /* Element (t high . low) records previous modtime. */ Lisp_Object high, low; - int mod_time; + time_t mod_time; struct buffer *base_buffer = current_buffer; high = Fcar (cdr); # Begin bundle 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 zo+ou5IpwoSErW6vUA== From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 04:39:36 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 08:39:36 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVLT-00082L-Dc for submit@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:36 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTVLP-000824-Fo for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 04:39:33 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 13EBB39E80FA; Mon, 6 Jun 2011 01:39:26 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UtC-fM3Xy+Sc; Mon, 6 Jun 2011 01:39:24 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 573BC39E80F0; Mon, 6 Jun 2011 01:39:24 -0700 (PDT) Message-ID: <4DEC923C.2090807@cs.ucla.edu> Date: Mon, 06 Jun 2011 01:39:24 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (c) fix the cons<->int conversions (2011-06-06 version) References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) Check for overflow when converting integer to cons and back. * charset.c (Fdefine_charset_internal, Fdecode_char): Use cons_to_unsigned to catch overflow. (Fencode_char): Use INTEGER_TO_CONS. * composite.h (LGLYPH_CODE): Use cons_to_unsigned. (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. * data.c (long_to_cons, cons_to_long): Remove. (cons_to_unsigned, cons_to_signed): New functions. These signal an error for invalid or out-of-range values. * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. * font.c (Ffont_variation_glyphs): * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. * lisp.h: Include . (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. (cons_to_signed, cons_to_unsigned): New decls. (long_to_cons, cons_to_long): Remove decls. * undo.c (record_first_change): Use INTEGER_TO_CONS. (Fprimitive_undo): Use CONS_TO_INTEGER. * xfns.c (Fx_window_property): Likewise. * xselect.c: Include . (x_own_selection, selection_data_to_lisp_data): Use INTEGER_TO_CONS. (x_handle_selection_request, x_handle_selection_clear) (x_get_foreign_selection, Fx_disown_selection_internal) (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. (lisp_data_to_selection_data): Use cons_to_unsigned. (x_fill_property_data): Use cons_to_signed. Report values out of range. === modified file 'src/charset.c' --- src/charset.c 2011-06-03 18:11:17 +0000 +++ src/charset.c 2011-06-06 06:19:52 +0000 @@ -932,17 +932,8 @@ val = args[charset_arg_min_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -954,17 +945,8 @@ val = args[charset_arg_max_code]; if (! NILP (val)) { - unsigned code; + unsigned code = cons_to_unsigned (val, UINT_MAX); - if (INTEGERP (val)) - code = XINT (val); - else - { - CHECK_CONS (val); - CHECK_NUMBER_CAR (val); - CHECK_NUMBER_CDR (val); - code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); - } if (code < charset.min_code || code > charset.max_code) args_out_of_range_3 (make_number (charset.min_code), @@ -1865,17 +1847,7 @@ struct charset *charsetp; CHECK_CHARSET_GET_ID (charset, id); - if (CONSP (code_point)) - { - CHECK_NATNUM_CAR (code_point); - CHECK_NATNUM_CDR (code_point); - code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); - } - else - { - CHECK_NATNUM (code_point); - code = XINT (code_point); - } + code = cons_to_unsigned (code_point, UINT_MAX); charsetp = CHARSET_FROM_ID (id); c = DECODE_CHAR (charsetp, code); return (c >= 0 ? make_number (c) : Qnil); @@ -1900,9 +1872,7 @@ code = ENCODE_CHAR (charsetp, XINT (ch)); if (code == CHARSET_INVALID_CODE (charsetp)) return Qnil; - if (code > 0x7FFFFFF) - return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); - return make_number (code); + return INTEGER_TO_CONS (code); } === modified file 'src/composite.h' --- src/composite.h 2011-05-31 06:05:00 +0000 +++ src/composite.h 2011-06-06 06:19:52 +0000 @@ -265,10 +265,7 @@ #define LGLYPH_CODE(g) \ (NILP (AREF ((g), LGLYPH_IX_CODE)) \ ? FONT_INVALID_CODE \ - : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ - ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ - | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ - : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) + : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) @@ -280,15 +277,8 @@ #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) /* Callers must assure that VAL is not negative! */ #define LGLYPH_SET_CODE(g, val) \ - do { \ - if (val == FONT_INVALID_CODE) \ - ASET ((g), LGLYPH_IX_CODE, Qnil); \ - else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ - ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ - make_number ((val) & 0xFFFF))); \ - else \ - ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ - } while (0) + ASET (g, LGLYPH_IX_CODE, \ + val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) === modified file 'src/data.c' --- src/data.c 2011-05-31 14:57:53 +0000 +++ src/data.c 2011-06-06 08:16:15 +0000 @@ -2326,33 +2326,110 @@ return Qnil; } -/* Convert between long values and pairs of Lisp integers. - Note that long_to_cons returns a single Lisp integer - when the value fits in one. */ +/* Convert the cons-of-integers, integer, or float value C to an + unsigned value with maximum value MAX. Signal an error if C does not + have a valid format or is out of range. */ +uintmax_t +cons_to_unsigned (Lisp_Object c, uintmax_t max) +{ + int valid = 0; + uintmax_t val IF_LINT (= 0); + if (INTEGERP (c)) + { + valid = 0 <= XINT (c); + val = XINT (c); + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (0 <= d + && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c) && NATNUMP (XCAR (c))) + { + uintmax_t top = XFASTINT (XCAR (c)); + Lisp_Object rest = XCDR (c); + if (top <= UINTMAX_MAX >> 24 >> 16 + && CONSP (rest) + && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 + && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) + { + uintmax_t mid = XFASTINT (XCAR (rest)); + val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); + valid = 1; + } + else if (top <= UINTMAX_MAX >> 16) + { + if (CONSP (rest)) + rest = XCAR (rest); + if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) + { + val = top << 16 | XFASTINT (rest); + valid = 1; + } + } + } -Lisp_Object -long_to_cons (long unsigned int i) -{ - unsigned long top = i >> 16; - unsigned int bot = i & 0xFFFF; - if (top == 0) - return make_number (bot); - if (top == (unsigned long)-1 >> 16) - return Fcons (make_number (-1), make_number (bot)); - return Fcons (make_number (top), make_number (bot)); + if (! (valid && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } -unsigned long -cons_to_long (Lisp_Object c) +/* Convert the cons-of-integers, integer, or float value C to a signed + value with extrema MIN and MAX. Signal an error if C does not have + a valid format or is out of range. */ +intmax_t +cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) { - Lisp_Object top, bot; + int valid = 0; + intmax_t val IF_LINT (= 0); if (INTEGERP (c)) - return XINT (c); - top = XCAR (c); - bot = XCDR (c); - if (CONSP (bot)) - bot = XCAR (bot); - return ((XINT (top) << 16) | XINT (bot)); + { + val = XINT (c); + valid = 1; + } + else if (FLOATP (c)) + { + double d = XFLOAT_DATA (c); + if (min <= d + && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) + { + val = d; + valid = 1; + } + } + else if (CONSP (c) && INTEGERP (XCAR (c))) + { + intmax_t top = XINT (XCAR (c)); + Lisp_Object rest = XCDR (c); + if (INTMAX_MIN >> 24 >> 16 <= top && top <= INTMAX_MAX >> 24 >> 16 + && CONSP (rest) + && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 + && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) + { + intmax_t mid = XFASTINT (XCAR (rest)); + val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); + valid = 1; + } + else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16) + { + if (CONSP (rest)) + rest = XCAR (rest); + if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) + { + val = top << 16 | XFASTINT (rest); + valid = 1; + } + } + } + + if (! (valid && min <= val && val <= max)) + error ("Not an in-range integer, float, or cons of integers"); + return val; } DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, === modified file 'src/dired.c' --- src/dired.c 2011-06-06 05:55:38 +0000 +++ src/dired.c 2011-06-06 06:26:32 +0000 @@ -900,11 +900,10 @@ This is a floating point number if the size is too large for an integer. 8. File modes, as a string of ten letters or dashes as in ls -l. 9. t if file's gid would change if file were deleted and recreated. -10. inode number. If inode number is larger than what Emacs integer - can hold, but still fits into a 32-bit number, this is a cons cell - containing two integers: first the high part, then the low 16 bits. - If the inode number is wider than 32 bits, this is of the form - (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits, +10. inode number. If it is larger than what an Emacs integer can hold, + this is of the form (HIGH . LOW): first the high bits, then the low 16 bits. + If even HIGH is too large for an Emacs integer, this is instead of the form + (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, and finally the low 16 bits. 11. Filesystem device number. If it is larger than what the Emacs integer can hold, this is a cons cell, similar to the inode number. @@ -998,34 +997,8 @@ #else /* file gid will be egid */ values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; #endif /* not BSD4_2 */ - if (!FIXNUM_OVERFLOW_P (s.st_ino)) - /* Keep the most common cases as integers. */ - values[10] = make_number (s.st_ino); - else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) - /* To allow inode numbers larger than VALBITS, separate the bottom - 16 bits. */ - values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), - make_number ((EMACS_INT)(s.st_ino & 0xffff))); - else - { - /* To allow inode numbers beyond 32 bits, separate into 2 24-bit - high parts and a 16-bit bottom part. - The code on the next line avoids a compiler warning on - systems where st_ino is 32 bit wide. (bug#766). */ - EMACS_INT high_ino = s.st_ino >> 31 >> 1; - - values[10] = Fcons (make_number (high_ino >> 8), - Fcons (make_number (((high_ino & 0xff) << 16) - + (s.st_ino >> 16 & 0xffff)), - make_number (s.st_ino & 0xffff))); - } - - /* Likewise for device. */ - if (FIXNUM_OVERFLOW_P (s.st_dev)) - values[11] = Fcons (make_number (s.st_dev >> 16), - make_number (s.st_dev & 0xffff)); - else - values[11] = make_number (s.st_dev); + values[10] = INTEGER_TO_CONS (s.st_ino); + values[11] = INTEGER_TO_CONS (s.st_dev); return Flist (sizeof(values) / sizeof(values[0]), values); } === modified file 'src/fileio.c' --- src/fileio.c 2011-06-06 06:16:12 +0000 +++ src/fileio.c 2011-06-06 06:19:52 +0000 @@ -5005,7 +5005,7 @@ { if (!NILP (time_list)) { - current_buffer->modtime = cons_to_long (time_list); + CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); current_buffer->modtime_size = -1; } else === modified file 'src/font.c' --- src/font.c 2011-05-29 19:04:01 +0000 +++ src/font.c 2011-06-06 06:19:52 +0000 @@ -4388,16 +4388,8 @@ for (i = 0; i < 255; i++) if (variations[i]) { - Lisp_Object code; int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); - /* Stops GCC whining about limited range of data type. */ - EMACS_INT var = variations[i]; - - if (var > MOST_POSITIVE_FIXNUM) - code = Fcons (make_number ((variations[i]) >> 16), - make_number ((variations[i]) & 0xFFFF)); - else - code = make_number (variations[i]); + Lisp_Object code = INTEGER_TO_CONS (variations[i]); val = Fcons (Fcons (make_number (vs), code), val); } return val; === modified file 'src/fontset.c' --- src/fontset.c 2011-05-28 22:39:39 +0000 +++ src/fontset.c 2011-06-06 06:19:52 +0000 @@ -1859,17 +1859,11 @@ { unsigned code = face->font->driver->encode_char (face->font, c); Lisp_Object font_object; - /* Assignment to EMACS_INT stops GCC whining about limited range - of data type. */ - EMACS_INT cod = code; if (code == FONT_INVALID_CODE) return Qnil; XSETFONT (font_object, face->font); - if (cod <= MOST_POSITIVE_FIXNUM) - return Fcons (font_object, make_number (code)); - return Fcons (font_object, Fcons (make_number (code >> 16), - make_number (code & 0xFFFF))); + return Fcons (font_object, INTEGER_TO_CONS (code)); } return Qnil; } === modified file 'src/lisp.h' --- src/lisp.h 2011-06-06 06:16:12 +0000 +++ src/lisp.h 2011-06-06 07:44:04 +0000 @@ -24,6 +24,8 @@ #include #include +#include + /* Use the configure flag --enable-checking[=LIST] to enable various types of run time checks for Lisp objects. */ @@ -2408,9 +2410,35 @@ EXFUN (Fsub1, 1); EXFUN (Fmake_variable_buffer_local, 1); +/* Convert the integer I to an Emacs representation, either the integer + itself, or a cons of two or three integers, or if all else fails a float. + I should not have side effects. */ +#define INTEGER_TO_CONS(i) \ + (! FIXNUM_OVERFLOW_P (i) \ + ? make_number (i) \ + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ + && FIXNUM_OVERFLOW_P ((i) >> 16)) \ + ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ + : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16 >> 24) \ + || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16 >> 24)) \ + && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \ + ? Fcons (make_number ((i) >> 16 >> 24), \ + Fcons (make_number ((i) >> 16 & 0xffffff), \ + make_number ((i) & 0xffff))) \ + : make_float (i)) + +/* Convert the Emacs representation CONS back to an integer of type + TYPE, storing the result the variable VAR. Signal an error if CONS + is not a valid representation or is out of range for TYPE. */ +#define CONS_TO_INTEGER(cons, type, var) \ + (TYPE_SIGNED (type) \ + ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ + : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) +extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); +extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); + extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); -extern Lisp_Object long_to_cons (unsigned long); -extern unsigned long cons_to_long (Lisp_Object); extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; === modified file 'src/undo.c' --- src/undo.c 2011-06-02 06:15:15 +0000 +++ src/undo.c 2011-06-06 06:19:52 +0000 @@ -212,7 +212,6 @@ void record_first_change (void) { - Lisp_Object high, low; struct buffer *base_buffer = current_buffer; if (EQ (BVAR (current_buffer, undo_list), Qt)) @@ -225,9 +224,9 @@ if (base_buffer->base_buffer) base_buffer = base_buffer->base_buffer; - XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); - XSETFASTINT (low, base_buffer->modtime & 0xffff); - BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); + BVAR (current_buffer, undo_list) = + Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), + BVAR (current_buffer, undo_list)); } /* Record a change in property PROP (whose old value was VAL) @@ -499,13 +498,9 @@ if (EQ (car, Qt)) { /* Element (t high . low) records previous modtime. */ - Lisp_Object high, low; + struct buffer *base_buffer = current_buffer; time_t mod_time; - struct buffer *base_buffer = current_buffer; - - high = Fcar (cdr); - low = Fcdr (cdr); - mod_time = (XFASTINT (high) << 16) + XFASTINT (low); + CONS_TO_INTEGER (cdr, time_t, mod_time); if (current_buffer->base_buffer) base_buffer = current_buffer->base_buffer; === modified file 'src/xfns.c' --- src/xfns.c 2011-06-05 22:20:42 +0000 +++ src/xfns.c 2011-06-06 06:19:52 +0000 @@ -4299,18 +4299,9 @@ if (! NILP (source)) { - if (NUMBERP (source)) - { - if (FLOATP (source)) - target_window = (Window) XFLOAT (source); - else - target_window = XFASTINT (source); - - if (target_window == 0) - target_window = FRAME_X_DISPLAY_INFO (f)->root_window; - } - else if (CONSP (source)) - target_window = cons_to_long (source); + CONS_TO_INTEGER (source, Window, target_window); + if (! target_window) + target_window = FRAME_X_DISPLAY_INFO (f)->root_window; } BLOCK_INPUT; === modified file 'src/xselect.c' --- src/xselect.c 2011-06-04 22:08:32 +0000 +++ src/xselect.c 2011-06-06 06:27:37 +0000 @@ -20,6 +20,7 @@ /* Rewritten by jwz */ #include +#include #include /* termhooks.h needs this */ #include @@ -335,7 +336,7 @@ Lisp_Object prev_value; selection_data = list4 (selection_name, selection_value, - long_to_cons (timestamp), frame); + INTEGER_TO_CONS (timestamp), frame); prev_value = LOCAL_SELECTION (selection_name, dpyinfo); dpyinfo->terminal->Vselection_alist @@ -419,7 +420,7 @@ || INTEGERP (check) || NILP (value)) return value; - /* Check for a value that cons_to_long could handle. */ + /* Check for a value that CONS_TO_INTEGER could handle. */ else if (CONSP (check) && INTEGERP (XCAR (check)) && (INTEGERP (XCDR (check)) @@ -782,8 +783,8 @@ if (NILP (local_selection_data)) goto DONE; /* Decline requests issued prior to our acquiring the selection. */ - local_selection_time - = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); if (SELECTION_EVENT_TIME (event) != CurrentTime && local_selection_time > SELECTION_EVENT_TIME (event)) goto DONE; @@ -950,8 +951,8 @@ /* Well, we already believe that we don't own it, so that's just fine. */ if (NILP (local_selection_data)) return; - local_selection_time = (Time) - cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); + CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), + Time, local_selection_time); /* We have reasserted the selection since this SelectionClear was generated, so we can disregard it. */ @@ -1212,16 +1213,7 @@ return Qnil; if (! NILP (time_stamp)) - { - if (CONSP (time_stamp)) - requestor_time = (Time) cons_to_long (time_stamp); - else if (INTEGERP (time_stamp)) - requestor_time = (Time) XUINT (time_stamp); - else if (FLOATP (time_stamp)) - requestor_time = (Time) XFLOAT_DATA (time_stamp); - else - error ("TIME_STAMP must be cons or number"); - } + CONS_TO_INTEGER (time_stamp, Time, requestor_time); BLOCK_INPUT; TRACE2 ("Get selection %s, type %s", @@ -1639,7 +1631,7 @@ convert it to a cons of integers, 16 bits in each half. */ else if (format == 32 && size == sizeof (int)) - return long_to_cons (((unsigned int *) data) [0]); + return INTEGER_TO_CONS (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (short)) return make_number ((int) (((unsigned short *) data) [0])); @@ -1665,7 +1657,7 @@ for (i = 0; i < size / 4; i++) { unsigned int j = ((unsigned int *) data) [i]; - Faset (v, make_number (i), long_to_cons (j)); + Faset (v, make_number (i), INTEGER_TO_CONS (j)); } return v; } @@ -1742,7 +1734,7 @@ *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); (*data_ret) [sizeof (long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_long (obj); + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1790,11 +1782,11 @@ *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); for (i = 0; i < *size_ret; i++) if (*format_ret == 32) - (*((unsigned long **) data_ret)) [i] - = cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned long **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); else - (*((unsigned short **) data_ret)) [i] - = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); + (*((unsigned short **) data_ret)) [i] = + cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); } } else @@ -2012,8 +2004,10 @@ selection_atom = symbol_to_x_atom (dpyinfo, selection); BLOCK_INPUT; - timestamp = (NILP (time_object) ? last_event_timestamp - : cons_to_long (time_object)); + if (NILP (time_object)) + timestamp = last_event_timestamp; + else + CONS_TO_INTEGER (time_object, Time, timestamp); XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); UNBLOCK_INPUT; @@ -2250,12 +2244,8 @@ { Lisp_Object o = XCAR (iter); - if (INTEGERP (o)) - val = (long) XFASTINT (o); - else if (FLOATP (o)) - val = (long) XFLOAT_DATA (o); - else if (CONSP (o)) - val = (long) cons_to_long (o); + if (INTEGERP (o) || FLOATP (o) || CONSP (o)) + val = cons_to_signed (o, LONG_MIN, LONG_MAX); else if (STRINGP (o)) { BLOCK_INPUT; @@ -2266,9 +2256,19 @@ error ("Wrong type, must be string, number or cons"); if (format == 8) - *d08++ = (char) val; + { + if (CHAR_MIN <= val && val <= CHAR_MAX) + *d08++ = val; + else + error ("Out of 'char' range"); + } else if (format == 16) - *d16++ = (short) val; + { + if (SHRT_MIN <= val && val <= SHRT_MAX) + *d16++ = val; + else + error ("Out of 'short' range"); + } else *d32++ = val; } @@ -2352,14 +2352,7 @@ Atom atom; int had_errors; - if (INTEGERP (value)) - atom = (Atom) XUINT (value); - else if (FLOATP (value)) - atom = (Atom) XFLOAT_DATA (value); - else if (CONSP (value)) - atom = (Atom) cons_to_long (value); - else - error ("Wrong type, value must be number or cons"); + CONS_TO_INTEGER (value, Atom, atom); BLOCK_INPUT; x_catch_errors (dpy); @@ -2549,17 +2542,8 @@ else error ("DEST as a string must be one of PointerWindow or InputFocus"); } - else if (INTEGERP (dest)) - wdest = (Window) XFASTINT (dest); - else if (FLOATP (dest)) - wdest = (Window) XFLOAT_DATA (dest); - else if (CONSP (dest)) - { - if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) - error ("Both car and cdr for DEST must be numbers"); - else - wdest = (Window) cons_to_long (dest); - } + else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) + CONS_TO_INTEGER (dest, Window, wdest); else error ("DEST must be a frame, nil, string, number or cons"); From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 10:52:53 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 14:52:53 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTbAg-00005V-U8 for submit@debbugs.gnu.org; Mon, 06 Jun 2011 10:52:52 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTbAe-00005F-8a; Mon, 06 Jun 2011 10:52:49 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:37678 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QTbAY-00040o-7X; Mon, 06 Jun 2011 10:52:42 -0400 Received: by ceviche.home (Postfix, from userid 20848) id EDD5C66189; Mon, 6 Jun 2011 11:52:39 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: (b) make the 64bit-on-32bit the default (if supported) Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> <4DE93610.4040209@cs.ucla.edu> Date: Mon, 06 Jun 2011 11:52:39 -0300 In-Reply-To: <4DE93610.4040209@cs.ucla.edu> (Paul Eggert's message of "Fri, 03 Jun 2011 12:29:20 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) severity 8794 wishlist tags 8794 +patch thanks As mentioned earlier, I don't think we want to install this right now, so let's keep it as an option for now and reconsider this choice for Emacs-24.2. We should make a --with-wide-int option for ./configure, tho. Stefan >>>>> "Paul" == Paul Eggert writes: > Almost all of this is documentation change. The only code change > is the lisp.h change to the default. > === modified file 'doc/emacs/ChangeLog' > --- doc/emacs/ChangeLog 2011-05-28 18:22:08 +0000 > +++ doc/emacs/ChangeLog 2011-06-03 18:47:14 +0000 > @@ -1,3 +1,9 @@ > +2011-06-02 Paul Eggert > + > + Document wide integers better. > + * buffers.texi (Buffers): > + * files.texi (Visiting): Default buffer maximum is now 2 EiB typically. > + > 2011-05-28 Chong Yidong > * custom.texi (Hooks): Reorganize. Mention Prog mode. > === modified file 'doc/emacs/buffers.texi' > --- doc/emacs/buffers.texi 2011-01-25 04:08:28 +0000 > +++ doc/emacs/buffers.texi 2011-06-03 18:47:14 +0000 > @@ -43,8 +43,11 @@ > A buffer's size cannot be larger than some maximum, which is defined > by the largest buffer position representable by the @dfn{Emacs > integer} data type. This is because Emacs tracks buffer positions > -using that data type. For 32-bit machines, the largest buffer size is > -512 megabytes. > +using that data type. For most machines, the maximum buffer size > +enforced by the data types is @math{2^61 - 2} bytes, or about 2 EiB. > +For some older machines, the maximum is @math{2^29 - 2} bytes, or > +about 512 MiB. Buffer sizes are also limited by the size of Emacs's > +virtual memory. > @menu > * Select Buffer:: Creating a new buffer or reselecting an old one. > === modified file 'doc/emacs/files.texi' > --- doc/emacs/files.texi 2011-01-31 23:54:50 +0000 > +++ doc/emacs/files.texi 2011-06-03 18:47:14 +0000 > @@ -209,7 +209,8 @@ > about 10 megabytes), Emacs asks you for confirmation first. You can > answer @kbd{y} to proceed with visiting the file. Note, however, that > Emacs cannot visit files that are larger than the maximum Emacs buffer > -size, which is around 512 megabytes on 32-bit machines > +size, which is limited by the amount of memory Emacs can allocate > +and by the integers that Emacs can represent > (@pxref{Buffers}). If you try, Emacs will display an error message > saying that the maximum buffer size has been exceeded. > === modified file 'doc/lispref/ChangeLog' > --- doc/lispref/ChangeLog 2011-05-31 18:40:00 +0000 > +++ doc/lispref/ChangeLog 2011-06-03 18:49:33 +0000 > @@ -1,3 +1,12 @@ > +2011-06-03 Paul Eggert > + > + Document wide integers better. > + * files.texi (File Attributes): Document ino_t values better. > + * numbers.texi (Integer Basics, Integer Basics, Arithmetic Operations): > + (Bitwise Operations): > + * objects.texi (Integer Type): Integers are typically 62 bits now. > + * os.texi (Time Conversion): Document time_t values better. > + > 2011-05-31 Lars Magne Ingebrigtsen > * processes.texi (Process Information): Document > === modified file 'doc/lispref/files.texi' > --- doc/lispref/files.texi 2011-05-12 07:07:06 +0000 > +++ doc/lispref/files.texi 2011-06-03 18:49:33 +0000 > @@ -1236,12 +1236,13 @@ > @item > The file's inode number. If possible, this is an integer. If the > -inode number is too large to be represented as an integer in Emacs > -Lisp, but still fits into a 32-bit integer, then the value has the > -form @code{(@var{high} . @var{low})}, where @var{low} holds the low 16 > -bits. If the inode is wider than 32 bits, the value is of the form > +inode number @math{N} is too large to be represented as an integer in > +Emacs Lisp, but @math{N / 2^16} is representable, then the value has > +the form @code{(@var{high} . @var{low})}, where @var{high} holds the > +high bits (i.e., excluding the low-order bits) and @var{low} the low > +16 bits. If the inode number is even larger, the value is of the form > @code{(@var{high} @var{middle} . @var{low})}, where @code{high} holds > -the high 24 bits, @var{middle} the next 24 bits, and @var{low} the low > +the high bits, @var{middle} the next 24 bits, and @var{low} the low > 16 bits. > @item > === modified file 'doc/lispref/numbers.texi' > --- doc/lispref/numbers.texi 2011-05-05 06:31:14 +0000 > +++ doc/lispref/numbers.texi 2011-06-03 18:49:33 +0000 > @@ -36,22 +36,24 @@ > @section Integer Basics > The range of values for an integer depends on the machine. The > -minimum range is @minus{}536870912 to 536870911 (30 bits; i.e., > +typical range is @minus{}2305843009213693952 to 2305843009213693951 > +(62 bits; i.e., > @ifnottex > --2**29 > +-2**61 > @end ifnottex > @tex > -@math{-2^{29}} > +@math{-2^{61}} > @end tex > to > @ifnottex > -2**29 - 1), > +2**61 - 1) > @end ifnottex > @tex > -@math{2^{29}-1}), > +@math{2^{61}-1}) > @end tex > -but some machines may provide a wider range. Many examples in this > -chapter assume an integer has 30 bits. > +but some older machines provide only 30 bits. Many examples in this > +chapter assume that an integer has 62 bits and that floating point > +numbers are IEEE double precision. > @cindex overflow > The Lisp reader reads an integer as a sequence of digits with optional > @@ -63,7 +65,8 @@ > 1. ; @r{The integer 1.} > +1 ; @r{Also the integer 1.} > -1 ; @r{The integer @minus{}1.} > - 1073741825 ; @r{The floating point number 1073741825.0.} > + 4611686018427387904 > + ; @r{The floating point number 4.611686018427388e+18.} > 0 ; @r{The integer 0.} > -0 ; @r{The integer 0.} > @end example > @@ -94,25 +97,21 @@ > bitwise operators (@pxref{Bitwise Operations}), it is often helpful to > view the numbers in their binary form. > - In 30-bit binary, the decimal integer 5 looks like this: > + In 62-bit binary, the decimal integer 5 looks like this: > @example > -00 0000 0000 0000 0000 0000 0000 0101 > +0000...000101 (62 bits total) > @end example > -@noindent > -(We have inserted spaces between groups of 4 bits, and two spaces > -between groups of 8 bits, to make the binary integer easier to read.) > - > The integer @minus{}1 looks like this: > @example > -11 1111 1111 1111 1111 1111 1111 1111 > +1111...111111 (62 bits total) > @end example > @noindent > @cindex two's complement > -@minus{}1 is represented as 30 ones. (This is called @dfn{two's > +@minus{}1 is represented as 62 ones. (This is called @dfn{two's > complement} notation.) > The negative integer, @minus{}5, is creating by subtracting 4 from > @@ -120,24 +119,24 @@ > @minus{}5 looks like this: > @example > -11 1111 1111 1111 1111 1111 1111 1011 > +1111...111011 (62 bits total) > @end example > - In this implementation, the largest 30-bit binary integer value is > -536,870,911 in decimal. In binary, it looks like this: > + In this implementation, the largest 62-bit binary integer value is > +2,305,843,009,213,693,951 in decimal. In binary, it looks like this: > @example > -01 1111 1111 1111 1111 1111 1111 1111 > +0111...111111 (62 bits total) > @end example > Since the arithmetic functions do not check whether integers go > -outside their range, when you add 1 to 536,870,911, the value is the > -negative integer @minus{}536,870,912: > +outside their range, when you add 1 to 2,305,843,009,213,693,951, the value is the > +negative integer @minus{}2,305,843,009,213,693,952: > @example > -(+ 1 536870911) > - @result{} -536870912 > - @result{} 10 0000 0000 0000 0000 0000 0000 0000 > +(+ 1 2305843009213693951) > + @result{} -2305843009213693952 > + @result{} 1000...000000 (62 bits total) > @end example > Many of the functions described in this chapter accept markers for > @@ -508,8 +507,8 @@ > if any argument is floating. > It is important to note that in Emacs Lisp, arithmetic functions > -do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to > -@minus{}268435456, depending on your hardware. > +do not check for overflow. Thus @code{(1+ 2305843009213693951)} may > +evaluate to @minus{}2305843009213693952, depending on your hardware. > @defun 1+ number-or-marker > This function returns @var{number-or-marker} plus 1. > @@ -829,19 +828,19 @@ > The function @code{lsh}, like all Emacs Lisp arithmetic functions, does > not check for overflow, so shifting left can discard significant bits > and change the sign of the number. For example, left shifting > -536,870,911 produces @minus{}2 on a 30-bit machine: > +2,305,843,009,213,693,951 produces @minus{}2 on a typical machine: > @example > -(lsh 536870911 1) ; @r{left shift} > +(lsh 2305843009213693951 1) ; @r{left shift} > @result{} -2 > @end example > -In binary, in the 30-bit implementation, the argument looks like this: > +In binary, in the 62-bit implementation, the argument looks like this: > @example > @group > -;; @r{Decimal 536,870,911} > -01 1111 1111 1111 1111 1111 1111 1111 > +;; @r{Decimal 2,305,843,009,213,693,951} > +0111...111111 (62 bits total) > @end group > @end example > @@ -851,7 +850,7 @@ > @example > @group > ;; @r{Decimal @minus{}2} > -11 1111 1111 1111 1111 1111 1111 1110 > +1111...111110 (62 bits total) > @end group > @end example > @end defun > @@ -874,9 +873,9 @@ > @group > (ash -6 -1) @result{} -3 > ;; @r{Decimal @minus{}6 becomes decimal @minus{}3.} > -11 1111 1111 1111 1111 1111 1111 1010 > +1111...111010 (62 bits total) > @result{} > -11 1111 1111 1111 1111 1111 1111 1101 > +1111...111101 (62 bits total) > @end group > @end example > @@ -885,11 +884,11 @@ > @example > @group > -(lsh -6 -1) @result{} 536870909 > -;; @r{Decimal @minus{}6 becomes decimal 536,870,909.} > -11 1111 1111 1111 1111 1111 1111 1010 > +(lsh -6 -1) @result{} 2305843009213693949 > +;; @r{Decimal @minus{}6 becomes decimal 2,305,843,009,213,693,949.} > +1111...111010 (62 bits total) > @result{} > -01 1111 1111 1111 1111 1111 1111 1101 > +0111...111101 (62 bits total) > @end group > @end example > @@ -899,34 +898,35 @@ > @c with smallbook but not with regular book! --rjc 16mar92 > @smallexample > @group > - ; @r{ 30-bit binary values} > + ; @r{ 62-bit binary values} > -(lsh 5 2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - @result{} 20 ; = @r{00 0000 0000 0000 0000 0000 0001 0100} > +(lsh 5 2) ; 5 = @r{0000...000101} > + @result{} 20 ; = @r{0000...010100} > @end group > @group > (ash 5 2) > @result{} 20 > -(lsh -5 2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} > - @result{} -20 ; = @r{11 1111 1111 1111 1111 1111 1110 1100} > +(lsh -5 2) ; -5 = @r{1111...111011} > + @result{} -20 ; = @r{1111...101100} > (ash -5 2) > @result{} -20 > @end group > @group > -(lsh 5 -2) ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - @result{} 1 ; = @r{00 0000 0000 0000 0000 0000 0000 0001} > +(lsh 5 -2) ; 5 = @r{0000...000101} > + @result{} 1 ; = @r{0000...000001} > @end group > @group > (ash 5 -2) > @result{} 1 > @end group > @group > -(lsh -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} > - @result{} 268435454 ; = @r{00 0111 1111 1111 1111 1111 1111 1110} > +(lsh -5 -2) ; -5 = @r{1111...111011} > + @result{} 1152921504606846974 > + ; = @r{0011...111110} > @end group > @group > -(ash -5 -2) ; -5 = @r{11 1111 1111 1111 1111 1111 1111 1011} > - @result{} -2 ; = @r{11 1111 1111 1111 1111 1111 1111 1110} > +(ash -5 -2) ; -5 = @r{1111...111011} > + @result{} -2 ; = @r{1111...111110} > @end group > @end smallexample > @end defun > @@ -961,23 +961,23 @@ > @smallexample > @group > - ; @r{ 30-bit binary values} > + ; @r{ 62-bit binary values} > -(logand 14 13) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} > - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} > - @result{} 12 ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} > +(logand 14 13) ; 14 = @r{0000...001110} > + ; 13 = @r{0000...001101} > + @result{} 12 ; 12 = @r{0000...001100} > @end group > @group > -(logand 14 13 4) ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} > - ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} > - ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} > - @result{} 4 ; 4 = @r{00 0000 0000 0000 0000 0000 0000 0100} > +(logand 14 13 4) ; 14 = @r{0000...001110} > + ; 13 = @r{0000...001101} > + ; 4 = @r{0000...000100} > + @result{} 4 ; 4 = @r{0000...000100} > @end group > @group > (logand) > - @result{} -1 ; -1 = @r{11 1111 1111 1111 1111 1111 1111 1111} > + @result{} -1 ; -1 = @r{1111...111111} > @end group > @end smallexample > @end defun > @@ -991,18 +991,18 @@ > @smallexample > @group > - ; @r{ 30-bit binary values} > + ; @r{ 62-bit binary values} > -(logior 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} > - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - @result{} 13 ; 13 = @r{00 0000 0000 0000 0000 0000 0000 1101} > +(logior 12 5) ; 12 = @r{0000...001100} > + ; 5 = @r{0000...000101} > + @result{} 13 ; 13 = @r{0000...001101} > @end group > @group > -(logior 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} > - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} > - @result{} 15 ; 15 = @r{00 0000 0000 0000 0000 0000 0000 1111} > +(logior 12 5 7) ; 12 = @r{0000...001100} > + ; 5 = @r{0000...000101} > + ; 7 = @r{0000...000111} > + @result{} 15 ; 15 = @r{0000...001111} > @end group > @end smallexample > @end defun > @@ -1016,18 +1016,18 @@ > @smallexample > @group > - ; @r{ 30-bit binary values} > + ; @r{ 62-bit binary values} > -(logxor 12 5) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} > - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - @result{} 9 ; 9 = @r{00 0000 0000 0000 0000 0000 0000 1001} > +(logxor 12 5) ; 12 = @r{0000...001100} > + ; 5 = @r{0000...000101} > + @result{} 9 ; 9 = @r{0000...001001} > @end group > @group > -(logxor 12 5 7) ; 12 = @r{00 0000 0000 0000 0000 0000 0000 1100} > - ; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > - ; 7 = @r{00 0000 0000 0000 0000 0000 0000 0111} > - @result{} 14 ; 14 = @r{00 0000 0000 0000 0000 0000 0000 1110} > +(logxor 12 5 7) ; 12 = @r{0000...001100} > + ; 5 = @r{0000...000101} > + ; 7 = @r{0000...000111} > + @result{} 14 ; 14 = @r{0000...001110} > @end group > @end smallexample > @end defun > @@ -1040,9 +1040,9 @@ > @example > (lognot 5) > @result{} -6 > -;; 5 = @r{00 0000 0000 0000 0000 0000 0000 0101} > +;; 5 = @r{0000...000101} (62 bits total) > ;; @r{becomes} > -;; -6 = @r{11 1111 1111 1111 1111 1111 1111 1010} > +;; -6 = @r{1111...111010} (62 bits total) > @end example > @end defun > === modified file 'doc/lispref/objects.texi' > --- doc/lispref/objects.texi 2011-05-05 06:31:14 +0000 > +++ doc/lispref/objects.texi 2011-06-03 18:49:33 +0000 > @@ -164,25 +164,25 @@ > @node Integer Type > @subsection Integer Type > - The range of values for integers in Emacs Lisp is @minus{}536870912 to > -536870911 (30 bits; i.e., > + The range of values for integers in Emacs Lisp is > +@minus{}2305843009213693952 to 2305843009213693951 (62 bits; i.e., > @ifnottex > --2**29 > +-2**61 > @end ifnottex > @tex > -@math{-2^{29}} > +@math{-2^{61}} > @end tex > to > @ifnottex > -2**29 - 1) > +2**61 - 1) > @end ifnottex > @tex > -@math{2^{29}-1}) > +@math{2^{61}-1}) > @end tex > -on most machines. (Some machines may provide a wider range.) It is > -important to note that the Emacs Lisp arithmetic functions do not check > -for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most > -machines. > +on most machines. Some machines may provide a narrower or wider > +range; all machines provide at least 30 bits. Emacs Lisp arithmetic > +functions do not check for overflow. Thus @code{(1+ > +2305843009213693951)} is @minus{}2305843009213693952 on most machines. > The read syntax for integers is a sequence of (base ten) digits with an > optional sign at the beginning and an optional period at the end. The > @@ -195,7 +195,6 @@ > 1 ; @r{The integer 1.} > 1. ; @r{Also the integer 1.} > +1 ; @r{Also the integer 1.} > -1073741825 ; @r{Also the integer 1 on a 30-bit implementation.} > @end group > @end example > @@ -203,8 +202,8 @@ > As a special exception, if a sequence of digits specifies an integer > too large or too small to be a valid integer object, the Lisp reader > reads it as a floating-point number (@pxref{Floating Point Type}). > -For instance, on most machines @code{536870912} is read as the > -floating-point number @code{536870912.0}. > +For instance, on most machines @code{2305843009213693952} is read as the > +floating-point number @code{2.305843009213694e+18}. > @xref{Numbers}, for more information. > === modified file 'doc/lispref/os.texi' > --- doc/lispref/os.texi 2011-02-01 07:23:48 +0000 > +++ doc/lispref/os.texi 2011-06-03 18:49:33 +0000 > @@ -1193,11 +1193,11 @@ > from the functions @code{current-time} (@pxref{Time of Day}) and > @code{file-attributes} (@pxref{Definition of file-attributes}). > - Many operating systems are limited to time values that contain 32 bits > + Many 32-bit operating systems are limited to time values that contain 32 bits > of information; these systems typically handle only the times from > -1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, some > -operating systems have larger time values, and can represent times far > -in the past or future. > +1901-12-13 20:45:52 UTC through 2038-01-19 03:14:07 UTC. However, 64-bit > +and some 32-bit operating systems have larger time values, and can > +represent times far in the past or future. > Time conversion functions always use the Gregorian calendar, even > for dates before the Gregorian calendar was introduced. Year numbers > === modified file 'etc/ChangeLog' > --- etc/ChangeLog 2011-05-24 14:22:44 +0000 > +++ etc/ChangeLog 2011-06-03 18:42:04 +0000 > @@ -1,3 +1,7 @@ > +2011-06-03 Paul Eggert > + > + * NEWS: 62-bit integers are typical now. > + > 2011-05-24 Leo Liu > * NEWS: Mention the new primitive sha1 and the removal of sha1.el. > === modified file 'etc/NEWS' > --- etc/NEWS 2011-06-01 15:34:41 +0000 > +++ etc/NEWS 2011-06-03 18:42:04 +0000 > @@ -902,6 +902,14 @@ > *** New function `special-variable-p' to check whether a variable is > declared as dynamically bound. > +** Emacs integers have a wider range on typical 32-bit hosts. > +Previously, they were limited to a 30-bit range (-2**29 .. 2**29-1). > +Now, they are limited to a 62-bit range (-2**61 .. 2**61-1), the > +same as on 64-bit hosts. This increased range comes from the Emacs > +interpreter using 64-bit native integer types that are available > +on typical modern 32-bit platforms. Older 32-bit hosts that lack > +64-bit integers have the same 30-bit range as before. > + > ** pre/post-command-hook are not reset to nil upon error. > Instead, the offending function is removed. > === modified file 'src/ChangeLog' > --- src/ChangeLog 2011-06-03 18:22:12 +0000 > +++ src/ChangeLog 2011-06-03 18:42:59 +0000 > @@ -1,5 +1,14 @@ > 2011-06-03 Paul Eggert > + Fix doc for machines with wider system times such as time_t. > + On such machines, it's now safe to assume that EMACS_INT is as > + wide as the system times, so that shifting right by 16 will > + result in an integer that always fits in EMACS_INT. > + * dired.c (Ffile_attributes): Document large inode number handling. > + * termhooks.h: Fix comment for large time stamp handling. > + > + * lisp.h (WIDE_EMACS_INT): Now defaults to 1. > + > * xselect.c: Use 'unsigned' more consistently. > (selection_data_to_lisp_data, lisp_data_to_selection_data): > Use 'unsigned' consistently when computing sizes of unsigned objects. > === modified file 'src/dired.c' > --- src/dired.c 2011-06-02 06:21:13 +0000 > +++ src/dired.c 2011-06-03 18:42:59 +0000 > @@ -901,10 +901,10 @@ > 8. File modes, as a string of ten letters or dashes as in ls -l. > 9. t if file's gid would change if file were deleted and recreated. > 10. inode number. If inode number is larger than what Emacs integer > - can hold, but still fits into a 32-bit number, this is a cons cell > + can hold, but all but the bottom 16 bits still fits, this is a cons cell > containing two integers: first the high part, then the low 16 bits. > - If the inode number is wider than 32 bits, this is of the form > - (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits, > + If the inode number is still wider, this is of the form > + (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, > and finally the low 16 bits. > 11. Filesystem device number. If it is larger than what the Emacs > integer can hold, this is a cons cell, similar to the inode number. > @@ -1008,8 +1008,8 @@ > make_number ((EMACS_INT)(s.st_ino & 0xffff))); > else > { > - /* To allow inode numbers beyond 32 bits, separate into 2 24-bit > - high parts and a 16-bit bottom part. > + /* To allow inode numbers beyond what INTEGER_TO_CONS can handle, > + separate into 2 24-bit high parts and a 16-bit bottom part. > The code on the next line avoids a compiler warning on > systems where st_ino is 32 bit wide. (bug#766). */ > EMACS_INT high_ino = s.st_ino >> 31 >> 1; > === modified file 'src/lisp.h' > --- src/lisp.h 2011-06-03 18:14:49 +0000 > +++ src/lisp.h 2011-06-03 18:28:20 +0000 > @@ -36,13 +36,14 @@ > #define CHECK_CONS_LIST() ((void) 0) > #endif > -/* Temporarily disable wider-than-pointer integers until they're tested more. > - Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ > -/* #undef WIDE_EMACS_INT */ > +/* To disable wider-than-pointer integers, build with -DWIDE_EMACS_INT=0. */ > +#ifndef WIDE_EMACS_INT > +#define WIDE_EMACS_INT 1 > +#endif > /* These are default choices for the types to use. */ > #ifndef EMACS_INT > -# if BITS_PER_LONG < BITS_PER_LONG_LONG && defined WIDE_EMACS_INT > +# if BITS_PER_LONG < BITS_PER_LONG_LONG && WIDE_EMACS_INT > # define EMACS_INT long long > # define BITS_PER_EMACS_INT BITS_PER_LONG_LONG > # define pI "ll" > === modified file 'src/termhooks.h' > --- src/termhooks.h 2011-05-27 16:17:59 +0000 > +++ src/termhooks.h 2011-06-03 18:42:59 +0000 > @@ -342,8 +342,8 @@ > SELECTION-VALUE is the value that emacs owns for that selection. > It may be any kind of Lisp object. > SELECTION-TIMESTAMP is the time at which emacs began owning this > - selection, as a cons of two 16-bit numbers (making a 32 bit > - time.) > + selection, as an Emacs integer; or if that doesn't fit, as a > + cons of two 16-bit integers (making a 32 bit time.) > FRAME is the frame for which we made the selection. If there is > an entry in this alist, then it can be assumed that Emacs owns > that selection. From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 12:01:36 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 16:01:36 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTcF8-0002Sb-4A for submit@debbugs.gnu.org; Mon, 06 Jun 2011 12:01:36 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTcF5-0002SM-TT for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 12:01:28 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:39469 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QTcEz-0001Kw-4k; Mon, 06 Jun 2011 12:01:21 -0400 Received: by ceviche.home (Postfix, from userid 20848) id 01F8866189; Mon, 6 Jun 2011 13:01:16 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: cons_to_long fixes; making 64-bit EMACS_INT the default Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> <4DEC9227.5060000@cs.ucla.edu> Date: Mon, 06 Jun 2011 13:01:16 -0300 In-Reply-To: <4DEC9227.5060000@cs.ucla.edu> (Paul Eggert's message of "Mon, 06 Jun 2011 01:39:03 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) > What else needs to be done before it's reasonable to install > something like (b)? Experience with it. AFAIK a non-negligible fraction of users would be happy to see such a feature because they need to access large files that don't grow too fast (i.e. large but still within the 32bit limit) but: - this category of files is fairly small: only files between 512MB and 2GB, basically. So a non-negligible fraction of those users may end up finding out that it only covers some percentage of their needs because the other files go beyond the 2GB limit. - some other percentage of those users won't be satisfied either because such large files may prove too slow to access. - so given the limited benefits, I want to make sure the drawbacks are negligible. How is the memory use impacted by your change in "typical" sessions? How is the CPU use impacted in typical sessions? Benchmarks running the byte-compiler, Gnus, and any other intensive Elisp code would be welcome. Benchmarks testing the impact on redisplay performance wold also be welcome. I'd hope most of those benchmarks to show very little difference, but so far I haven't seen any reports to make confident that this is the case. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 13:17:53 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 17:17:53 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTdR3-0004Cg-HX for submit@debbugs.gnu.org; Mon, 06 Jun 2011 13:17:53 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTdR1-0004CU-Qa for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 13:17:52 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:41304 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QTdQv-0002bs-Ph; Mon, 06 Jun 2011 13:17:46 -0400 Received: by ceviche.home (Postfix, from userid 20848) id D901F660DD; Mon, 6 Jun 2011 14:17:42 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: (a) uncontroversial fixes (2011-06-06 version) Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> <4DEC9232.6040200@cs.ucla.edu> Date: Mon, 06 Jun 2011 14:17:42 -0300 In-Reply-To: <4DEC9232.6040200@cs.ucla.edu> (Paul Eggert's message of "Mon, 06 Jun 2011 01:39:14 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) Feel free to install it. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 13:18:27 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 17:18:27 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTdRb-0004Dk-6B for submit@debbugs.gnu.org; Mon, 06 Jun 2011 13:18:27 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTdRZ-0004DZ-OG for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 13:18:26 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:41305 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1QTdRU-0002dD-0v; Mon, 06 Jun 2011 13:18:20 -0400 Received: by ceviche.home (Postfix, from userid 20848) id 1712E660DD; Mon, 6 Jun 2011 14:18:18 -0300 (ART) From: Stefan Monnier To: Paul Eggert Subject: Re: bug#8794: (c) fix the cons<->int conversions (2011-06-06 version) Message-ID: References: <4DE89EB8.9020202@cs.ucla.edu> <4DE935F6.2080802@cs.ucla.edu> <4DEC923C.2090807@cs.ucla.edu> Date: Mon, 06 Jun 2011 14:18:18 -0300 In-Reply-To: <4DEC923C.2090807@cs.ucla.edu> (Paul Eggert's message of "Mon, 06 Jun 2011 01:39:24 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) > Check for overflow when converting integer to cons and back. Now that it doesn't depend on (b), feel free to install it. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Jun 06 13:54:35 2011 Received: (at 8794) by debbugs.gnu.org; 6 Jun 2011 17:54:35 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTe0Y-00052h-0r for submit@debbugs.gnu.org; Mon, 06 Jun 2011 13:54:34 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTe0W-00052V-1Y for 8794@debbugs.gnu.org; Mon, 06 Jun 2011 13:54:33 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 9476739E8121; Mon, 6 Jun 2011 10:54:26 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HtNnrTH6uBmf; Mon, 6 Jun 2011 10:54:24 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id D9B6439E80F0; Mon, 6 Jun 2011 10:54:24 -0700 (PDT) Message-ID: <4DED1450.9090605@cs.ucla.edu> Date: Mon, 06 Jun 2011 10:54:24 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (b) make the 64bit-on-32bit the default (if supported) References: <4DE89EB8.9020202@cs.ucla.edu> <4DE93610.4040209@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org, Emacs Development X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) [CC'ing to emacs-devel as this may be of more-general interest. This is about a plan to widen Emacs integers to 64 bits (62 bits after tagging) on typical 32-bit hosts. The original thread is in .] On 06/06/11 07:52, Stefan Monnier wrote: > let's keep it as an option for now and reconsider this choice for > Emacs-24.2. We should make a --with-wide-int option for ./configure, tho. OK, thanks, I'll add that option. > I want to make sure the drawbacks > are negligible. How is the memory use impacted by your change in > "typical" sessions? How is the CPU use impacted in typical sessions? > Benchmarks running the byte-compiler, Gnus, and any other intensive > Elisp code would be welcome. Benchmarks testing the impact on > redisplay performance wold also be welcome. > I'd hope most of those benchmarks to show very little difference, but so > far I haven't seen any reports to make confident that this is the case. This all sounds reasonable. I haven't noticed much difference in ordinary interactive use, but I haven't done quantitative benchmarks. Thanks for reviewing it and for taking the time to make these suggestions. One thing I plan to do while benchmarking is to replace EMACS_INT with ptrdiff_t whenever the value is known to fit in a 32-bit quantity on a 32-bit host. This won't make any difference unless --with-wide-int is used, since EMACS_INT and ptrdiff_t are normally the same (on both 32-bit and 64-bit hosts). But in the --with-wide-int case it should decrease both memory footprint and register pressure and should be a measurable win. I've started an effort to do that, and (as usual) I'm finding more int-overflow bugs as a side effect. For example, on a 64-bit host, (copy-sequence (make-bool-vector 17179869184 nil)) crashes Emacs, due to integer overflow. I plan to fix those bugs independently of the EMACS_INT->ptrdiff_t change. From debbugs-submit-bounces@debbugs.gnu.org Tue Jun 07 00:21:24 2011 Received: (at 8794) by debbugs.gnu.org; 7 Jun 2011 04:21:24 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTnn9-0002HX-PH for submit@debbugs.gnu.org; Tue, 07 Jun 2011 00:21:24 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QTnn6-0002HK-Rk for 8794@debbugs.gnu.org; Tue, 07 Jun 2011 00:21:22 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6235B39E80F7; Mon, 6 Jun 2011 21:21:14 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GKAPUkoMunt0; Mon, 6 Jun 2011 21:21:13 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 391A339E80F0; Mon, 6 Jun 2011 21:21:13 -0700 (PDT) Message-ID: <4DEDA733.4040008@cs.ucla.edu> Date: Mon, 06 Jun 2011 21:21:07 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110516 Thunderbird/3.1.10 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8794: (b) make the 64bit-on-32bit the default (if supported) References: <4DE89EB8.9020202@cs.ucla.edu> <4DE93610.4040209@cs.ucla.edu> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8794 Cc: 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) On 06/06/11 07:52, Stefan Monnier wrote: > We should make a --with-wide-int option for ./configure, tho. I did that in the trunk as bzr 104521, with this patch: [ChangeLog] * configure.in: Add --with-wide-int. * INSTALL: Mention this. [etc/ChangeLog] * NEWS: Mention new configure option --with-wide-int. === modified file 'INSTALL' --- INSTALL 2011-05-18 03:39:45 +0000 +++ INSTALL 2011-06-07 04:13:43 +0000 @@ -309,6 +309,10 @@ Use --without-sound to disable sound support. +Use --with-wide-int to implement Emacs values with the type 'long long', +even on hosts where a narrower type would do. With this option, on a +typical 32-bit host, Emacs integers have 62 bits instead of 30. + The `--prefix=PREFIXDIR' option specifies where the installation process should put emacs and its data files. This defaults to `/usr/local'. - Emacs (and the other utilities users run) go in PREFIXDIR/bin === modified file 'configure.in' --- configure.in 2011-05-28 22:39:39 +0000 +++ configure.in 2011-06-07 04:13:43 +0000 @@ -144,6 +144,11 @@ with_x_toolkit=$val ]) +OPTION_DEFAULT_OFF([wide-int], [prefer wide Emacs integers (typically 62-bit)]) +if test "$with_wide_int" = yes; then + AC_DEFINE([WIDE_EMACS_INT], 1, [Use long long for EMACS_INT if available.]) +fi + dnl _ON results in a '--without' option in the --help output, so dnl the help text should refer to "don't compile", etc. OPTION_DEFAULT_ON([xpm],[don't compile with XPM image support]) === modified file 'etc/NEWS' --- etc/NEWS 2011-06-06 19:43:39 +0000 +++ etc/NEWS 2011-06-07 04:13:43 +0000 @@ -47,6 +47,9 @@ This is only useful for Emacs developers to debug certain types of bugs. This is not a new feature; only the configure flag is new. +** There is a new configure option --with-wide-int. +With it, Emacs integers typically have 62 bits, even on 32-bit machines. + --- ** New translation of the Emacs Tutorial in Hebrew is available. Type `C-u C-h t' to choose it in case your language setup doesn't From debbugs-submit-bounces@debbugs.gnu.org Sat Dec 31 03:51:08 2011 Received: (at control) by debbugs.gnu.org; 31 Dec 2011 08:51:08 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Rguei-00008e-4Z for submit@debbugs.gnu.org; Sat, 31 Dec 2011 03:51:08 -0500 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Rgueg-00008X-JI for control@debbugs.gnu.org; Sat, 31 Dec 2011 03:51:07 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id C4104A60001 for ; Sat, 31 Dec 2011 00:48:05 -0800 (PST) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jrTnNomNcGz0 for ; Sat, 31 Dec 2011 00:48:05 -0800 (PST) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 7D47439E8007 for ; Sat, 31 Dec 2011 00:48:05 -0800 (PST) Message-ID: <4EFECC4A.70305@cs.ucla.edu> Date: Sat, 31 Dec 2011 00:48:10 -0800 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux i686; rv:8.0) Gecko/20111124 Thunderbird/8.0 MIME-Version: 1.0 To: control@debbugs.gnu.org Subject: 8794 has a patch Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -2.9 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.9 (--) tags 8794 patch From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 14 14:24:40 2012 Received: (at 8794) by debbugs.gnu.org; 14 Jun 2012 18:24:40 +0000 Received: from localhost ([127.0.0.1]:42617 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1SfEil-0002ef-DJ for submit@debbugs.gnu.org; Thu, 14 Jun 2012 14:24:40 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:41644) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1SfEij-0002eY-LD for 8794@debbugs.gnu.org; Thu, 14 Jun 2012 14:24:38 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 0AE0CA60008; Thu, 14 Jun 2012 11:21:42 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id USze9h9cjy7s; Thu, 14 Jun 2012 11:21:41 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 27C2839E8005; Thu, 14 Jun 2012 11:21:41 -0700 (PDT) Message-ID: <4FDA2BAF.8010707@cs.ucla.edu> Date: Thu, 14 Jun 2012 11:21:35 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: "Stephen J. Turnbull" Subject: Re: feature request: view part of file References: <87lijrszn0.fsf@gnu.org> <87d351uap6.fsf@gnu.org> <87wr396bpl.fsf@uwakimon.sk.tsukuba.ac.jp> In-Reply-To: <87wr396bpl.fsf@uwakimon.sk.tsukuba.ac.jp> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -1.9 (-) X-Debbugs-Envelope-To: 8794 Cc: sds@gnu.org, emacs-devel@gnu.org, 8794@debbugs.gnu.org, Mathias Dahl X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: 8794@debbugs.gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -1.9 (-) Following up to the thread at , on 06/14/2012 10:32 AM, Stephen J. Turnbull wrote: > some users did care about files bigger than 512MB Sam Steingold was talking about the large-file-warning-threshold limit, which is soft and which defaults to 10 MB, whereas GNU Emacs's hard 512 MiB limit (on 32-bit hosts) is imposed by how fixnums are implemented. We could increase GNU Emacs's hard limit from 512 MiB to 2 GiB by making --with-wide-int the default. This is Emacs bug 8794. Stefan asked in for measurements about the performance consequences of this change. I haven't gotten around to that, but will try to bump the priority. I'll CC: this to 8794@debbugs.gnu.org and ask for replies to be sent there too, as this topic is a somewhat-separate issue. From debbugs-submit-bounces@debbugs.gnu.org Thu Feb 25 01:49:34 2016 Received: (at 8794) by debbugs.gnu.org; 25 Feb 2016 06:49:34 +0000 Received: from localhost ([127.0.0.1]:44651 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aYpjy-00031h-D3 for submit@debbugs.gnu.org; Thu, 25 Feb 2016 01:49:34 -0500 Received: from hermes.netfonds.no ([80.91.224.195]:54320) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aYpjx-00031a-61 for 8794@debbugs.gnu.org; Thu, 25 Feb 2016 01:49:33 -0500 Received: from [175.103.25.178] (helo=mouse) by hermes.netfonds.no with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1aYpjX-0005Ji-Do; Thu, 25 Feb 2016 07:49:08 +0100 From: Lars Ingebrigtsen To: Paul Eggert Subject: Re: bug#8794: (c) fix the cons<->int conversions References: <4DE89EB8.9020202@cs.ucla.edu> <4DE9363B.7090504@cs.ucla.edu> Date: Thu, 25 Feb 2016 17:19:02 +1030 In-Reply-To: <4DE9363B.7090504@cs.ucla.edu> (Paul Eggert's message of "Fri, 03 Jun 2011 12:30:03 -0700") Message-ID: <87r3g1uvxd.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-MailScanner-ID: 1aYpjX-0005Ji-Do X-Netfonds-MailScanner: Found to be clean X-Netfonds-MailScanner-From: larsi@gnus.org MailScanner-NULL-Check: 1456987750.53822@V4Ud93cwoTsl3T+X00LqKw X-Spam-Status: No X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 8794 Cc: Stefan Monnier , 8794@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) This was a quite long thread, and some parts were supposed to be applied later. I've looked at a couple of those parts, and they seem to be applied now: grep --color -nH -e cons_to_unsigned *.c charset.c:918: unsigned code = cons_to_unsigned (val, UINT_MAX); charset.c:931: unsigned code = cons_to_unsigned (val, UINT_MAX); charset.c:956: charset.invalid_code = cons_to_unsigned (val, UINT_MAX); charset.c:1853: code = cons_to_unsigned (code_point, UINT_MAX); data.c:2458:cons_to_unsigned (Lisp_Object c, uintmax_t max) xselect.c:1663: return cons_to_unsigned (obj, X_ULONG_MAX); So I'm closing this bug report now. If there were bits that were still left dangling, please reopen. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no From debbugs-submit-bounces@debbugs.gnu.org Thu Feb 25 01:49:43 2016 Received: (at control) by debbugs.gnu.org; 25 Feb 2016 06:49:43 +0000 Received: from localhost ([127.0.0.1]:44660 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aYpk6-00032O-Vy for submit@debbugs.gnu.org; Thu, 25 Feb 2016 01:49:43 -0500 Received: from hermes.netfonds.no ([80.91.224.195]:54327) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aYpk4-00032F-N6 for control@debbugs.gnu.org; Thu, 25 Feb 2016 01:49:40 -0500 Received: from [175.103.25.178] (helo=mouse) by hermes.netfonds.no with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1aYpjh-0005Jy-1H for control@debbugs.gnu.org; Thu, 25 Feb 2016 07:49:17 +0100 Date: Thu, 25 Feb 2016 17:19:12 +1030 Message-Id: <87povluvx3.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #8794 X-MailScanner-ID: 1aYpjh-0005Jy-1H X-Netfonds-MailScanner: Found to be clean X-Netfonds-MailScanner-From: larsi@gnus.org MailScanner-NULL-Check: 1456987757.88632@iVnHJAOqTPCIcA7DPxd+pw X-Spam-Status: No X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) tags 8794 fixed close 8794 From unknown Tue Jun 24 15:39:36 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Thu, 24 Mar 2016 11:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator