diff options
| author | Stefan Monnier | 2024-03-11 16:12:26 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2024-04-18 15:28:36 -0400 |
| commit | 126be02077520a943252d0d219bb7677466d0168 (patch) | |
| tree | f762237714f11b303c708f93f09a8dc72426bb2a /doc/lispref/compile.texi | |
| parent | 7842af6095db4384898725fb4a14ebaa11379a34 (diff) | |
| download | emacs-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.texi | 61 |
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 | |||
| 120 | definition of @var{symbol} must be the actual code for the function; | 120 | definition 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 |
| 122 | value is the byte-code function object which is the compiled | 122 | value is the byte-code function object which is the compiled |
| 123 | definition of @var{symbol} (@pxref{Byte-Code Objects}). | 123 | definition of @var{symbol} (@pxref{Closure Objects}). |
| 124 | 124 | ||
| 125 | @example | 125 | @example |
| 126 | @group | 126 | @group |
| @@ -487,21 +487,22 @@ string for details. | |||
| 487 | using @code{error}. If so, set @code{byte-compile-error-on-warn} to a | 487 | using @code{error}. If so, set @code{byte-compile-error-on-warn} to a |
| 488 | non-@code{nil} value. | 488 | non-@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 | 497 | Closures are used both for byte-compiled Lisp functions as well as for |
| 498 | a function to be called, Emacs uses the byte-code interpreter to | 498 | interpreted Lisp functions. Whenever such an object appears as |
| 499 | execute the byte-code. | 499 | a function to be called, Emacs uses the appropriate interpreter to |
| 500 | execute 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 |
| 502 | elements can be accessed using @code{aref}. Its printed | 503 | elements can be accessed using @code{aref}. Its printed |
| 503 | representation is like that for a vector, with an additional @samp{#} | 504 | representation is like that for a vector, with an additional @samp{#} |
| 504 | before the opening @samp{[}. It must have at least four elements; | 505 | before the opening @samp{[}. It must have at least three elements; |
| 505 | there is no maximum number, but only the first six elements have any | 506 | there is no maximum number, but only the first six elements have any |
| 506 | normal use. They are: | 507 | normal use. They are: |
| 507 | 508 | ||
| @@ -515,20 +516,28 @@ zero to 6, and the maximum number of arguments in bits 8 to 14. If | |||
| 515 | the argument list uses @code{&rest}, then bit 7 is set; otherwise it's | 516 | the argument list uses @code{&rest}, then bit 7 is set; otherwise it's |
| 516 | cleared. | 517 | cleared. |
| 517 | 518 | ||
| 518 | If @var{argdesc} is a list, the arguments will be dynamically bound | 519 | When the closure is a byte-code function, |
| 520 | if @var{argdesc} is a list, the arguments will be dynamically bound | ||
| 519 | before executing the byte code. If @var{argdesc} is an integer, the | 521 | before executing the byte code. If @var{argdesc} is an integer, the |
| 520 | arguments will be instead pushed onto the stack of the byte-code | 522 | arguments will be instead pushed onto the stack of the byte-code |
| 521 | interpreter, before executing the code. | 523 | interpreter, before executing the code. |
| 522 | 524 | ||
| 523 | @item byte-code | 525 | @item code |
| 524 | The string containing the byte-code instructions. | 526 | For interpreted functions, this element is the (non-empty) list of Lisp |
| 527 | forms that make up the function's body. For byte-compiled functions, it | ||
| 528 | is the string containing the byte-code instructions. | ||
| 525 | 529 | ||
| 526 | @item constants | 530 | @item constants |
| 527 | The vector of Lisp objects referenced by the byte code. These include | 531 | For byte-compiled functions, this holds the vector of Lisp objects |
| 528 | symbols used as function names and variable names. | 532 | referenced by the byte code. These include symbols used as function |
| 533 | names and variable names. | ||
| 534 | For interpreted functions, this is @code{nil} if the function is using the old | ||
| 535 | dynamically scoped dialect of Emacs Lisp, and otherwise it holds the | ||
| 536 | function's lexical environment. | ||
| 529 | 537 | ||
| 530 | @item stacksize | 538 | @item stacksize |
| 531 | The maximum stack size this function needs. | 539 | The maximum stack size this function needs. This element is left unused |
| 540 | for interpreted functions. | ||
| 532 | 541 | ||
| 533 | @item docstring | 542 | @item docstring |
| 534 | The documentation string (if any); otherwise, @code{nil}. The value may | 543 | The 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 |
| 561 | This function constructs and returns a byte-code function object | 570 | This function constructs and returns a closure which represents the |
| 562 | with @var{elements} as its elements. | 571 | byte-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 | |||
| 567 | when you call the function. Always leave it to the byte compiler to | 576 | when you call the function. Always leave it to the byte compiler to |
| 568 | create these objects; it makes the elements consistent (we hope). | 577 | create these objects; it makes the elements consistent (we hope). |
| 569 | 578 | ||
| 579 | The 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 | ||
| 583 | This function constructs and returns a closure representing the | ||
| 584 | interpreted 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 | ||
| 586 | lexical environment in the same form as used with @code{eval} | ||
| 587 | (@pxref{Eval}). The documentation @var{docstring} if non-@code{nil} should be | ||
| 588 | a string, and the interactive form @var{iform} if non-@code{nil} should be of | ||
| 589 | the form @w{@code{(interactive @var{arg-descriptor})}} (@pxref{Using | ||
| 590 | Interactive}). | ||
| 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 | |||
| 595 | point is left before the output. | 618 | point is left before the output. |
| 596 | 619 | ||
| 597 | The argument @var{object} can be a function name, a lambda expression | 620 | The 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 |
| 599 | Objects}). If it is a lambda expression, @code{disassemble} compiles | 622 | Objects}). If it is a lambda expression, @code{disassemble} compiles |
| 600 | it and disassembles the resulting compiled code. | 623 | it and disassembles the resulting compiled code. |
| 601 | @end deffn | 624 | @end deffn |