Function: cconv--convert-function

cconv--convert-function is a byte-compiled function defined in cconv.el.gz.

Signature

(cconv--convert-function ARGS BODY ENV PARENTFORM &optional DOCSTRING)

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/cconv.el.gz
(defun cconv--convert-function (args body env parentform &optional docstring)
  (cl-assert (equal body (caar cconv-freevars-alist)))
  (let* ((fvs (cdr (pop cconv-freevars-alist)))
         (body-new '())
         (envector ())
         (i 0)
         (new-env ()))
    ;; Build the "formal and actual envs" for the closure-converted function.
    ;; Hack for OClosure: `nreverse' here intends to put the captured vars
    ;; in the closure such that the first one is the one that is bound
    ;; most closely.
    (dolist (fv (nreverse fvs))
      (let ((exp (or (cdr (assq fv env)) fv)))
        (pcase exp
          ;; If `fv' is a variable that's wrapped in a cons-cell,
          ;; we want to put the cons-cell itself in the closure,
          ;; rather than just a copy of its current content.
          (`(car-safe ,iexp . ,_)
           (push iexp envector)
           (push `(,fv . (car-safe (internal-get-closed-var ,i))) new-env))
          (_
           (push exp envector)
           (push `(,fv . (internal-get-closed-var ,i)) new-env))))
      (setq i (1+ i)))
    (setq envector (nreverse envector))
    (setq new-env (nreverse new-env))

    (setq body-new (cconv--convert-funcbody
                     args body new-env parentform))
    (cond
     ((not (or envector docstring))     ;If no freevars - do nothing.
      `(function (lambda ,args . ,body-new)))
     (t
      `(internal-make-closure
        ,args ,envector ,docstring . ,body-new)))))