mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-04 11:23:24 +00:00
![]() Interpreted closures currently just grab a reference to the complete lexical environment, so (lambda (x) (+ x y)) can end up looking like (closure ((foo ...) (y 7) (bar ...) ...) (x) (+ x y)) where the foo/bar/... bindings are not only useless but can prevent the GC from collecting that memory (i.e. it's a representation that is not "safe for space") and it can also make that closure "unwritable" (or more specifically, it can cause the closure's print representation to be u`read`able). Compiled closures don't suffer from this problem because `cconv.el` actually looks at the code and only stores in the compiled closure those variables which are actually used. So, we fix this discrepancy by letting the existing code in `cconv.el` tell `Ffunction` which variables are actually used by the body of the function such that it can filter out the irrelevant elements and return a closure of the form: (closure ((y 7)) (x) (+ x y)) * lisp/loadup.el: Preload `cconv` and set `internal-filter-closure-env-function` once we have a usable `cconv-fv`. * lisp/emacs-lisp/bytecomp.el (byte-compile-preprocess): Adjust to new calling convention of `cconv-closure-convert`. (byte-compile-not-lexical-var-p): Delete function, moved to `cconv.el`. (byte-compile-bind): Use `cconv--not-lexical-var-p`. * lisp/emacs-lisp/cconv.el (cconv--dynbound-variables): New var. (cconv-closure-convert): New arg `dynbound-vars` (cconv--warn-unused-msg): Remove special case for `ignored`, so we don't get confused when a function uses an argument called `ignored`, e.g. holding a list of things that it should ignore. (cconv--not-lexical-var-p): New function, moved from `bytecomp.el`. Don't special case keywords and `nil` and `t` since they are already `special-variable-p`. (cconv--analyze-function): Use `cconv--not-lexical-var-p`. (cconv--dynbindings): New dynbound var. (cconv-analyze-form): Use `cconv--not-lexical-var-p`. Remember in `cconv--dynbindings` the vars for which we used dynamic scoping. (cconv-analyze-form): Use `cconv--dynbound-variables` rather than `byte-compile-bound-variables`. (cconv-fv): New function. * src/eval.c (Fsetq, eval_sub): Remove optimization designed when `lexical-binding == nil` was the common case. (Ffunction): Use `internal-filter-closure-env-function` when available. (eval_sub, Ffuncall): Improve error info for `excessive_lisp_nesting`. (internal-filter-closure-env-function): New defvar. |
||
---|---|---|
.. | ||
advice.el | ||
avl-tree.el | ||
backquote.el | ||
backtrace.el | ||
benchmark.el | ||
bindat.el | ||
byte-opt.el | ||
byte-run.el | ||
bytecomp.el | ||
cconv.el | ||
chart.el | ||
check-declare.el | ||
checkdoc.el | ||
cl-extra.el | ||
cl-generic.el | ||
cl-indent.el | ||
cl-lib.el | ||
cl-macs.el | ||
cl-preloaded.el | ||
cl-print.el | ||
cl-seq.el | ||
comp-cstr.el | ||
comp.el | ||
copyright.el | ||
crm.el | ||
cursor-sensor.el | ||
debug-early.el | ||
debug.el | ||
derived.el | ||
disass.el | ||
easy-mmode.el | ||
easymenu.el | ||
edebug.el | ||
eieio-base.el | ||
eieio-core.el | ||
eieio-custom.el | ||
eieio-datadebug.el | ||
eieio-opt.el | ||
eieio-speedbar.el | ||
eieio.el | ||
eldoc.el | ||
elint.el | ||
elp.el | ||
ert-x.el | ||
ert.el | ||
ewoc.el | ||
faceup.el | ||
find-func.el | ||
float-sup.el | ||
generate-lisp-file.el | ||
generator.el | ||
generic.el | ||
gv.el | ||
helper.el | ||
hierarchy.el | ||
icons.el | ||
inline.el | ||
let-alist.el | ||
lisp-mnt.el | ||
lisp-mode.el | ||
lisp.el | ||
loaddefs-gen.el | ||
macroexp.el | ||
map-ynp.el | ||
map.el | ||
memory-report.el | ||
multisession.el | ||
nadvice.el | ||
oclosure.el | ||
package-x.el | ||
package.el | ||
pcase.el | ||
pp.el | ||
radix-tree.el | ||
range.el | ||
re-builder.el | ||
regexp-opt.el | ||
regi.el | ||
ring.el | ||
rmc.el | ||
rx.el | ||
seq.el | ||
shadow.el | ||
shortdoc.el | ||
shorthands.el | ||
smie.el | ||
subr-x.el | ||
syntax.el | ||
tabulated-list.el | ||
tcover-ses.el | ||
testcover.el | ||
text-property-search.el | ||
thunk.el | ||
timer-list.el | ||
timer.el | ||
tq.el | ||
trace.el | ||
unsafep.el | ||
vtable.el | ||
warnings.el |