Commit 876c194c authored by Stefan Monnier's avatar Stefan Monnier
Browse files

Get rid of funvec.

* lisp/emacs-lisp/bytecomp.el (byte-compile-lapcode): Handle new form of
`byte-constant'.
(byte-compile-close-variables, displaying-byte-compile-warnings):
Add edebug spec.
(byte-compile-toplevel-file-form): New fun, split out of
byte-compile-file-form.
(byte-compile-from-buffer): Use it to avoid applying cconv
multiple times.
(byte-compile): Only strip `function' if it's present.
(byte-compile-lambda): Add `reserved-csts' argument.
Use new lexenv arg of byte-compile-top-level.
(byte-compile-reserved-constants): New var.
(byte-compile-constants-vector): Obey it.
(byte-compile-constants-vector): Handle new `byte-constant' form.
(byte-compile-top-level): Add args `lexenv' and `reserved-csts'.
(byte-compile-form): Don't check callargs here.
(byte-compile-normal-call): Do it here instead.
(byte-compile-push-unknown-constant)
(byte-compile-resolve-unknown-constant): Remove, unused.
(byte-compile-make-closure): Use `make-byte-code' rather than `curry',
putting the environment into the "constant" pool.
(byte-compile-get-closed-var): Use special byte-constant.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Handle new
intermediate special form `internal-make-vector'.
(byte-optimize-lapcode): Handle new form of `byte-constant'.
* lisp/help-fns.el (describe-function-1): Don't handle funvecs.
* lisp/emacs-lisp/macroexp.el (macroexpand-all-1): Only convert quote to
function if the content is a lambda expression, not if it's a closure.
* emacs-lisp/eieio-come.el: Remove.
* lisp/emacs-lisp/eieio.el: Don't require eieio-comp.
(defmethod): Do a bit more work to find the body and wrap it into
a function before passing it to eieio-defmethod.
(eieio-defmethod): New arg `code' for it.
* lisp/emacs-lisp/debug.el (debugger-setup-buffer): Don't hide things in
debugger backtrace.
* lisp/emacs-lisp/cl-extra.el (cl-macroexpand-all): Use backquotes, and be
more careful when quoting a function value.
* lisp/emacs-lisp/cconv.el (cconv-freevars): Accept defvar/defconst.
(cconv-closure-convert-rec): Catch stray `internal-make-closure'.
* lisp/Makefile.in (COMPILE_FIRST): Compile pcase and cconv early.

