mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
(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.
This commit is contained in:
parent
f559bd1248
commit
e85ebb3d82
5 changed files with 95 additions and 113 deletions
|
|
@ -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)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue