aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/emacs-lisp/cconv.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/cconv.el')
-rw-r--r--lisp/emacs-lisp/cconv.el38
1 files changed, 22 insertions, 16 deletions
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 4ff47971351..e6a78f07762 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -902,7 +902,7 @@ lexically and dynamically bound symbols actually used by FORM."
902 (delete-dups cconv--dynbindings))))) 902 (delete-dups cconv--dynbindings)))))
903 (cons fvs dyns))))) 903 (cons fvs dyns)))))
904 904
905(defun cconv-make-interpreted-closure (fun env) 905(defun cconv-make-interpreted-closure (args body env docstring iform)
906 "Make a closure for the interpreter. 906 "Make a closure for the interpreter.
907This is intended to be called at runtime by the ELisp interpreter (when 907This is intended to be called at runtime by the ELisp interpreter (when
908the code has not been compiled). 908the code has not been compiled).
@@ -911,22 +911,27 @@ ENV is the runtime representation of the lexical environment,
911i.e. a list whose elements can be either plain symbols (which indicate 911i.e. a list whose elements can be either plain symbols (which indicate
912that this symbol should use dynamic scoping) or pairs (SYMBOL . VALUE) 912that this symbol should use dynamic scoping) or pairs (SYMBOL . VALUE)
913for the lexical bindings." 913for the lexical bindings."
914 (cl-assert (eq (car-safe fun) 'lambda)) 914 (cl-assert (consp body))
915 (cl-assert (listp args))
915 (let ((lexvars (delq nil (mapcar #'car-safe env)))) 916 (let ((lexvars (delq nil (mapcar #'car-safe env))))
916 (if (or (null lexvars) 917 (if (or
917 ;; Functions with a `:closure-dont-trim-context' marker 918 ;; Functions with a `:closure-dont-trim-context' marker
918 ;; should keep their whole context untrimmed (bug#59213). 919 ;; should keep their whole context untrimmed (bug#59213).
919 (and (eq :closure-dont-trim-context (nth 2 fun)) 920 (and (eq :closure-dont-trim-context (car body))
920 ;; Check the function doesn't just return the magic keyword. 921 ;; Check the function doesn't just return the magic keyword.
921 (nthcdr 3 fun))) 922 (cdr body)
923 ;; Drop the magic marker from the closure.
924 (setq body (cdr body)))
925 ;; There's no var to capture, so skip the analysis.
926 (null lexvars))
922 ;; The lexical environment is empty, or needs to be preserved, 927 ;; The lexical environment is empty, or needs to be preserved,
923 ;; so there's no need to look for free variables. 928 ;; so there's no need to look for free variables.
924 ;; Attempting to replace ,(cdr fun) by a macroexpanded version 929 ;; Attempting to replace body by a macroexpanded version
925 ;; causes bootstrap to fail. 930 ;; caused bootstrap to fail.
926 `(closure ,env . ,(cdr fun)) 931 (make-interpreted-closure args body env docstring iform)
927 ;; We could try and cache the result of the macroexpansion and 932 ;; We could try and cache the result of the macroexpansion and
928 ;; `cconv-fv' analysis. Not sure it's worth the trouble. 933 ;; `cconv-fv' analysis. Not sure it's worth the trouble.
929 (let* ((form `#',fun) 934 (let* ((form `#'(lambda ,args ,iform . ,body))
930 (expanded-form 935 (expanded-form
931 (let ((lexical-binding t) ;; Tell macros which dialect is in use. 936 (let ((lexical-binding t) ;; Tell macros which dialect is in use.
932 ;; Make the macro aware of any defvar declarations in scope. 937 ;; Make the macro aware of any defvar declarations in scope.
@@ -935,10 +940,10 @@ for the lexical bindings."
935 (append env macroexp--dynvars) env))) 940 (append env macroexp--dynvars) env)))
936 (macroexpand-all form macroexpand-all-environment))) 941 (macroexpand-all form macroexpand-all-environment)))
937 ;; Since we macroexpanded the body, we may as well use that. 942 ;; Since we macroexpanded the body, we may as well use that.
938 (expanded-fun-cdr 943 (expanded-fun-body
939 (pcase expanded-form 944 (pcase expanded-form
940 (`#'(lambda . ,cdr) cdr) 945 (`#'(lambda ,_args ,_iform . ,newbody) newbody)
941 (_ (cdr fun)))) 946 (_ body)))
942 947
943 (dynvars (delq nil (mapcar (lambda (b) (if (symbolp b) b)) env))) 948 (dynvars (delq nil (mapcar (lambda (b) (if (symbolp b) b)) env)))
944 (fvs (cconv-fv expanded-form lexvars dynvars)) 949 (fvs (cconv-fv expanded-form lexvars dynvars))
@@ -946,7 +951,8 @@ for the lexical bindings."
946 (cdr fvs)))) 951 (cdr fvs))))
947 ;; Never return a nil env, since nil means to use the dynbind 952 ;; Never return a nil env, since nil means to use the dynbind
948 ;; dialect of ELisp. 953 ;; dialect of ELisp.
949 `(closure ,(or newenv '(t)) . ,expanded-fun-cdr))))) 954 (make-interpreted-closure args expanded-fun-body (or newenv '(t))
955 docstring iform)))))
950 956
951 957
952(provide 'cconv) 958(provide 'cconv)