aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2018-01-08 00:33:13 +0900
committerTino Calancha2018-01-08 00:33:15 +0900
commitbfca19e475c01f13dbacc7f8b7bb1aecf46cb7e4 (patch)
tree9dd5fede04dd8d423a4625bde5a97d6c2af9dce5
parent378be8df8d9075719437c475fbb520dd40d2353b (diff)
downloademacs-bfca19e475c01f13dbacc7f8b7bb1aecf46cb7e4.tar.gz
emacs-bfca19e475c01f13dbacc7f8b7bb1aecf46cb7e4.zip
cl-loop: Calculate the array length just once
* lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Dont calculate the array length on each iteration (Bug#29866).
-rw-r--r--lisp/emacs-lisp/cl-macs.el12
1 files changed, 9 insertions, 3 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 16f33282bae..9af014cf8e9 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1317,11 +1317,13 @@ For more details, see Info node `(cl)Loop Facility'.
1317 1317
1318 ((memq word '(across across-ref)) 1318 ((memq word '(across across-ref))
1319 (let ((temp-vec (make-symbol "--cl-vec--")) 1319 (let ((temp-vec (make-symbol "--cl-vec--"))
1320 (temp-len (make-symbol "--cl-len--"))
1320 (temp-idx (make-symbol "--cl-idx--"))) 1321 (temp-idx (make-symbol "--cl-idx--")))
1321 (push (list temp-vec (pop cl--loop-args)) loop-for-bindings) 1322 (push (list temp-vec (pop cl--loop-args)) loop-for-bindings)
1323 (push (list temp-len `(length ,temp-vec)) loop-for-bindings)
1322 (push (list temp-idx -1) loop-for-bindings) 1324 (push (list temp-idx -1) loop-for-bindings)
1323 (push `(< (setq ,temp-idx (1+ ,temp-idx)) 1325 (push `(< (setq ,temp-idx (1+ ,temp-idx))
1324 (length ,temp-vec)) 1326 ,temp-len)
1325 cl--loop-body) 1327 cl--loop-body)
1326 (if (eq word 'across-ref) 1328 (if (eq word 'across-ref)
1327 (push (list var `(aref ,temp-vec ,temp-idx)) 1329 (push (list var `(aref ,temp-vec ,temp-idx))
@@ -1336,6 +1338,7 @@ For more details, see Info node `(cl)Loop Facility'.
1336 (error "Expected `of'")))) 1338 (error "Expected `of'"))))
1337 (seq (cl--pop2 cl--loop-args)) 1339 (seq (cl--pop2 cl--loop-args))
1338 (temp-seq (make-symbol "--cl-seq--")) 1340 (temp-seq (make-symbol "--cl-seq--"))
1341 (temp-len (make-symbol "--cl-len--"))
1339 (temp-idx 1342 (temp-idx
1340 (if (eq (car cl--loop-args) 'using) 1343 (if (eq (car cl--loop-args) 'using)
1341 (if (and (= (length (cadr cl--loop-args)) 2) 1344 (if (and (= (length (cadr cl--loop-args)) 2)
@@ -1346,16 +1349,19 @@ For more details, see Info node `(cl)Loop Facility'.
1346 (push (list temp-seq seq) loop-for-bindings) 1349 (push (list temp-seq seq) loop-for-bindings)
1347 (push (list temp-idx 0) loop-for-bindings) 1350 (push (list temp-idx 0) loop-for-bindings)
1348 (if ref 1351 (if ref
1349 (let ((temp-len (make-symbol "--cl-len--"))) 1352 (progn
1350 (push (list temp-len `(length ,temp-seq)) 1353 (push (list temp-len `(length ,temp-seq))
1351 loop-for-bindings) 1354 loop-for-bindings)
1352 (push (list var `(elt ,temp-seq ,temp-idx)) 1355 (push (list var `(elt ,temp-seq ,temp-idx))
1353 cl--loop-symbol-macs) 1356 cl--loop-symbol-macs)
1354 (push `(< ,temp-idx ,temp-len) cl--loop-body)) 1357 (push `(< ,temp-idx ,temp-len) cl--loop-body))
1358 ;; Evaluate seq length just if needed, that is, when seq is not a cons.
1359 (push (list temp-len (or (consp seq) `(length ,temp-seq)))
1360 loop-for-bindings)
1355 (push (list var nil) loop-for-bindings) 1361 (push (list var nil) loop-for-bindings)
1356 (push `(and ,temp-seq 1362 (push `(and ,temp-seq
1357 (or (consp ,temp-seq) 1363 (or (consp ,temp-seq)
1358 (< ,temp-idx (length ,temp-seq)))) 1364 (< ,temp-idx ,temp-len)))
1359 cl--loop-body) 1365 cl--loop-body)
1360 (push (list var `(if (consp ,temp-seq) 1366 (push (list var `(if (consp ,temp-seq)
1361 (pop ,temp-seq) 1367 (pop ,temp-seq)