>From ae38a3b8208a71c32f723776297290ee5096d8d4 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 22 Aug 2018 10:18:34 -0700 Subject: [PATCH] Make vc-hg safe for bignums * lisp/vc/vc-hg.el (vc-hg--raw-dirstate-search): Use eql, not eq, on integers that could be bignums. (vc-hg--time-to-integer): Rename from vc-hg--time-to-fixnum. All uses changed. (vc-hg-state-fast): Remove test that 32-bit unsigned values must be fixnums. --- lisp/vc/vc-hg.el | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index da4fc2bdf7..d11dc4c5f4 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -583,15 +583,14 @@ vc-hg-parse-hg-data-structures (defsubst vc-hg--read-u8 () "Read and advance over an unsigned byte. -Return a fixnum." +Return the byte's value as an integer." (prog1 (char-after) (forward-char))) (defsubst vc-hg--read-u32-be () - "Read and advance over a big-endian unsigned 32-bit integer. -Return a fixnum; on overflow, result is undefined." + "Read and advance over a big-endian unsigned 32-bit integer." ;; Because elisp bytecode has an instruction for multiply and - ;; doesn't have one for lsh, it's somewhat counter-intuitively + ;; doesn't have one for shift, it's somewhat counter-intuitively ;; faster to multiply than to shift. (+ (* (vc-hg--read-u8) (* 256 256 256)) (* (vc-hg--read-u8) (* 256 256)) @@ -627,12 +626,10 @@ vc-hg--raw-dirstate-search ;; hundreds of thousands of times, so performance is important ;; here (while (< (point) search-limit) - ;; 1+4*4 is the length of the dirstate item header, which we - ;; spell as a literal for performance, since the elisp - ;; compiler lacks constant propagation + ;; 1+4*4 is the length of the dirstate item header. (forward-char (1+ (* 3 4))) (let ((this-flen (vc-hg--read-u32-be))) - (if (and (or (eq this-flen flen) + (if (and (or (eql this-flen flen) (and (> this-flen flen) (eq (char-after (+ (point) flen)) 0))) (search-forward fname (+ (point) flen) t)) @@ -917,7 +914,7 @@ vc-hg--ignore-patterns-ignored-p (setf ignored (string-match (pop patterns) filename))) ignored)) -(defun vc-hg--time-to-fixnum (ts) +(defun vc-hg--time-to-integer (ts) (+ (* 65536 (car ts)) (cadr ts))) (defvar vc-hg--cached-ignore-patterns nil @@ -1016,8 +1013,6 @@ vc-hg-state-fast (not (vc-hg--requirements-understood-p repo)) ;; Dirstate too small to be valid (< (nth 7 dirstate-attr) 40) - ;; We want to store 32-bit unsigned values in fixnums. - (zerop (ash most-positive-fixnum -32)) (progn (setf repo-relative-filename (file-relative-name truename repo)) @@ -1042,7 +1037,7 @@ vc-hg-state-fast (let ((vc-hg-size (nth 2 dirstate-entry)) (vc-hg-mtime (nth 3 dirstate-entry)) (fs-size (nth 7 stat)) - (fs-mtime (vc-hg--time-to-fixnum (nth 5 stat)))) + (fs-mtime (vc-hg--time-to-integer (nth 5 stat)))) (if (and (eql vc-hg-size fs-size) (eql vc-hg-mtime fs-mtime)) 'up-to-date 'edited))) -- 2.17.1