diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2023-06-24 17:53:41 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2023-06-24 17:53:41 -0400 |
commit | e85ebb3d82466c5838e9c6836e6d8b5c8d0a7c33 (patch) | |
tree | 8c2f375400a73620d77cedeaa87a80299d66afd3 /lisp/emacs-lisp/byte-opt.el | |
parent | f559bd1248a265662665c462b750eb5fc64dd811 (diff) | |
download | emacs-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.el | 30 |
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))) |