Function: byte-compile-make-closure
byte-compile-make-closure is a byte-compiled function defined in
bytecomp.el.gz.
Signature
(byte-compile-make-closure FORM)
Documentation
Byte-compile the special internal-make-closure form.
This function is never called when lexical-binding is nil.
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/bytecomp.el.gz
(defun byte-compile-make-closure (form)
"Byte-compile the special `internal-make-closure' form.
This function is never called when `lexical-binding' is nil."
(if byte-compile--for-effect (setq byte-compile--for-effect nil)
(let* ((vars (nth 1 form))
(env (nth 2 form))
(docstring-exp (nth 3 form))
(body (nthcdr 4 form))
(fun
(byte-compile-lambda `(lambda ,vars . ,body) nil (length env))))
(cl-assert (or (> (length env) 0)
docstring-exp)) ;Otherwise, we don't need a closure.
(cl-assert (byte-code-function-p fun))
(byte-compile-form
(if (macroexp-const-p docstring-exp)
;; Use symbols V0, V1 ... as placeholders for closure variables:
;; they should be short (to save space in the .elc file), yet
;; distinct when disassembled.
(let* ((dummy-vars (mapcar (lambda (i) (intern (format "V%d" i)))
(number-sequence 0 (1- (length env)))))
(opt-args (mapcar (lambda (i) (aref fun i))
(number-sequence 4 (1- (length fun)))))
(proto-fun
(apply #'make-byte-code
(aref fun 0) ; The arglist is always the 15-bit
; form, never the list of symbols.
(aref fun 1) ; The byte-code.
;; Prepend dummy cells to the constant vector,
;; to get the indices right when disassembling.
(vconcat dummy-vars (aref fun 2))
(aref fun 3) ; Stack depth of function
(if docstring-exp
(cons
(eval (byte-run-strip-symbol-positions
docstring-exp)
t)
(cdr opt-args)) ; The interactive spec will
; have been stripped in
; `byte-compile-lambda'.
opt-args))))
`(make-closure ,proto-fun ,@env))
;; Nontrivial doc string expression: create a bytecode object
;; from small pieces at run time.
`(make-byte-code
',(aref fun 0) ; 15-bit form of arglist descriptor.
',(aref fun 1) ; The byte-code.
(vconcat (vector . ,env) ',(aref fun 2)) ; constant vector.
,@(let ((rest (nthcdr 3 (mapcar (lambda (x) `',x) fun))))
(if docstring-exp
`(,(car rest)
,(byte-run-strip-symbol-positions docstring-exp)
,@(cddr rest))
rest))))
))))