aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-05-29 10:28:02 -0400
committerStefan Monnier2012-05-29 10:28:02 -0400
commit6876a58db34b81e411293b5ee8d161aa451fd767 (patch)
treeb1cc081fe4c2b62f737018f19c016b95ff5a9e99
parent46b7967e4d98570501f5e75ba7460fa4c79e4617 (diff)
downloademacs-6876a58db34b81e411293b5ee8d161aa451fd767.tar.gz
emacs-6876a58db34b81e411293b5ee8d161aa451fd767.zip
Fix minor corner case bugs in byte compilation and pcase.
* lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Don't re-preprocess functions from byte-compile-function-environment. * lisp/emacs-lisp/bytecomp.el (byte-compile-constp): Treat #'v as a constant. (byte-compile-close-variables): Bind byte-compile--outbuffer here... (byte-compile-from-buffer): ...rather than here. * lisp/emacs-lisp/pcase.el (pcase--expand): Accept different sets of vars in different alternative patterns. (pcase-codegen): Be more careful to preserve identity. (pcase--u1): Don't forget to mark vars as used.
-rw-r--r--lisp/ChangeLog14
-rw-r--r--lisp/emacs-lisp/byte-opt.el12
-rw-r--r--lisp/emacs-lisp/bytecomp.el75
-rw-r--r--lisp/emacs-lisp/pcase.el15
4 files changed, 71 insertions, 45 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index fbb398335d8..83d3f3e4677 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,17 @@
12012-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/pcase.el (pcase--expand): Accept different sets of vars in
4 different alternative patterns.
5 (pcase-codegen): Be more careful to preserve identity.
6 (pcase--u1): Don't forget to mark vars as used.
7
8 * emacs-lisp/bytecomp.el (byte-compile-constp): Treat #'v as a constant.
9 (byte-compile-close-variables): Bind byte-compile--outbuffer here...
10 (byte-compile-from-buffer): ...rather than here.
11
12 * emacs-lisp/byte-opt.el (byte-compile-inline-expand): Don't re-preprocess
13 functions from byte-compile-function-environment.
14
12012-05-29 Troels Nielsen <bn.troels@gmail.com> 152012-05-29 Troels Nielsen <bn.troels@gmail.com>
2 16
3 * window.el (window-deletable-p): Avoid deleting the root window 17 * window.el (window-deletable-p): Avoid deleting the root window
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 3b324a09659..9dd475f2a51 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -288,10 +288,14 @@
288 (push `(,(car binding) ',(cdr binding)) renv))) 288 (push `(,(car binding) ',(cdr binding)) renv)))
289 ((eq binding t)) 289 ((eq binding t))
290 (t (push `(defvar ,binding) body)))) 290 (t (push `(defvar ,binding) body))))
291 (let ((newfn (byte-compile-preprocess 291 (let ((newfn (if (eq fn localfn)
292 (if (null renv) 292 ;; If `fn' is from the same file, it has already
293 `(lambda ,args ,@body) 293 ;; been preprocessed!
294 `(lambda ,args (let ,(nreverse renv) ,@body)))))) 294 `(function ,fn)
295 (byte-compile-preprocess
296 (if (null renv)
297 `(lambda ,args ,@body)
298 `(lambda ,args (let ,(nreverse renv) ,@body)))))))
295 (if (eq (car-safe newfn) 'function) 299 (if (eq (car-safe newfn) 'function)
296 (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) 300 (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form)))
297 (byte-compile-log-warning 301 (byte-compile-log-warning
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 91db288feef..2518d8359c3 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1478,40 +1478,46 @@ symbol itself."
1478 1478
1479(defmacro byte-compile-constp (form) 1479(defmacro byte-compile-constp (form)
1480 "Return non-nil if FORM is a constant." 1480 "Return non-nil if FORM is a constant."
1481 `(cond ((consp ,form) (eq (car ,form) 'quote)) 1481 `(cond ((consp ,form) (or (eq (car ,form) 'quote)
1482 (and (eq (car ,form) 'function)
1483 (symbolp (cadr ,form)))))
1482 ((not (symbolp ,form))) 1484 ((not (symbolp ,form)))
1483 ((byte-compile-const-symbol-p ,form)))) 1485 ((byte-compile-const-symbol-p ,form))))
1484 1486
1487;; Dynamically bound in byte-compile-from-buffer.
1488;; NB also used in cl.el and cl-macs.el.
1489(defvar byte-compile--outbuffer)
1490
1485(defmacro byte-compile-close-variables (&rest body) 1491(defmacro byte-compile-close-variables (&rest body)
1486 (declare (debug t)) 1492 (declare (debug t))
1487 (cons 'let 1493 `(let (;;
1488 (cons '(;; 1494 ;; Close over these variables to encapsulate the
1489 ;; Close over these variables to encapsulate the 1495 ;; compilation state
1490 ;; compilation state 1496 ;;
1491 ;; 1497 (byte-compile-macro-environment
1492 (byte-compile-macro-environment 1498 ;; Copy it because the compiler may patch into the
1493 ;; Copy it because the compiler may patch into the 1499 ;; macroenvironment.
1494 ;; macroenvironment. 1500 (copy-alist byte-compile-initial-macro-environment))
1495 (copy-alist byte-compile-initial-macro-environment)) 1501 (byte-compile--outbuffer nil)
1496 (byte-compile-function-environment nil) 1502 (byte-compile-function-environment nil)
1497 (byte-compile-bound-variables nil) 1503 (byte-compile-bound-variables nil)
1498 (byte-compile-const-variables nil) 1504 (byte-compile-const-variables nil)
1499 (byte-compile-free-references nil) 1505 (byte-compile-free-references nil)
1500 (byte-compile-free-assignments nil) 1506 (byte-compile-free-assignments nil)
1501 ;; 1507 ;;
1502 ;; Close over these variables so that `byte-compiler-options' 1508 ;; Close over these variables so that `byte-compiler-options'
1503 ;; can change them on a per-file basis. 1509 ;; can change them on a per-file basis.
1504 ;; 1510 ;;
1505 (byte-compile-verbose byte-compile-verbose) 1511 (byte-compile-verbose byte-compile-verbose)
1506 (byte-optimize byte-optimize) 1512 (byte-optimize byte-optimize)
1507 (byte-compile-dynamic byte-compile-dynamic) 1513 (byte-compile-dynamic byte-compile-dynamic)
1508 (byte-compile-dynamic-docstrings 1514 (byte-compile-dynamic-docstrings
1509 byte-compile-dynamic-docstrings) 1515 byte-compile-dynamic-docstrings)
1510;; (byte-compile-generate-emacs19-bytecodes 1516 ;; (byte-compile-generate-emacs19-bytecodes
1511;; byte-compile-generate-emacs19-bytecodes) 1517 ;; byte-compile-generate-emacs19-bytecodes)
1512 (byte-compile-warnings byte-compile-warnings) 1518 (byte-compile-warnings byte-compile-warnings)
1513 ) 1519 )
1514 body))) 1520 ,@body))
1515 1521
1516(defmacro displaying-byte-compile-warnings (&rest body) 1522(defmacro displaying-byte-compile-warnings (&rest body)
1517 (declare (debug t)) 1523 (declare (debug t))
@@ -1852,13 +1858,8 @@ With argument ARG, insert value in current buffer after the form."
1852 (insert "\n")) 1858 (insert "\n"))
1853 ((message "%s" (prin1-to-string value))))))) 1859 ((message "%s" (prin1-to-string value)))))))
1854 1860
1855;; Dynamically bound in byte-compile-from-buffer.
1856;; NB also used in cl.el and cl-macs.el.
1857(defvar byte-compile--outbuffer)
1858
1859(defun byte-compile-from-buffer (inbuffer) 1861(defun byte-compile-from-buffer (inbuffer)
1860 (let (byte-compile--outbuffer 1862 (let ((byte-compile-current-buffer inbuffer)
1861 (byte-compile-current-buffer inbuffer)
1862 (byte-compile-read-position nil) 1863 (byte-compile-read-position nil)
1863 (byte-compile-last-position nil) 1864 (byte-compile-last-position nil)
1864 ;; Prevent truncation of flonums and lists as we read and print them 1865 ;; Prevent truncation of flonums and lists as we read and print them
@@ -1930,8 +1931,8 @@ and will be removed soon. See (elisp)Backquote in the manual."))
1930 ;; if the buffer contains multibyte characters. 1931 ;; if the buffer contains multibyte characters.
1931 (and byte-compile-current-file 1932 (and byte-compile-current-file
1932 (with-current-buffer byte-compile--outbuffer 1933 (with-current-buffer byte-compile--outbuffer
1933 (byte-compile-fix-header byte-compile-current-file))))) 1934 (byte-compile-fix-header byte-compile-current-file))))
1934 byte-compile--outbuffer)) 1935 byte-compile--outbuffer)))
1935 1936
1936(defun byte-compile-fix-header (filename) 1937(defun byte-compile-fix-header (filename)
1937 "If the current buffer has any multibyte characters, insert a version test." 1938 "If the current buffer has any multibyte characters, insert a version test."
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 363c0965c3e..9f98b30adae 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -206,9 +206,12 @@ of the form (UPAT EXP)."
206 (setq vars (delq v vars)) 206 (setq vars (delq v vars))
207 (cdr v))) 207 (cdr v)))
208 prevvars))) 208 prevvars)))
209 (when vars ;New additional vars. 209 ;; If some of `vars' were not found in `prevvars', that's
210 (error "The vars %s are only bound in some paths" 210 ;; OK it just means those vars aren't present in all
211 (mapcar #'car vars))) 211 ;; branches, so they can be used within the pattern
212 ;; (e.g. by a `guard/let/pred') but not in the branch.
213 ;; FIXME: But if some of `prevvars' are not in `vars' we
214 ;; should remove them from `prevvars'!
212 `(funcall ,res ,@args))))))) 215 `(funcall ,res ,@args)))))))
213 (main 216 (main
214 (pcase--u 217 (pcase--u
@@ -225,7 +228,10 @@ of the form (UPAT EXP)."
225 (pcase--let* defs main)))) 228 (pcase--let* defs main))))
226 229
227(defun pcase-codegen (code vars) 230(defun pcase-codegen (code vars)
228 `(let* ,(mapcar (lambda (b) (list (car b) (cdr b))) vars) 231 ;; Don't use let*, otherwise pcase--let* may merge it with some surrounding
232 ;; let* which might prevent the setcar/setcdr in pcase--expand's fancy
233 ;; codegen from later metamorphosing this let into a funcall.
234 `(let ,(mapcar (lambda (b) (list (car b) (cdr b))) vars)
229 ,@code)) 235 ,@code))
230 236
231(defun pcase--small-branch-p (code) 237(defun pcase--small-branch-p (code)
@@ -619,6 +625,7 @@ Otherwise, it defers to REST which is a list of branches of the form
619 sym (apply-partially #'pcase--split-member elems) rest)) 625 sym (apply-partially #'pcase--split-member elems) rest))
620 (then-rest (car splitrest)) 626 (then-rest (car splitrest))
621 (else-rest (cdr splitrest))) 627 (else-rest (cdr splitrest)))
628 (put sym 'pcase-used t)
622 (pcase--if `(,(if memq-fine #'memq #'member) ,sym ',elems) 629 (pcase--if `(,(if memq-fine #'memq #'member) ,sym ',elems)
623 (pcase--u1 matches code vars then-rest) 630 (pcase--u1 matches code vars then-rest)
624 (pcase--u else-rest))) 631 (pcase--u else-rest)))