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))))
         ))))