Function: byte-compile-lambda

byte-compile-lambda is a byte-compiled function defined in bytecomp.el.gz.

Signature

(byte-compile-lambda FUN &optional ADD-LAMBDA RESERVED-CSTS)

Documentation

Byte-compile a lambda-expression and return a valid function.

The value is usually a compiled function but may be the original lambda-expression. When ADD-LAMBDA is non-nil, the symbol lambda is added as head of the list FUN and byte-compile-set-symbol-position is not called. Use this feature to avoid calling byte-compile-set-symbol-position for symbols generated by the byte compiler itself.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/bytecomp.el.gz
(defun byte-compile-lambda (fun &optional add-lambda reserved-csts)
  "Byte-compile a lambda-expression and return a valid function.
The value is usually a compiled function but may be the original
lambda-expression.
When ADD-LAMBDA is non-nil, the symbol `lambda' is added as head
of the list FUN and `byte-compile-set-symbol-position' is not called.
Use this feature to avoid calling `byte-compile-set-symbol-position'
for symbols generated by the byte compiler itself."
  (if add-lambda
      (setq fun (cons 'lambda fun))
    (unless (eq 'lambda (car-safe fun))
      (error "Not a lambda list: %S" fun))
    (byte-compile-set-symbol-position 'lambda))
  (byte-compile-docstring-length-warn fun)
  (byte-compile-check-lambda-list (nth 1 fun))
  (let* ((arglist (nth 1 fun))
         (arglistvars (byte-compile-arglist-vars arglist))
	 (byte-compile-bound-variables
	  (append (if (not lexical-binding) arglistvars)
                  byte-compile-bound-variables))
	 (body (cdr (cdr fun)))
	 (doc (if (stringp (car body))
                  (prog1 (car body)
                    ;; Discard the doc string
                    ;; unless it is the last element of the body.
                    (if (cdr body)
                        (setq body (cdr body))))))
	 (int (assq 'interactive body))
         command-modes)
    (when lexical-binding
      (dolist (var arglistvars)
        (when (assq var byte-compile--known-dynamic-vars)
          (byte-compile--warn-lexical-dynamic var 'lambda))))
    ;; Process the interactive spec.
    (when int
      (byte-compile-set-symbol-position 'interactive)
      ;; Skip (interactive) if it is in front (the most usual location).
      (if (eq int (car body))
	  (setq body (cdr body)))
      (cond ((consp (cdr int))       ; There is an `interactive' spec.
             ;; Check that the bit after the `interactive' spec is
             ;; just a list of symbols (i.e., modes).
	     (unless (seq-every-p #'symbolp (cdr (cdr int)))
	       (byte-compile-warn "malformed interactive specc: %s"
				  (prin1-to-string int)))
             (setq command-modes (cdr (cdr int)))
	     ;; If the interactive spec is a call to `list', don't
	     ;; compile it, because `call-interactively' looks at the
	     ;; args of `list'.  Actually, compile it to get warnings,
	     ;; but don't use the result.
	     (let* ((form (nth 1 int))
                    (newform (byte-compile-top-level form)))
	       (while (memq (car-safe form) '(let let* progn save-excursion))
		 (while (consp (cdr form))
		   (setq form (cdr form)))
		 (setq form (car form)))
	       (when (or (not (eq (car-safe form) 'list))
                         ;; For code using lexical-binding, form is not
                         ;; valid lisp, but rather an intermediate form
                         ;; which may include "calls" to
                         ;; internal-make-closure (Bug#29988).
                         lexical-binding)
                 (setq int `(interactive ,newform)))))
            ((cdr int)                  ; Invalid (interactive . something).
	     (byte-compile-warn "malformed interactive spec: %s"
				(prin1-to-string int)))))
    ;; Process the body.
    (let ((compiled
           (byte-compile-top-level (cons 'progn body) nil 'lambda
                                   ;; If doing lexical binding, push a new
                                   ;; lexical environment containing just the
                                   ;; args (since lambda expressions should be
                                   ;; closed by now).
                                   (and lexical-binding
                                        (byte-compile-make-lambda-lexenv
                                         arglistvars))
                                   reserved-csts)))
      ;; Build the actual byte-coded function.
      (cl-assert (eq 'byte-code (car-safe compiled)))
      (let ((out
	     (apply #'make-byte-code
		    (if lexical-binding
			(byte-compile-make-args-desc arglist)
		      arglist)
		    (append
		     ;; byte-string, constants-vector, stack depth
		     (cdr compiled)
		     ;; optionally, the doc string.
		     (cond ((and lexical-binding arglist)
			    ;; byte-compile-make-args-desc lost the args's names,
			    ;; so preserve them in the docstring.
			    (list (help-add-fundoc-usage doc arglist)))
			   ((or doc int)
			    (list doc)))
		     ;; optionally, the interactive spec (and the modes the
		     ;; command applies to).
		     (cond
		      ;; We have some command modes, so use the vector form.
		      (command-modes
                       (list (vector (nth 1 int) command-modes)))
		      ;; No command modes, use the simple form with just the
		      ;; interactive spec.
		      (int
                       (list (nth 1 int))))))))
	(when byte-native-compiling
          (setf (byte-to-native-lambda-byte-func
                 (gethash (cadr compiled)
                          byte-to-native-lambdas-h))
                out))
	out))))