summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2023-06-24 17:53:41 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2023-06-24 17:53:41 -0400
commite85ebb3d82466c5838e9c6836e6d8b5c8d0a7c33 (patch)
tree8c2f375400a73620d77cedeaa87a80299d66afd3 /lisp/emacs-lisp/byte-opt.el
parentf559bd1248a265662665c462b750eb5fc64dd811 (diff)
downloademacs-e85ebb3d82466c5838e9c6836e6d8b5c8d0a7c33.tar.gz
emacs-e85ebb3d82466c5838e9c6836e6d8b5c8d0a7c33.tar.bz2
emacs-e85ebb3d82466c5838e9c6836e6d8b5c8d0a7c33.zip
(macroexp--unfold-lambda): Obey the lexbind semantics
While at it, rework the code so as not to rely on an intermediate rewriting of (funcall (lambda ..) ...) to ((lambda ..) ...) since that forms is deprecated. * lisp/emacs-lisp/byte-opt.el (byte-optimize-funcall): Unfold lambdas instead of turning them into the deprecated ((lambda ..) ..). (byte-optimize-form-code-walker): Don't unfold ((lambda ..) ..) any more. (byte-compile-inline-expand): Revert to non-optimized call if the unfolding can't be optimized. * lisp/emacs-lisp/bytecomp.el (byte-compile-form): Don't unfold ((lambda ..) ..) any more. * lisp/emacs-lisp/cl-macs.el (cl--slet): Remove workaround. * lisp/emacs-lisp/disass.el (disassemble): Make sure the code is compiled with its own `lexical-binding` value. * lisp/emacs-lisp/macroexp.el (macroexp--unfold-lambda): Make it work both for ((lambda ..) ..) and for (funcall #'(lambda ..) ..). Be careful not to move dynbound vars from `lambda` to `let`. (macroexp--expand-all): Unfold (funcall #'(lambda ..) ..) instead of turning it into ((lambda ..) ..). Don't unfold ((lambda ..) ..) any more.
Diffstat (limited to 'lisp/emacs-lisp/byte-opt.el')
-rw-r--r--lisp/emacs-lisp/byte-opt.el30
1 files changed, 13 insertions, 17 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 307e3841e9b..26a1dc4a103 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -167,8 +167,8 @@ Earlier variables shadow later ones with the same name.")
((or `(lambda . ,_) `(closure . ,_))
;; While byte-compile-unfold-bcf can inline dynbind byte-code into
;; letbind byte-code (or any other combination for that matter), we
- ;; can only inline dynbind source into dynbind source or letbind
- ;; source into letbind source.
+ ;; can only inline dynbind source into dynbind source or lexbind
+ ;; source into lexbind source.
;; When the function comes from another file, we byte-compile
;; the inlined function first, and then inline its byte-code.
;; This also has the advantage that the final code does not
@@ -176,7 +176,10 @@ Earlier variables shadow later ones with the same name.")
;; the build more reproducible.
(if (eq fn localfn)
;; From the same file => same mode.
- (macroexp--unfold-lambda `(,fn ,@(cdr form)))
+ (let* ((newform `(,fn ,@(cdr form)))
+ (unfolded (macroexp--unfold-lambda newform)))
+ ;; Use the newform only if it could be optimized.
+ (if (eq unfolded newform) form unfolded))
;; Since we are called from inside the optimizer, we need to make
;; sure not to propagate lexvar values.
(let ((byte-optimize--lexvars nil)
@@ -452,13 +455,6 @@ for speeding up processing.")
`(progn ,@(byte-optimize-body env t))
`(,fn ,vars ,(mapcar #'byte-optimize-form env) . ,rest)))
- (`((lambda . ,_) . ,_)
- (let ((newform (macroexp--unfold-lambda form)))
- (if (eq newform form)
- ;; Some error occurred, avoid infinite recursion.
- form
- (byte-optimize-form newform for-effect))))
-
(`(setq ,var ,expr)
(let ((lexvar (assq var byte-optimize--lexvars))
(value (byte-optimize-form expr nil)))
@@ -1412,15 +1408,15 @@ See Info node `(elisp) Integer Basics'."
(defun byte-optimize-funcall (form)
- ;; (funcall #'(lambda ...) ...) -> ((lambda ...) ...)
+ ;; (funcall #'(lambda ...) ...) -> (let ...)
;; (funcall #'SYM ...) -> (SYM ...)
;; (funcall 'SYM ...) -> (SYM ...)
- (let* ((fn (nth 1 form))
- (head (car-safe fn)))
- (if (or (eq head 'function)
- (and (eq head 'quote) (symbolp (nth 1 fn))))
- (cons (nth 1 fn) (cdr (cdr form)))
- form)))
+ (pcase form
+ (`(,_ #'(lambda . ,_) . ,_)
+ (macroexp--unfold-lambda form))
+ (`(,_ ,(or `#',f `',(and f (pred symbolp))) . ,actuals)
+ `(,f ,@actuals))
+ (_ form)))
(defun byte-optimize-apply (form)
(let ((len (length form)))