* src/eval.c (Qcurry): Remove.
(funcall_funvec): Remove.
(funcall_lambda): Move new byte-code handling to reduce impact.
Treat all args as lexical in the case of lexbind.
(Fcurry): Remove.
* src/data.c (Qfunction_vector): Remove.
(Ffunvecp): Remove.
* src/lread.c (read1): Revert to calling make_byte_code here.
(read_vector): Don't call make_byte_code any more.
* src/lisp.h (enum pvec_type): Rename back to PVEC_COMPILED.
(XSETCOMPILED): Rename back from XSETFUNVEC.
(FUNVEC_SIZE): Remove.
(FUNVEC_COMPILED_TAG_P, FUNVEC_COMPILED_P): Remove.
(COMPILEDP): Rename back from FUNVECP.
* src/fns.c (Felt): Remove unexplained FUNVEC check.
* src/doc.c (Fdocumentation): Don't handle funvec.
* src/alloc.c (make_funvec, Ffunvec): Remove.
* doc/lispref/vol2.texi (Top):
* doc/lispref/vol1.texi (Top):
* doc/lispref/objects.texi (Programming Types, Funvec Type, Type Predicates):
* doc/lispref/functions.texi (Functions, What Is a Function, FunctionCurrying):
* doc/lispref/elisp.texi (Top): Remove mentions of funvec and curry.
parent cb9336bd
((nil . ((tab-width . 8)
(sentence-end-double-space . t)
(fill-column . 70)))
(fill-column . 79)))
(c-mode . ((c-file-style . "GNU")))
;; You must set bugtracker_debbugs_url in your bazaar.conf for this to work.
;; See admin/notes/bugtracker.
......
2011-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
* vol2.texi (Top):
* vol1.texi (Top):
* objects.texi (Programming Types, Funvec Type, Type Predicates):
* functions.texi (Functions, What Is a Function, Function Currying):
* elisp.texi (Top): Remove mentions of funvec and curry.
2011-02-19 Eli Zaretskii <eliz@gnu.org>
* elisp.texi: Sync @dircategory with ../../info/dir.
......
......@@ -249,7 +249,7 @@ Programming Types
* Macro Type:: A method of expanding an expression into another
expression, more fundamental but less pretty.
* Primitive Function Type:: A function written in C, callable from Lisp.
* Funvec Type:: A vector type callable as a function.
* Byte-Code Type:: A function written in Lisp, then compiled.
* Autoload Type:: A type used for automatically loading seldom-used
functions.
......@@ -464,8 +464,6 @@ Functions
* Inline Functions:: Defining functions that the compiler
will open code.
* Declaring Functions:: Telling the compiler that a function is defined.
* Function Currying:: Making wrapper functions that pre-specify
some arguments.
* Function Safety:: Determining whether a function is safe to call.
* Related Topics:: Cross-references to specific Lisp primitives
that have a special bearing on how functions work.
......
......@@ -23,8 +23,6 @@ define them.
of a symbol.
* Obsolete Functions:: Declaring functions obsolete.
* Inline Functions:: Defining functions that the compiler will open code.
* Function Currying:: Making wrapper functions that pre-specify
some arguments.
* Declaring Functions:: Telling the compiler that a function is defined.
* Function Safety:: Determining whether a function is safe to call.
* Related Topics:: Cross-references to specific Lisp primitives
......@@ -113,25 +111,7 @@ editors; for Lisp programs, the distinction is normally unimportant.
@item byte-code function
A @dfn{byte-code function} is a function that has been compiled by the
byte compiler. A byte-code function is actually a special case of a
@dfn{funvec} object (see below).
@item function vector
A @dfn{function vector}, or @dfn{funvec} is a vector-like object whose
purpose is to define special kinds of functions. @xref{Funvec Type}.
The exact meaning of the vector elements is determined by the type of
funvec: the most common use is byte-code functions, which have a
list---the argument list---as the first element. Further types of
funvec object are:
@table @code
@item curry
A curried function. Remaining arguments in the funvec are function to
call, and arguments to prepend to user arguments at the time of the
call; @xref{Function Currying}.
@end table
byte compiler. @xref{Byte-Code Type}.
@end table
@defun functionp object
......@@ -172,11 +152,6 @@ function. For example:
@end example
@end defun
@defun funvecp object
@code{funvecp} returns @code{t} if @var{object} is a function vector
object (including byte-code objects), and @code{nil} otherwise.
@end defun
@defun subr-arity subr
This function provides information about the argument list of a
primitive, @var{subr}. The returned value is a pair
......@@ -1302,49 +1277,6 @@ do for macros. (@xref{Argument Evaluation}.)
Inline functions can be used and open-coded later on in the same file,
following the definition, just like macros.
@node Function Currying
@section Function Currying
@cindex function currying
@cindex currying
@cindex partial-application
Function currying is a way to make a new function that calls an
existing function with a partially pre-determined argument list.
@defun curry function &rest args
Return a function-like object that will append any arguments it is
called with to @var{args}, and call @var{function} with the resulting
list of arguments.
For example, @code{(curry 'concat "The ")} returns a function that
concatenates @code{"The "} and its arguments. Calling this function
on @code{"end"} returns @code{"The end"}:
@example
(funcall (curry 'concat "The ") "end")
@result{} "The end"
@end example
The @dfn{curried function} is useful as an argument to @code{mapcar}:
@example
(mapcar (curry 'concat "The ") '("big" "red" "balloon"))
@result{} ("The big" "The red" "The balloon")
@end example
@end defun
Function currying may be implemented in any Lisp by constructing a
@code{lambda} expression, for instance:
@example
(defun curry (function &rest args)
`(lambda (&rest call-args)
(apply #',function ,@@args call-args)))
@end example
However in Emacs Lisp, a special curried function object is used for
efficiency. @xref{Funvec Type}.
@node Declaring Functions
@section Telling the Compiler that a Function is Defined
@cindex function declaration
......
......@@ -156,7 +156,7 @@ latter are unique to Emacs Lisp.
* Macro Type:: A method of expanding an expression into another
expression, more fundamental but less pretty.
* Primitive Function Type:: A function written in C, callable from Lisp.
* Funvec Type:: A vector type callable as a function.
* Byte-Code Type:: A function written in Lisp, then compiled.
* Autoload Type:: A type used for automatically loading seldom-used
functions.
@end menu
......@@ -1313,55 +1313,18 @@ with the name of the subroutine.
@end group
@end example
@node Funvec Type
@subsection ``Function Vector' Type
@cindex function vector
@cindex funvec
@node Byte-Code Type
@subsection Byte-Code Function Type
A @dfn{function vector}, or @dfn{funvec} is a vector-like object whose
purpose is to define special kinds of functions. You can examine or
modify the contents of a funvec like a normal vector, using the
@code{aref} and @code{aset} functions.
The byte compiler produces @dfn{byte-code function objects}.
Internally, a byte-code function object is much like a vector; however,
the evaluator handles this data type specially when it appears as a
function to be called. @xref{Byte Compilation}, for information about
the byte compiler.
The behavior of a funvec when called is dependent on the kind of
funvec it is, and that is determined by its first element (a
zero-length funvec will signal an error if called):
@table @asis
@item A list
A funvec with a list as its first element is a byte-compiled function,
produced by the byte compiler; such funvecs are known as
@dfn{byte-code function objects}. @xref{Byte Compilation}, for
information about the byte compiler.
@item The symbol @code{curry}
A funvec with @code{curry} as its first element is a ``curried function''.
The second element in such a funvec is the function which is
being curried, and the remaining elements are a list of arguments.
Calling such a funvec operates by calling the embedded function with
an argument list composed of the arguments in the funvec followed by
the arguments the funvec was called with. @xref{Function Currying}.
@end table
The printed representation and read syntax for a funvec object is like
that for a vector, with an additional @samp{#} before the opening
@samp{[}.
@defun funvecp object
@code{funvecp} returns @code{t} if @var{object} is a function vector
object (including byte-code objects), and @code{nil} otherwise.
@end defun
@defun funvec kind &rest params
@code{funvec} returns a new function vector containing @var{kind} and
@var{params}. @var{kind} determines the type of funvec; it should be
one of the choices listed in the table above.
Typically you should use the @code{make-byte-code} function to create
byte-code objects, though they are a type of funvec.
@end defun
The printed representation and read syntax for a byte-code function
object is like that for a vector, with an additional @samp{#} before the
opening @samp{[}.
@node Autoload Type
@subsection Autoload Type
......@@ -1808,7 +1771,7 @@ with references to further information.
@xref{Buffer Basics, bufferp}.
@item byte-code-function-p
@xref{Funvec Type, byte-code-function-p}.
@xref{Byte-Code Type, byte-code-function-p}.
@item case-table-p
@xref{Case Tables, case-table-p}.
......
......@@ -269,7 +269,7 @@ Programming Types
* Macro Type:: A method of expanding an expression into another
expression, more fundamental but less pretty.
* Primitive Function Type:: A function written in C, callable from Lisp.
* Funvec Type:: A vector type callable as a function.
* Byte-Code Type:: A function written in Lisp, then compiled.
* Autoload Type:: A type used for automatically loading seldom-used
functions.
......
......@@ -268,7 +268,7 @@ Programming Types
* Macro Type:: A method of expanding an expression into another
expression, more fundamental but less pretty.
* Primitive Function Type:: A function written in C, callable from Lisp.
* Funvec Type:: A vector type callable as a function.
* Byte-Code Type:: A function written in Lisp, then compiled.
* Autoload Type:: A type used for automatically loading seldom-used
functions.
......
GNU Emacs NEWS -- history of user-visible changes.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2011
Free Software Foundation, Inc.
See the end of the file for license conditions.
......@@ -12,21 +12,12 @@ This file is about changes in the Emacs "lexbind" branch.
* Lisp changes in Emacs 23.1
** New `function vector' type, including function currying
The `function vector', or `funvec' type extends the old
byte-compiled-function vector type to have other uses as well, and
includes existing byte-compiled functions as a special case. The kind
of funvec is determined by the first element: a list is a byte-compiled
function, and a non-nil atom is one of the new extended uses, currently
`curry' for curried functions. See the node `Funvec Type' in the Emacs
Lisp Reference Manual for more information.
*** New function curry allows constructing `curried functions'
(see the node `Function Currying' in the Emacs Lisp Reference Manual).
*** New functions funvec and funvecp allow primitive access to funvecs
** The `lexical-binding' lets code use lexical scoping for local variables.
It is typically set via file-local variables, in which case it applies to
all the code in that file.
** Lexically scoped interpreted functions are represented with a new form
of function value which looks like (closure ENV lambda ARGS &rest BODY).
----------------------------------------------------------------------
This file is part of GNU Emacs.
......
2011-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
* emacs-lisp/bytecomp.el (byte-compile-lapcode): Handle new form of
`byte-constant'.
(byte-compile-close-variables, displaying-byte-compile-warnings):
Add edebug spec.
(byte-compile-toplevel-file-form): New fun, split out of
byte-compile-file-form.
(byte-compile-from-buffer): Use it to avoid applying cconv
multiple times.
(byte-compile): Only strip `function' if it's present.
(byte-compile-lambda): Add `reserved-csts' argument.
Use new lexenv arg of byte-compile-top-level.
(byte-compile-reserved-constants): New var.
(byte-compile-constants-vector): Obey it.
(byte-compile-constants-vector): Handle new `byte-constant' form.
(byte-compile-top-level): Add args `lexenv' and `reserved-csts'.
(byte-compile-form): Don't check callargs here.
(byte-compile-normal-call): Do it here instead.
(byte-compile-push-unknown-constant)
(byte-compile-resolve-unknown-constant): Remove, unused.
(byte-compile-make-closure): Use `make-byte-code' rather than `curry',
putting the environment into the "constant" pool.
(byte-compile-get-closed-var): Use special byte-constant.
* emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Handle new
intermediate special form `internal-make-vector'.
(byte-optimize-lapcode): Handle new form of `byte-constant'.
* help-fns.el (describe-function-1): Don't handle funvecs.
* emacs-lisp/macroexp.el (macroexpand-all-1): Only convert quote to
function if the content is a lambda expression, not if it's a closure.
* emacs-lisp/eieio-come.el: Remove.
* emacs-lisp/eieio.el: Don't require eieio-comp.
(defmethod): Do a bit more work to find the body and wrap it into
a function before passing it to eieio-defmethod.
(eieio-defmethod): New arg `code' for it.
* emacs-lisp/debug.el (debugger-setup-buffer): Don't hide things in
debugger backtrace.
* emacs-lisp/cl-extra.el (cl-macroexpand-all): Use backquotes, and be
more careful when quoting a function value.
* emacs-lisp/cconv.el (cconv-freevars): Accept defvar/defconst.
(cconv-closure-convert-rec): Catch stray `internal-make-closure'.
* Makefile.in (COMPILE_FIRST): Compile pcase and cconv early.
2011-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
* emacs-lisp/cconv.el (cconv-closure-convert-rec): Let the byte
......
......@@ -83,7 +83,9 @@ BIG_STACK_OPTS = --eval "(setq max-lisp-eval-depth $(BIG_STACK_DEPTH))"
COMPILE_FIRST = \
$(lisp)/emacs-lisp/bytecomp.elc \
$(lisp)/emacs-lisp/byte-opt.elc \
$(lisp)/emacs-lisp/pcase.elc \
$(lisp)/emacs-lisp/macroexp.elc \
$(lisp)/emacs-lisp/cconv.elc \
$(lisp)/emacs-lisp/autoload.elc
# The actual Emacs command run in the targets below.
......@@ -203,7 +205,7 @@ compile-onefile:
@echo Compiling $(THEFILE)
@# Use byte-compile-refresh-preloaded to try and work around some of
@# the most common bootstrapping problems.
@$(emacs) -l bytecomp.el -f byte-compile-refresh-preloaded \
$(emacs) -l bytecomp.el -f byte-compile-refresh-preloaded \
$(BIG_STACK_OPTS) $(BYTE_COMPILE_EXTRA_FLAGS) \
-f batch-byte-compile $(THEFILE)
......@@ -220,7 +222,7 @@ compile-onefile:
# cannot have prerequisites.
.el.elc:
@echo Compiling $<
@$(emacs) $(BIG_STACK_OPTS) $(BYTE_COMPILE_EXTRA_FLAGS) \
$(emacs) $(BIG_STACK_OPTS) $(BYTE_COMPILE_EXTRA_FLAGS) \
-f batch-byte-compile $<
.PHONY: compile-first compile-main compile compile-always
......
......@@ -531,7 +531,11 @@
;; However, don't actually bother calling `ignore'.
`(prog1 nil . ,(mapcar 'byte-optimize-form (cdr form))))
((eq fn 'internal-make-closure)
form)
((not (symbolp fn))
(debug)
(byte-compile-warn "`%s' is a malformed function"
(prin1-to-string fn))
form)
......@@ -1472,7 +1476,8 @@
byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max
byte-point-min byte-following-char byte-preceding-char
byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp
byte-current-buffer byte-stack-ref))
byte-current-buffer byte-stack-ref ;; byte-closed-var
))
(defconst byte-compile-side-effect-free-ops
(nconc
......@@ -1680,11 +1685,18 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
;; const goto-if-* --> whatever
;;
((and (eq 'byte-constant (car lap0))
(memq (car lap1) byte-conditional-ops))
(memq (car lap1) byte-conditional-ops)
;; If the `byte-constant's cdr is not a cons cell, it has
;; to be an index into the constant pool); even though
;; it'll be a constant, that constant is not known yet
;; (it's typically a free variable of a closure, so will
;; only be known when the closure will be built at
;; run-time).
(consp (cdr lap0)))
(cond ((if (or (eq (car lap1) 'byte-goto-if-nil)
(eq (car lap1) 'byte-goto-if-nil-else-pop))
(car (cdr lap0))
(not (car (cdr lap0))))
(eq (car lap1) 'byte-goto-if-nil-else-pop))
(car (cdr lap0))
(not (car (cdr lap0))))
(byte-compile-log-lap " %s %s\t-->\t<deleted>"
lap0 lap1)
(setq rest (cdr rest)
......@@ -1696,11 +1708,11 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
(when (memq (car lap1) byte-goto-always-pop-ops)
(setq lap (delq lap0 lap)))
(setcar lap1 'byte-goto)))
(setq keep-going t))
(setq keep-going t))
;;
;; varref-X varref-X --> varref-X dup
;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup
;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup
;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup
;; We don't optimize the const-X variations on this here,
;; because that would inhibit some goto optimizations; we
;; optimize the const-X case after all other optimizations.
......@@ -1877,18 +1889,21 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
(cons 'byte-discard byte-conditional-ops)))
(not (eq lap1 (car tmp))))
(setq tmp2 (car tmp))
(cond ((memq (car tmp2)
(if (null (car (cdr lap0)))
'(byte-goto-if-nil byte-goto-if-nil-else-pop)
'(byte-goto-if-not-nil
byte-goto-if-not-nil-else-pop)))
(cond ((when (consp (cdr lap0))
(memq (car tmp2)
(if (null (car (cdr lap0)))
'(byte-goto-if-nil byte-goto-if-nil-else-pop)
'(byte-goto-if-not-nil
byte-goto-if-not-nil-else-pop))))
(byte-compile-log-lap " %s goto [%s]\t-->\t%s %s"
lap0 tmp2 lap0 tmp2)
(setcar lap1 (car tmp2))
(setcdr lap1 (cdr tmp2))
;; Let next step fix the (const,goto-if*) sequence.
(setq rest (cons nil rest)))
(t
(setq rest (cons nil rest))
(setq keep-going t))
((or (consp (cdr lap0))
(eq (car tmp2) 'byte-discard))
;; Jump one step further
(byte-compile-log-lap
" %s goto [%s]\t-->\t<deleted> goto <skip>"
......@@ -1897,8 +1912,8 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
(setcdr tmp (cons (byte-compile-make-tag)
(cdr tmp))))
(setcdr lap1 (car (cdr tmp)))
(setq lap (delq lap0 lap))))
(setq keep-going t))
(setq lap (delq lap0 lap))
(setq keep-going t))))
;;
;; X: varref-Y ... varset-Y goto-X -->
;; X: varref-Y Z: ... dup varset-Y goto-Z
......
......@@ -794,10 +794,13 @@ CONST2 may be evaulated multiple times."
;; goto
(byte-compile-push-bytecodes opcode nil (cdr off) bytes pc)
(push bytes patchlist))
((and (consp off)
;; Variable or constant reference
(progn (setq off (cdr off))
(eq op 'byte-constant)))
((or (and (consp off)
;; Variable or constant reference
(progn
(setq off (cdr off))
(eq op 'byte-constant)))
(and (eq op 'byte-constant) ;; 'byte-closed-var
(integerp off)))
;; constant ref
(if (< off byte-constant-limit)
(byte-compile-push-bytecodes (+ byte-constant off)
......@@ -1480,6 +1483,7 @@ symbol itself."
((byte-compile-const-symbol-p ,form))))
(defmacro byte-compile-close-variables (&rest body)
(declare (debug t))
(cons 'let
(cons '(;;
;; Close over these variables to encapsulate the
......@@ -1510,6 +1514,7 @@ symbol itself."
body)))
(defmacro displaying-byte-compile-warnings (&rest body)
(declare (debug t))
`(let* ((--displaying-byte-compile-warnings-fn (lambda () ,@body))
(warning-series-started
(and (markerp warning-series)
......@@ -1930,7 +1935,7 @@ With argument ARG, insert value in current buffer after the form."
(byte-compile-warn "!! The file uses old-style backquotes !!
This functionality has been obsolete for more than 10 years already
and will be removed soon. See (elisp)Backquote in the manual."))
(byte-compile-file-form form)))
(byte-compile-toplevel-file-form form)))
;; Compile pending forms at end of file.
(byte-compile-flush-pending)
;; Make warnings about unresolved functions
......@@ -2041,8 +2046,8 @@ Call from the source buffer."
;; defalias calls are output directly by byte-compile-file-form-defmumble;
;; it does not pay to first build the defalias in defmumble and then parse
;; it here.
(if (and (memq (car-safe form) '(defun defmacro defvar defvaralias defconst autoload
custom-declare-variable))
(if (and (memq (car-safe form) '(defun defmacro defvar defvaralias defconst
autoload custom-declare-variable))
(stringp (nth 3 form)))
(byte-compile-output-docform nil nil '("\n(" 3 ")") form nil
(memq (car form)
......@@ -2182,12 +2187,17 @@ list that represents a doc string reference.
byte-compile-maxdepth 0
byte-compile-output nil))))
(defun byte-compile-file-form (form)
(let ((byte-compile-current-form nil) ; close over this for warnings.
bytecomp-handler)
;; byte-hunk-handlers cannot call this!
(defun byte-compile-toplevel-file-form (form)
(let ((byte-compile-current-form nil)) ; close over this for warnings.
(setq form (macroexpand-all form byte-compile-macro-environment))
(if lexical-binding
(setq form (cconv-closure-convert form)))
(byte-compile-file-form form)))
;; byte-hunk-handlers can call this.
(defun byte-compile-file-form (form)
(let (bytecomp-handler)
(cond ((not (consp form))
(byte-compile-keep-pending form))
((and (symbolp (car form))
......@@ -2541,7 +2551,7 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(if lexical-binding
(setq fun (cconv-closure-convert fun)))
;; Get rid of the `function' quote added by the `lambda' macro.
(setq fun (cadr fun))
(if (eq (car-safe fun) 'function) (setq fun (cadr fun)))
(setq fun (if macro
(cons 'macro (byte-compile-lambda fun))
(byte-compile-lambda fun)))
......@@ -2654,7 +2664,7 @@ If FORM is a lambda or a macro, byte-compile it as a function."
;; 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.
(defun byte-compile-lambda (bytecomp-fun &optional add-lambda)
(defun byte-compile-lambda (bytecomp-fun &optional add-lambda reserved-csts)
(if add-lambda
(setq bytecomp-fun (cons 'lambda bytecomp-fun))
(unless (eq 'lambda (car-safe bytecomp-fun))
......@@ -2702,14 +2712,16 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(byte-compile-warn "malformed interactive spec: %s"
(prin1-to-string bytecomp-int)))))
;; Process the body.
(let* ((byte-compile-lexical-environment
;; 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 bytecomp-fun)))
(compiled
(byte-compile-top-level (cons 'progn bytecomp-body) nil 'lambda)))
(let* ((compiled
(byte-compile-top-level (cons 'progn bytecomp-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
bytecomp-fun))
reserved-csts)))
;; Build the actual byte-coded function.
(if (eq 'byte-code (car-safe compiled))
(apply 'make-byte-code
......@@ -2740,6 +2752,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
;; A simple lambda is just a constant.
(byte-compile-constant code)))
(defvar byte-compile-reserved-constants 0)
(defun byte-compile-constants-vector ()
;; Builds the constants-vector from the current variables and constants.
;; This modifies the constants from (const . nil) to (const . offset).
......@@ -2748,7 +2762,7 @@ If FORM is a lambda or a macro, byte-compile it as a function."
;; Next up to byte-constant-limit are constants, still with one-byte codes.
;; Next variables again, to get 2-byte codes for variable lookup.
;; The rest of the constants and variables need 3-byte byte-codes.
(let* ((i -1)
(let* ((i (1- byte-compile-reserved-constants))
(rest (nreverse byte-compile-variables)) ; nreverse because the first
(other (nreverse byte-compile-constants)) ; vars often are used most.
ret tmp
......@@ -2759,11 +2773,15 @@ If FORM is a lambda or a macro, byte-compile it as a function."
limit)
(while (or rest other)
(setq limit (car limits))
(while (and rest (not (eq i limit)))
(if (setq tmp (assq (car (car rest)) ret))
(setcdr (car rest) (cdr tmp))
(while (and rest (< i limit))
(cond
((numberp (car rest))
(assert (< (car rest) byte-compile-reserved-constants)))
((setq tmp (assq (car (car rest)) ret))
(setcdr (car rest) (cdr tmp)))
(t
(setcdr (car rest) (setq i (1+ i)))
(setq ret (cons (car rest) ret)))
(setq ret (cons (car rest) ret))))
(setq rest (cdr rest)))
(setq limits (cdr limits)
rest (prog1 other
......@@ -2772,7 +2790,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
;; Given an expression FORM, compile it and return an equivalent byte-code
;; expression (a call to the function byte-code).
(defun byte-compile-top-level (form &optional for-effect output-type)
(defun byte-compile-top-level (form &optional for-effect output-type
lexenv reserved-csts)
;; OUTPUT-TYPE advises about how form is expected to be used:
;; 'eval or nil -> a single form,
;; 'progn or t -> a list of forms,
......@@ -2783,9 +2802,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(byte-compile-tag-number 0)
(byte-compile-depth 0)
(byte-compile-maxdepth 0)
(byte-compile-lexical-environment
(when (eq output-type 'lambda)
byte-compile-lexical-environment))
(byte-compile-lexical-environment lexenv)
(byte-compile-reserved-constants (or reserved-csts 0))
(byte-compile-output nil))
(if (memq byte-optimize '(t source))
(setq form (byte-optimize-form form for-effect)))
......@@ -2904,6 +2922,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(bytecomp-body
(list bytecomp-body))))
;; FIXME: Like defsubst's, this hunk-handler won't be called any more
;; because the macro is expanded away before we see it.