From: Chong Yidong Date: Fri, 10 Feb 2012 15:50:11 +0000 (+0800) Subject: Update Compilation and Advice chapters in Lisp manual. X-Git-Tag: emacs-pretest-24.0.94~191 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=25dec3650947892e638be48220024a7d1b1d8be8;p=emacs.git Update Compilation and Advice chapters in Lisp manual. * doc/lispref/advice.texi (Defining Advice): Clarify ad-unadvise. (Activation of Advice): Specifying the ACTIVATE flag in defadvice is not abnormal. (Advising Primitives): Node deleted; ad-define-subr-args has been removed. * doc/lispref/compile.texi (Speed of Byte-Code): Use float-time in example. (Compilation Functions): Note that the log uses Compilation mode. Don't discuss the contents of byte-code function object here. (Compilation Functions): De-document internal function byte-code. (Docs and Compilation): Minor clarifications. * doc/lispref/objects.texi (Byte-Code Type): Add xref to Byte-Code Function Objects. * lisp/emacs-lisp/advice.el: Update commentary to reflect deletion of ad-define-subr-args --- diff --git a/admin/FOR-RELEASE b/admin/FOR-RELEASE index 58662acb604..abe53ad0b0d 100644 --- a/admin/FOR-RELEASE +++ b/admin/FOR-RELEASE @@ -180,13 +180,13 @@ xresources.texi cyd ** Check the Lisp manual. abbrevs.texi -advice.texi +advice.texi cyd anti.texi back.texi backups.texi buffers.texi commands.texi -compile.texi +compile.texi cyd control.texi cyd customize.texi cyd debugging.texi diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 762f173563f..1e93d5dd737 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,20 @@ +2012-02-10 Chong Yidong + + * advice.texi (Defining Advice): Clarify ad-unadvise. + (Activation of Advice): Specifying the ACTIVATE flag in defadvice + is not abnormal. + (Advising Primitives): Node deleted; ad-define-subr-args has been + removed. + + * compile.texi (Speed of Byte-Code): Use float-time in example. + (Compilation Functions): Note that the log uses Compilation mode. + Don't discuss the contents of byte-code function object here. + (Compilation Functions): De-document internal function byte-code. + (Docs and Compilation): Minor clarifications. + + * objects.texi (Byte-Code Type): Add xref to Byte-Code Function + Objects. + 2012-02-10 Glenn Morris * text.texi (Checksum/Hash): Rename node from MD5 Checksum. diff --git a/doc/lispref/advice.texi b/doc/lispref/advice.texi index ee1950a589a..78b4ac9aa2d 100644 --- a/doc/lispref/advice.texi +++ b/doc/lispref/advice.texi @@ -13,30 +13,35 @@ for a library to customize functions defined within Emacs---cleaner than redefining the whole function. @cindex piece of advice - Each function can have multiple @dfn{pieces of advice}, separately -defined. Each defined piece of advice can be @dfn{enabled} or -@dfn{disabled} explicitly. All the enabled pieces of advice for any given -function actually take effect when you @dfn{activate} advice for that + Each function can have multiple @dfn{pieces of advice}, each of +which can be separately defined and then @dfn{enabled} or +@dfn{disabled}. All the enabled pieces of advice for any given +function actually take effect when you @dfn{activate advice} for that function, or when you define or redefine the function. Note that -enabling a piece of advice and activating advice for a function -are not the same thing. - - @strong{Usage Note:} Advice is useful for altering the behavior of -existing calls to an existing function. If you want the new behavior -for new calls, or for key bindings, you should define a new function -(or a new command) which uses the existing function. - - @strong{Usage note:} Advising a function can cause confusion in -debugging, since people who debug calls to the original function may -not notice that it has been modified with advice. Therefore, if you -have the possibility to change the code of that function (or ask -someone to do so) to run a hook, please solve the problem that way. -Advice should be reserved for the cases where you cannot get the -function changed. - - In particular, this means that a file in Emacs should not put advice -on a function in Emacs. There are currently a few exceptions to this -convention, but we aim to correct them. +enabling a piece of advice and activating advice for a function are +not the same thing. + + Advice is useful for altering the behavior of existing calls to an +existing function. If you want the new behavior for new function +calls or new key bindings, you should define a new function or +command, and have it use the existing function as a subroutine. + + Advising a function can cause confusion in debugging, since people +who debug calls to the original function may not notice that it has +been modified with advice. Therefore, if you have the possibility to +change the code of that function to run a hook, please solve the +problem that way. Advice should be reserved for the cases where you +cannot get the function changed. In particular, Emacs' own source +files should not put advice on functions in Emacs. There are +currently a few exceptions to this convention, but we aim to correct +them. + + Unless you know what you are doing, do @emph{not} advise a primitive +(@pxref{What Is a Function}). Some primitives are used by the advice +mechanism; advising them could cause an infinite recursion. Also, +many primitives are called directly from C code. Calls to the +primitive from Lisp code will take note of the advice, but calls from +C code will ignore the advice. @menu * Simple Advice:: A simple example to explain the basics of advice. @@ -48,7 +53,6 @@ convention, but we aim to correct them. * Preactivation:: Preactivation is a way of speeding up the loading of compiled advice. * Argument Access in Advice:: How advice can access the function's arguments. -* Advising Primitives:: Accessing arguments when advising a primitive. * Combined Definition:: How advice is implemented. @end menu @@ -258,7 +262,7 @@ All subroutines used by the advice need to be available when the byte compiler expands the macro. @deffn Command ad-unadvise function -This command deletes the advice from @var{function}. +This command deletes all pieces of advice from @var{function}. @end deffn @deffn Command ad-unadvise-all @@ -355,13 +359,13 @@ replaced with the new one. @cindex advice, activating By default, advice does not take effect when you define it---only when -you @dfn{activate} advice for the function that was advised. However, -the advice will be activated automatically if you define or redefine -the function later. You can request the activation of advice for a -function when you define the advice, by specifying the @code{activate} -flag in the @code{defadvice}. But normally you activate the advice -for a function by calling the function @code{ad-activate} or one of -the other activation commands listed below. +you @dfn{activate} advice for the function. However, the advice will +be activated automatically if you define or redefine the function +later. You can request the activation of advice for a function when +you define the advice, by specifying the @code{activate} flag in the +@code{defadvice}; or you can activate the advice separately by calling +the function @code{ad-activate} or one of the other activation +commands listed below. Separating the activation of advice from the act of defining it permits you to add several pieces of advice to one function efficiently, without @@ -680,39 +684,6 @@ will be 3, and @var{r} will be @code{(2 1 0)} inside the body of These argument constructs are not really implemented as Lisp macros. Instead they are implemented specially by the advice mechanism. -@node Advising Primitives -@section Advising Primitives -@cindex advising primitives - - Advising a primitive function (@pxref{What Is a Function}) is risky. -Some primitive functions are used by the advice mechanism; advising -them could cause an infinite recursion. Also, many primitive -functions are called directly from C code. Calls to the primitive -from Lisp code will take note of the advice, but calls from C code -will ignore the advice. - -When the advice facility constructs the combined definition, it needs -to know the argument list of the original function. This is not -always possible for primitive functions. When advice cannot determine -the argument list, it uses @code{(&rest ad-subr-args)}, which always -works but is inefficient because it constructs a list of the argument -values. You can use @code{ad-define-subr-args} to declare the proper -argument names for a primitive function: - -@defun ad-define-subr-args function arglist -This function specifies that @var{arglist} should be used as the -argument list for function @var{function}. -@end defun - -For example, - -@example -(ad-define-subr-args 'fset '(sym newdef)) -@end example - -@noindent -specifies the argument list for the function @code{fset}. - @node Combined Definition @section The Combined Definition diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 4e21df78430..545f05d9d57 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -32,9 +32,6 @@ variable binding for @code{no-byte-compile} into it, like this: ;; -*-no-byte-compile: t; -*- @end example - @xref{Compilation Errors}, for how to investigate errors occurring in -byte compilation. - @menu * Speed of Byte-Code:: An example of speedup from byte compilation. * Compilation Functions:: Byte compilation functions. @@ -56,18 +53,16 @@ Here is an example: @example @group (defun silly-loop (n) - "Return time before and after N iterations of a loop." - (let ((t1 (current-time-string))) - (while (> (setq n (1- n)) - 0)) - (list t1 (current-time-string)))) + "Return the time, in seconds, to run N iterations of a loop." + (let ((t1 (float-time))) + (while (> (setq n (1- n)) 0)) + (- (float-time) t1))) @result{} silly-loop @end group @group (silly-loop 50000000) -@result{} ("Wed Mar 11 21:10:19 2009" - "Wed Mar 11 21:10:41 2009") ; @r{22 seconds} +@result{} 10.235304117202759 @end group @group @@ -77,18 +72,17 @@ Here is an example: @group (silly-loop 50000000) -@result{} ("Wed Mar 11 21:12:26 2009" - "Wed Mar 11 21:12:32 2009") ; @r{6 seconds} +@result{} 3.705854892730713 @end group @end example - In this example, the interpreted code required 22 seconds to run, -whereas the byte-compiled code required 6 seconds. These results are -representative, but actual results will vary greatly. + In this example, the interpreted code required 10 seconds to run, +whereas the byte-compiled code required less than 4 seconds. These +results are representative, but actual results may vary. @node Compilation Functions @comment node-name, next, previous, up -@section The Compilation Functions +@section Byte-Compilation Functions @cindex compilation functions You can byte-compile an individual function or macro definition with @@ -96,43 +90,36 @@ the @code{byte-compile} function. You can compile a whole file with @code{byte-compile-file}, or several files with @code{byte-recompile-directory} or @code{batch-byte-compile}. - The byte compiler produces error messages and warnings about each file -in a buffer called @samp{*Compile-Log*}. These report things in your -program that suggest a problem but are not necessarily erroneous. + Sometimes, the byte compiler produces warning and/or error messages +(@pxref{Compiler Errors}, for details). These messages are recorded +in a buffer called @samp{*Compile-Log*}, which uses Compilation mode. +@xref{Compilation Mode,,,emacs, The GNU Emacs Manual}. @cindex macro compilation - Be careful when writing macro calls in files that you may someday -byte-compile. Macro calls are expanded when they are compiled, so the -macros must already be defined for proper compilation. For more -details, see @ref{Compiling Macros}. If a program does not work the -same way when compiled as it does when interpreted, erroneous macro -definitions are one likely cause (@pxref{Problems with Macros}). -Inline (@code{defsubst}) functions are less troublesome; if you + Be careful when writing macro calls in files that you intend to +byte-compile. Since macro calls are expanded when they are compiled, +the macros need to be loaded into Emacs or the byte compiler will not +do the right thing. The usual way to handle this is with +@code{require} forms which specify the files containing the needed +macro definitions (@pxref{Named Features}). Normally, the +byte compiler does not evaluate the code that it is compiling, but it +handles @code{require} forms specially, by loading the specified +libraries. To avoid loading the macro definition files when someone +@emph{runs} the compiled program, write @code{eval-when-compile} +around the @code{require} calls (@pxref{Eval During Compile}). For +more details, @xref{Compiling Macros}. + + Inline (@code{defsubst}) functions are less troublesome; if you compile a call to such a function before its definition is known, the call will still work right, it will just run slower. - Normally, compiling a file does not evaluate the file's contents or -load the file. But it does execute any @code{require} calls at top -level in the file. One way to ensure that necessary macro definitions -are available during compilation is to require the file that defines -them (@pxref{Named Features}). To avoid loading the macro definition files -when someone @emph{runs} the compiled program, write -@code{eval-when-compile} around the @code{require} calls (@pxref{Eval -During Compile}). - @defun byte-compile symbol This function byte-compiles the function definition of @var{symbol}, replacing the previous definition with the compiled one. The function definition of @var{symbol} must be the actual code for the function; -i.e., the compiler does not follow indirection to another symbol. -@code{byte-compile} returns the new, compiled definition of -@var{symbol}. - - If @var{symbol}'s definition is a byte-code function object, -@code{byte-compile} does nothing and returns @code{nil}. Lisp records -only one function definition for any symbol, and if that is already -compiled, non-compiled code is not available anywhere. So there is no -way to ``compile the same definition again.'' +@code{byte-compile} does not handle function indirection. The return +value is the byte-code function object which is the compiled +definition of @var{symbol} (@pxref{Byte-Code Objects}). @example @group @@ -153,16 +140,15 @@ way to ``compile the same definition again.'' @end group @end example -@noindent -The result is a byte-code function object. The string it contains is -the actual byte-code; each character in it is an instruction or an -operand of an instruction. The vector contains all the constants, -variable names and function names used by the function, except for -certain primitives that are coded as special instructions. - -If the argument to @code{byte-compile} is a @code{lambda} expression, -it returns the corresponding compiled code, but does not store -it anywhere. +If @var{symbol}'s definition is a byte-code function object, +@code{byte-compile} does nothing and returns @code{nil}. It does not +``compile the symbol's definition again'', since the original +(non-compiled) code has already been replaced in the symbol's function +cell by the byte-compiled code. + +The argument to @code{byte-compile} can also be a @code{lambda} +expression. In that case, the function returns the corresponding +compiled code but does not store it anywhere. @end defun @deffn Command compile-defun &optional arg @@ -252,19 +238,6 @@ files that have an up-to-date @samp{.elc} file. @end example @end defun -@defun byte-code code-string data-vector max-stack -@cindex byte-code interpreter -This function actually interprets byte-code. A byte-compiled function -is actually defined with a body that calls @code{byte-code}. Don't call -this function yourself---only the byte compiler knows how to generate -valid calls to this function. - -In Emacs version 18, byte-code was always executed by way of a call to -the function @code{byte-code}. Nowadays, byte-code is usually executed -as part of a byte-code function object, and only rarely through an -explicit call to @code{byte-code}. -@end defun - @node Docs and Compilation @section Documentation Strings and Compilation @cindex dynamic loading of documentation @@ -290,33 +263,11 @@ then further access to documentation strings in this file will probably give nonsense results. @end itemize - If your site installs Emacs following the usual procedures, these -problems will never normally occur. Installing a new version uses a new -directory with a different name; as long as the old version remains -installed, its files will remain unmodified in the places where they are -expected to be. - - However, if you have built Emacs yourself and use it from the -directory where you built it, you will experience this problem -occasionally if you edit and recompile Lisp files. When it happens, you -can cure the problem by reloading the file after recompiling it. - - You can turn off this feature at compile time by setting -@code{byte-compile-dynamic-docstrings} to @code{nil}; this is useful -mainly if you expect to change the file, and you want Emacs processes -that have already loaded it to keep working when the file changes. -You can do this globally, or for one source file by specifying a -file-local binding for the variable. One way to do that is by adding -this string to the file's first line: - -@example --*-byte-compile-dynamic-docstrings: nil;-*- -@end example - -@defvar byte-compile-dynamic-docstrings -If this is non-@code{nil}, the byte compiler generates compiled files -that are set up for dynamic loading of documentation strings. -@end defvar +@noindent +These problems normally occur only if you build Emacs yourself and use +it from the directory where you built it, and you happen to edit +and/or recompile the Lisp source files. They can be easily cured by +reloading each file after recompiling it. @cindex @samp{#@@@var{count}} @cindex @samp{#$} @@ -328,6 +279,23 @@ string.'' It is usually best not to use these constructs in Lisp source files, since they are not designed to be clear to humans reading the file. + You can disable the dynamic documentation string feature at compile +time by setting @code{byte-compile-dynamic-docstrings} to @code{nil}; +this is useful mainly if you expect to change the file, and you want +Emacs processes that have already loaded it to keep working when the +file changes. You can do this globally, or for one source file by +specifying a file-local binding for the variable. One way to do that +is by adding this string to the file's first line: + +@example +-*-byte-compile-dynamic-docstrings: nil;-*- +@end example + +@defvar byte-compile-dynamic-docstrings +If this is non-@code{nil}, the byte compiler generates compiled files +that are set up for dynamic loading of documentation strings. +@end defvar + @node Dynamic Loading @section Dynamic Loading of Individual Functions @@ -541,17 +509,16 @@ one you intend to suppress. @cindex byte-code function Byte-compiled functions have a special data type: they are -@dfn{byte-code function objects}. +@dfn{byte-code function objects}. Whenever such an object appears as +a function to be called, Emacs uses the byte-code interpreter to +execute the byte-code. - 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. The printed representation for a byte-code -function object is like that for a vector, with an additional @samp{#} -before the opening @samp{[}. - - A byte-code function object must have at least four elements; there is -no maximum number, but only the first six elements have any normal use. -They are: + Internally, a byte-code function object is much like a vector; its +elements can be accessed using @code{aref}. Its printed +representation is like that for a vector, with an additional @samp{#} +before the opening @samp{[}. It must have at least four elements; +there is no maximum number, but only the first six elements have any +normal use. They are: @table @var @item arglist @@ -588,7 +555,7 @@ representation. It is the definition of the command [arg 1 forward-sexp] 2 254435 - "p"] + "^p"] @end example The primitive way to create a byte-code object is with @@ -604,10 +571,6 @@ function yourself, because if they are inconsistent, Emacs may crash when you call the function. Always leave it to the byte compiler to create these objects; it makes the elements consistent (we hope). - You can access the elements of a byte-code object using @code{aref}; -you can also use @code{vconcat} to create a vector with the same -elements. - @node Disassembly @section Disassembled Byte-Code @cindex disassembled byte-code diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index cd688acd6ac..a925f3865a4 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -548,7 +548,6 @@ Advising Emacs Lisp Functions * Preactivation:: Preactivation is a way of speeding up the loading of compiled advice. * Argument Access in Advice:: How advice can access the function's arguments. -* Advising Primitives:: Accessing arguments when advising a primitive. * Combined Definition:: How advice is implemented. Debugging Lisp Programs diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 445cb800d33..995a4d89352 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -1323,11 +1323,11 @@ with the name of the subroutine. @node Byte-Code Type @subsection Byte-Code Function Type -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. +@dfn{Byte-code function objects} are produced by byte-compiling Lisp +code (@pxref{Byte Compilation}). Internally, a byte-code function +object is much like a vector; however, the evaluator handles this data +type specially when it appears in a function call. @xref{Byte-Code +Objects}. The printed representation and read syntax for a byte-code function object is like that for a vector, with an additional @samp{#} before the diff --git a/doc/lispref/vol1.texi b/doc/lispref/vol1.texi index 798bd0cabf6..31055bd03fe 100644 --- a/doc/lispref/vol1.texi +++ b/doc/lispref/vol1.texi @@ -568,7 +568,6 @@ Advising Emacs Lisp Functions * Preactivation:: Preactivation is a way of speeding up the loading of compiled advice. * Argument Access in Advice:: How advice can access the function's arguments. -* Advising Primitives:: Accessing arguments when advising a primitive. * Combined Definition:: How advice is implemented. Debugging Lisp Programs diff --git a/doc/lispref/vol2.texi b/doc/lispref/vol2.texi index 3ef7dd7f87f..92f049135a1 100644 --- a/doc/lispref/vol2.texi +++ b/doc/lispref/vol2.texi @@ -567,7 +567,6 @@ Advising Emacs Lisp Functions * Preactivation:: Preactivation is a way of speeding up the loading of compiled advice. * Argument Access in Advice:: How advice can access the function's arguments. -* Advising Primitives:: Accessing arguments when advising a primitive. * Combined Definition:: How advice is implemented. Debugging Lisp Programs diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el index e0d8ffaba90..09dde2c1c17 100644 --- a/lisp/emacs-lisp/advice.el +++ b/lisp/emacs-lisp/advice.el @@ -348,10 +348,7 @@ ;; first argument list defined in the list of before/around/after advices. ;; The values of variables can be accessed/changed in the body of ;; an advice by simply referring to them by their original name, however, -;; more portable argument access macros are also provided (see below). For -;; subrs/special-forms for which neither explicit argument list definitions -;; are available, nor their documentation strings contain such definitions -;; (as they do v19s), `(&rest ad-subr-args)' will be used. +;; more portable argument access macros are also provided (see below). ;; is an optional, special documentation string which will ;; be expanded into a proper documentation string upon call of `documentation'. @@ -491,17 +488,15 @@ ;; @@@ Argument list mapping: ;; ========================== -;; Because `defadvice' allows the specification of the argument list of the -;; advised function we need a mapping mechanism that maps this argument list -;; onto that of the original function. For example, somebody might specify -;; `(sym newdef)' as the argument list of `fset', while advice might use -;; `(&rest ad-subr-args)' as the argument list of the original function -;; (depending on what Emacs version is used). Hence SYM and NEWDEF have to -;; be properly mapped onto the &rest variable when the original definition is -;; called. Advice automatically takes care of that mapping, hence, the advice -;; programmer can specify an argument list without having to know about the -;; exact structure of the original argument list as long as the new argument -;; list takes a compatible number/magnitude of actual arguments. +;; Because `defadvice' allows the specification of the argument list +;; of the advised function we need a mapping mechanism that maps this +;; argument list onto that of the original function. Hence SYM and +;; NEWDEF have to be properly mapped onto the &rest variable when the +;; original definition is called. Advice automatically takes care of +;; that mapping, hence, the advice programmer can specify an argument +;; list without having to know about the exact structure of the +;; original argument list as long as the new argument list takes a +;; compatible number/magnitude of actual arguments. ;; @@ Activation and deactivation: ;; =============================== @@ -884,9 +879,6 @@ ;; @@ Summary of forms with special meanings when used within an advice: ;; ===================================================================== ;; ad-return-value name of the return value variable (get/settable) -;; ad-subr-args name of &rest argument variable used for advised -;; subrs whose actual argument list cannot be -;; determined (get/settable) ;; (ad-get-arg ), (ad-get-args ), ;; (ad-set-arg ), (ad-set-args ) ;; argument access text macros to get/set the values of @@ -2594,36 +2586,6 @@ For that it has to be fbound with a non-autoload definition." (byte-compile symbol) (fset function (symbol-function symbol)))))) - -;; @@ Constructing advised definitions: -;; ==================================== -;; -;; Main design decisions about the form of advised definitions: -;; -;; A) How will original definitions be called? -;; B) What will argument lists of advised functions look like? -;; -;; Ad A) -;; I chose to use function indirection for all four types of original -;; definitions (functions, macros, subrs and special forms), i.e., create -;; a unique symbol `ad-Orig-' which is fbound to the original -;; definition and call it according to type and arguments. Functions and -;; subrs that don't have any &rest arguments can be called directly in a -;; `(ad-Orig- ....)' form. If they have a &rest argument we have to -;; use `apply'. Macros will be called with -;; `(macroexpand '(ad-Orig- ....))', and special forms also need a -;; form like that with `eval' instead of `macroexpand'. -;; -;; Ad B) -;; Use original arguments where possible and `(&rest ad-subr-args)' -;; otherwise, even though this seems to be more complicated and less -;; uniform than a general `(&rest args)' approach. My reason to still -;; do it that way is that in most cases my approach leads to the more -;; efficient form for the advised function, and portability (e.g., to -;; make the same advice work regardless of whether something is a -;; function or a subr) can still be achieved with argument access macros. - - (defun ad-prognify (forms) (cond ((<= (length forms) 1) (car forms))