aboutsummaryrefslogtreecommitdiffstats
path: root/doc/lispref/compile.texi
diff options
context:
space:
mode:
authorStefan Monnier2024-03-11 16:12:26 -0400
committerStefan Monnier2024-04-18 15:28:36 -0400
commit126be02077520a943252d0d219bb7677466d0168 (patch)
treef762237714f11b303c708f93f09a8dc72426bb2a /doc/lispref/compile.texi
parent7842af6095db4384898725fb4a14ebaa11379a34 (diff)
downloademacs-scratch/interpreted-function.tar.gz
emacs-scratch/interpreted-function.zip
Use a dedicated type to represent interpreted-function valuesscratch/interpreted-function
Change `function` so that when evaluating #'(lambda ...) we return an object of type `interpreted-function` rather than a list starting with one of `lambda` or `closure`. The new type reuses the existing PVEC_CLOSURE (nee PVEC_COMPILED) tag and tries to align the corresponding elements: - the arglist, the docstring, and the interactive-form go in the same slots as for byte-code functions. - the body of the function goes in the slot used for the bytecode string. - the lexical context goes in the slot used for the constants of bytecoded functions. The first point above means that `help-function-arglist`, `documentation`, and `interactive-form`s don't need to distinguish interpreted and bytecode functions any more. Main benefits of the change: - We can now reliably distinguish a list from a function value. - `cl-defmethod` can dispatch on `interactive-function` and `closure`. Dispatch on `function` also works now for interpreted functions but still won't work for functions represented as lists or as symbols, of course. - Function values are now self-evaluating. That was alrready the case when byte-compiled, but not when interpreted since (eval '(closure ...)) signals a void-function error. That also avoids false-positive warnings about "don't quote your lambdas" when doing things like `(mapcar ',func ...)`. * src/eval.c (Fmake_interpreted_closure): New function. (Ffunction): Use it and change calling convention of `Vinternal_make_interpreted_closure_function`. (FUNCTIONP, Fcommandp, eval_sub, funcall_general, funcall_lambda) (Ffunc_arity, lambda_arity): Simplify. (funcall_lambda): Adjust to new representation. (syms_of_eval): `defsubr` the new function. Remove definition of `Qclosure`. * lisp/emacs-lisp/cconv.el (cconv-make-interpreted-closure): Change calling convention and use `make-interpreted-closure`. * src/data.c (Fcl_type_of): Distinguish `byte-code-function`s from `interpreted-function`s. (Fclosurep, finterpreted_function_p): New functions. (Fbyte_code_function_p): Don't be confused by `interpreted-function`s. (Finteractive_form, Fcommand_modes): Simplify. (syms_of_data): Define new type symbols and `defsubr` the two new functions. * lisp/emacs-lisp/cl-print.el (cl-print-object) <interpreted-function>: New method. * lisp/emacs-lisp/oclosure.el (oclosure): Refine the parent to be `closure`. (oclosure--fix-type, oclosure-type): Simplify. (oclosure--copy, oclosure--get, oclosure--set): Adjust to new representation. * src/callint.c (Fcall_interactively): Adjust to new representation. * src/lread.c (bytecode_from_rev_list): * lisp/simple.el (function-documentation): * lisp/help.el (help-function-arglist): Remove the old `closure` case and adjust the byte-code case so it handles `interpreted-function`s. * lisp/emacs-lisp/cl-preloaded.el (closure): New type. (byte-code-function): Add it as a parent. (interpreted-function): Adjust parent (the type itself was already added earlier by accident). * lisp/emacs-lisp/bytecomp.el (byte-compile--reify-function): Adjust to new representation. (byte-compile): Use `interpreted-function-p`. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Adjust to new representation. (side-effect-free-fns): Add `interpreted-function-p` and `closurep`. * src/profiler.c (trace_hash, ffunction_equal): Simplify. * lisp/profiler.el (profiler-function-equal): Simplify. * lisp/emacs-lisp/nadvice.el (advice--interactive-form-1): Use `interpreted-function-p`; adjust to new representation; and take advantage of the fact that function values are now self-evaluating. * lisp/emacs-lisp/lisp-mode.el (closure): Remove `lisp-indent-function` property. * lisp/emacs-lisp/disass.el (disassemble-internal): Adjust to new representation. * lisp/emacs-lisp/edebug.el (edebug--strip-instrumentation): Use `interpreted-function-p`. * lisp/emacs-lisp/comp-common.el (comp-known-type-specifiers): Add `closurep` and `interpreted-function-p`. * test/lisp/help-fns-tests.el (help-fns-test-lisp-defun): Adjust to more precise type info in `describe-function`. * test/lisp/erc/resources/erc-d/erc-d-tests.el (erc-d--render-entries): Use `interpreted-function-p`. * test/lisp/emacs-lisp/macroexp-resources/vk.el (vk-f4, vk-f5): Don't hardcode function values. * doc/lispref/functions.texi (Anonymous Functions): Don't suggest that function values are lists. Reword "self-quoting" to reflect the fact that #' doesn't return the exact same object. Update examples with the new shape of the return value. * doc/lispref/variables.texi (Lexical Binding): * doc/lispref/lists.texi (Rearrangement): * doc/lispref/control.texi (Handling Errors): Update examples to reflect new representation of function values.
Diffstat (limited to 'doc/lispref/compile.texi')
-rw-r--r--doc/lispref/compile.texi61
1 files changed, 42 insertions, 19 deletions
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index 00602198da5..3fbf39b349d 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -37,7 +37,7 @@ variable binding for @code{no-byte-compile} into it, like this:
37* Docs and Compilation:: Dynamic loading of documentation strings. 37* Docs and Compilation:: Dynamic loading of documentation strings.
38* Eval During Compile:: Code to be evaluated when you compile. 38* Eval During Compile:: Code to be evaluated when you compile.
39* Compiler Errors:: Handling compiler error messages. 39* Compiler Errors:: Handling compiler error messages.
40* Byte-Code Objects:: The data type used for byte-compiled functions. 40* Closure Objects:: The data type used for byte-compiled functions.
41* Disassembly:: Disassembling byte-code; how to read byte-code. 41* Disassembly:: Disassembling byte-code; how to read byte-code.
42@end menu 42@end menu
43 43
@@ -120,7 +120,7 @@ replacing the previous definition with the compiled one. The function
120definition of @var{symbol} must be the actual code for the function; 120definition of @var{symbol} must be the actual code for the function;
121@code{byte-compile} does not handle function indirection. The return 121@code{byte-compile} does not handle function indirection. The return
122value is the byte-code function object which is the compiled 122value is the byte-code function object which is the compiled
123definition of @var{symbol} (@pxref{Byte-Code Objects}). 123definition of @var{symbol} (@pxref{Closure Objects}).
124 124
125@example 125@example
126@group 126@group
@@ -487,21 +487,22 @@ string for details.
487using @code{error}. If so, set @code{byte-compile-error-on-warn} to a 487using @code{error}. If so, set @code{byte-compile-error-on-warn} to a
488non-@code{nil} value. 488non-@code{nil} value.
489 489
490@node Byte-Code Objects 490@node Closure Objects
491@section Byte-Code Function Objects 491@section Closure Function Objects
492@cindex compiled function 492@cindex compiled function
493@cindex byte-code function 493@cindex byte-code function
494@cindex byte-code object 494@cindex byte-code object
495 495
496 Byte-compiled functions have a special data type: they are 496 Byte-compiled functions use a special data type: they are closures.
497@dfn{byte-code function objects}. Whenever such an object appears as 497Closures are used both for byte-compiled Lisp functions as well as for
498a function to be called, Emacs uses the byte-code interpreter to 498interpreted Lisp functions. Whenever such an object appears as
499execute the byte-code. 499a function to be called, Emacs uses the appropriate interpreter to
500execute either the byte-code or the non-compiled Lisp code.
500 501
501 Internally, a byte-code function object is much like a vector; its 502 Internally, a closure is much like a vector; its
502elements can be accessed using @code{aref}. Its printed 503elements can be accessed using @code{aref}. Its printed
503representation is like that for a vector, with an additional @samp{#} 504representation is like that for a vector, with an additional @samp{#}
504before the opening @samp{[}. It must have at least four elements; 505before the opening @samp{[}. It must have at least three elements;
505there is no maximum number, but only the first six elements have any 506there is no maximum number, but only the first six elements have any
506normal use. They are: 507normal use. They are:
507 508
@@ -515,20 +516,28 @@ zero to 6, and the maximum number of arguments in bits 8 to 14. If
515the argument list uses @code{&rest}, then bit 7 is set; otherwise it's 516the argument list uses @code{&rest}, then bit 7 is set; otherwise it's
516cleared. 517cleared.
517 518
518If @var{argdesc} is a list, the arguments will be dynamically bound 519When the closure is a byte-code function,
520if @var{argdesc} is a list, the arguments will be dynamically bound
519before executing the byte code. If @var{argdesc} is an integer, the 521before executing the byte code. If @var{argdesc} is an integer, the
520arguments will be instead pushed onto the stack of the byte-code 522arguments will be instead pushed onto the stack of the byte-code
521interpreter, before executing the code. 523interpreter, before executing the code.
522 524
523@item byte-code 525@item code
524The string containing the byte-code instructions. 526For interpreted functions, this element is the (non-empty) list of Lisp
527forms that make up the function's body. For byte-compiled functions, it
528is the string containing the byte-code instructions.
525 529
526@item constants 530@item constants
527The vector of Lisp objects referenced by the byte code. These include 531For byte-compiled functions, this holds the vector of Lisp objects
528symbols used as function names and variable names. 532referenced by the byte code. These include symbols used as function
533names and variable names.
534For interpreted functions, this is @code{nil} if the function is using the old
535dynamically scoped dialect of Emacs Lisp, and otherwise it holds the
536function's lexical environment.
529 537
530@item stacksize 538@item stacksize
531The maximum stack size this function needs. 539The maximum stack size this function needs. This element is left unused
540for interpreted functions.
532 541
533@item docstring 542@item docstring
534The documentation string (if any); otherwise, @code{nil}. The value may 543The documentation string (if any); otherwise, @code{nil}. The value may
@@ -558,8 +567,8 @@ representation. It is the definition of the command
558@code{make-byte-code}: 567@code{make-byte-code}:
559 568
560@defun make-byte-code &rest elements 569@defun make-byte-code &rest elements
561This function constructs and returns a byte-code function object 570This function constructs and returns a closure which represents the
562with @var{elements} as its elements. 571byte-code function object with @var{elements} as its elements.
563@end defun 572@end defun
564 573
565 You should not try to come up with the elements for a byte-code 574 You should not try to come up with the elements for a byte-code
@@ -567,6 +576,20 @@ function yourself, because if they are inconsistent, Emacs may crash
567when you call the function. Always leave it to the byte compiler to 576when you call the function. Always leave it to the byte compiler to
568create these objects; it makes the elements consistent (we hope). 577create these objects; it makes the elements consistent (we hope).
569 578
579The primitive way to create an interpreted function is with
580@code{make-interpreted-closure}:
581
582@defun make-interpreted-closure args body env &optional docstring iform
583This function constructs and returns a closure representing the
584interpreted function with arguments @var{args} and whose body is made of
585@var{body} which must be a non-@code{nil} list of Lisp forms. @var{env} is the
586lexical environment in the same form as used with @code{eval}
587(@pxref{Eval}). The documentation @var{docstring} if non-@code{nil} should be
588a string, and the interactive form @var{iform} if non-@code{nil} should be of
589the form @w{@code{(interactive @var{arg-descriptor})}} (@pxref{Using
590Interactive}).
591@end defun
592
570@node Disassembly 593@node Disassembly
571@section Disassembled Byte-Code 594@section Disassembled Byte-Code
572@cindex disassembled byte-code 595@cindex disassembled byte-code
@@ -595,7 +618,7 @@ name of an existing buffer. Then the output goes there, at point, and
595point is left before the output. 618point is left before the output.
596 619
597The argument @var{object} can be a function name, a lambda expression 620The argument @var{object} can be a function name, a lambda expression
598(@pxref{Lambda Expressions}), or a byte-code object (@pxref{Byte-Code 621(@pxref{Lambda Expressions}), or a byte-code object (@pxref{Closure
599Objects}). If it is a lambda expression, @code{disassemble} compiles 622Objects}). If it is a lambda expression, @code{disassemble} compiles
600it and disassembles the resulting compiled code. 623it and disassembles the resulting compiled code.
601@end deffn 624@end deffn