]> code.delx.au - gnu-emacs/blobdiff - doc/lispref/compile.texi
Improve documentation of byte-code objects
[gnu-emacs] / doc / lispref / compile.texi
index ead75942b244ca5640c12f9a60ee76eb040b6b2b..c943a6a29c19a4649dd3efab5e4ab6da539fb570 100644 (file)
@@ -1,8 +1,8 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Emacs Lisp Reference Manual.
-@c Copyright (C) 1990-1994, 2001-2012 Free Software Foundation, Inc.
+@c Copyright (C) 1990-1994, 2001-2016 Free Software Foundation, Inc.
 @c See the file elisp.texi for copying conditions.
-@node Byte Compilation, Advising Functions, Loading, Top
+@node Byte Compilation
 @chapter Byte Compilation
 @cindex byte compilation
 @cindex byte-code
@@ -80,7 +80,6 @@ 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 Byte-Compilation Functions
 @cindex compilation functions
 
@@ -141,7 +140,7 @@ definition of @var{symbol} (@pxref{Byte-Code Objects}).
 
 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
+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.
 
@@ -182,8 +181,8 @@ after compiling it.  Interactively, @var{load} is the prefix argument.
 
 @example
 @group
-% ls -l push*
--rw-r--r--  1 lewis     791 Oct  5 20:31 push.el
+$ ls -l push*
+-rw-r--r-- 1 lewis lewis 791 Oct  5 20:31 push.el
 @end group
 
 @group
@@ -192,9 +191,9 @@ after compiling it.  Interactively, @var{load} is the prefix argument.
 @end group
 
 @group
-% ls -l push*
--rw-r--r--  1 lewis     791 Oct  5 20:31 push.el
--rw-rw-rw-  1 lewis     638 Oct  8 20:25 push.elc
+$ ls -l push*
+-rw-r--r-- 1 lewis lewis 791 Oct  5 20:31 push.el
+-rw-rw-rw- 1 lewis lewis 638 Oct  8 20:25 push.elc
 @end group
 @end example
 @end deffn
@@ -233,7 +232,7 @@ If @var{noforce} is non-@code{nil}, this function does not recompile
 files that have an up-to-date @samp{.elc} file.
 
 @example
-% emacs -batch -f batch-byte-compile *.el
+$ emacs -batch -f batch-byte-compile *.el
 @end example
 @end defun
 
@@ -241,59 +240,49 @@ files that have an up-to-date @samp{.elc} file.
 @section Documentation Strings and Compilation
 @cindex dynamic loading of documentation
 
-  Functions and variables loaded from a byte-compiled file access their
-documentation strings dynamically from the file whenever needed.  This
-saves space within Emacs, and makes loading faster because the
-documentation strings themselves need not be processed while loading the
-file.  Actual access to the documentation strings becomes slower as a
-result, but this normally is not enough to bother users.
+  When Emacs loads functions and variables from a byte-compiled file,
+it normally does not load their documentation strings into memory.
+Each documentation string is dynamically loaded from the
+byte-compiled file only when needed.  This saves memory, and speeds up
+loading by skipping the processing of the documentation strings.
 
-  Dynamic access to documentation strings does have drawbacks:
+  This feature has a drawback: if you delete, move, or alter the
+compiled file (such as by compiling a new version), Emacs may no
+longer be able to access the documentation string of previously-loaded
+functions or variables.  Such a problem normally only occurs if you
+build Emacs yourself, and happen to edit and/or recompile the Lisp
+source files.  To solve it, just reload each file after recompilation.
 
-@itemize @bullet
-@item
-If you delete or move the compiled file after loading it, Emacs can no
-longer access the documentation strings for the functions and variables
-in the file.
-
-@item
-If you alter the compiled file (such as by compiling a new version),
-then further access to documentation strings in this file will
-probably give nonsense results.
-@end itemize
+  Dynamic loading of documentation strings from byte-compiled files is
+determined, at compile time, for each byte-compiled file.  It can be
+disabled via the option @code{byte-compile-dynamic-docstrings}.
 
-@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.
+@defopt 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.
 
-@cindex @samp{#@@@var{count}}
-@cindex @samp{#$}
-  The dynamic documentation string feature writes compiled files that
-use a special Lisp reader construct, @samp{#@@@var{count}}.  This
-construct skips the next @var{count} characters.  It also uses the
-@samp{#$} construct, which stands for ``the name of this file, as a
-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:
+To disable the dynamic loading feature for a specific file, set this
+option to @code{nil} in its header line (@pxref{File Variables, ,
+Local Variables in Files, emacs, The GNU Emacs Manual}), like this:
 
-@example
+@smallexample
 -*-byte-compile-dynamic-docstrings: nil;-*-
-@end example
+@end smallexample
 
-@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
+This is useful mainly if you expect to change the file, and you want
+Emacs sessions that have already loaded it to keep working when the
+file changes.
+@end defopt
+
+@cindex @samp{#@@@var{count}}
+@cindex @samp{#$}
+Internally, the dynamic loading of documentation strings is
+accomplished by writing compiled files with a special Lisp reader
+construct, @samp{#@@@var{count}}.  This construct skips the next
+@var{count} characters.  It also uses the @samp{#$} construct, which
+stands for the name of this file, as a string.  Do not use these
+constructs in Lisp source files; they are not designed to be clear to
+humans reading the file.
 
 @node Dynamic Loading
 @section Dynamic Loading of Individual Functions
@@ -358,6 +347,7 @@ it does nothing.  It always returns @var{function}.
 
 @node Eval During Compile
 @section Evaluation During Compilation
+@cindex eval during compilation
 
   These features permit you to write code to be evaluated during
 compilation of a program.
@@ -441,29 +431,35 @@ to what @code{eval-when-compile} does.
 @section Compiler Errors
 @cindex compiler errors
 
-  Byte compilation outputs all errors and warnings into the buffer
-@file{*Compile-Log*}.  The messages include file names and line
-numbers that identify the location of the problem.  The usual Emacs
-commands for operating on compiler diagnostics work properly on these
+  Error and warning messages from byte compilation are printed in a
+buffer named @file{*Compile-Log*}.  These messages include file names
+and line numbers identifying the location of the problem.  The usual
+Emacs commands for operating on compiler output can be used on these
 messages.
 
   When an error is due to invalid syntax in the program, the byte
 compiler might get confused about the errors' exact location.  One way
-to investigate is to switch to the buffer @w{@file{ *Compiler Input*}}.
-(This buffer name starts with a space, so it does not show up in
-@kbd{M-x list-buffers}.)  This buffer contains the program being
+to investigate is to switch to the buffer @w{@file{ *Compiler
+Input*}}.  (This buffer name starts with a space, so it does not show
+up in the Buffer Menu.)  This buffer contains the program being
 compiled, and point shows how far the byte compiler was able to read;
 the cause of the error might be nearby.  @xref{Syntax Errors}, for
 some tips for locating syntax errors.
 
-  When the byte compiler warns about functions that were used but not
-defined, it always reports the line number for the end of the file,
-not the locations where the missing functions were called.  To find
-the latter, you must search for the function names.
+  A common type of warning issued by the byte compiler is for
+functions and variables that were used but not defined.  Such warnings
+report the line number for the end of the file, not the locations
+where the missing functions or variables were used; to find these, you
+must search the file manually.
+
+  If you are sure that a warning message about a missing function or
+variable is unjustified, there are several ways to suppress it:
 
-  You can suppress the compiler warning for calling an undefined
-function @var{func} by conditionalizing the function call on an
-@code{fboundp} test, like this:
+@itemize @bullet
+@item
+You can suppress the warning for a specific call to a function
+@var{func} by conditionalizing it on an @code{fboundp} test, like
+this:
 
 @example
 (if (fboundp '@var{func}) ...(@var{func} ...)...)
@@ -474,14 +470,10 @@ The call to @var{func} must be in the @var{then-form} of the
 @code{if}, and @var{func} must appear quoted in the call to
 @code{fboundp}.  (This feature operates for @code{cond} as well.)
 
-  You can tell the compiler that a function is defined using
-@code{declare-function} (@pxref{Declaring Functions}).  Likewise, you
-can tell the compiler that a variable is defined using @code{defvar}
-with no initial value.
-
-  You can suppress the compiler warning for a specific use of an
-undefined variable @var{variable} by conditionalizing its use on a
-@code{boundp} test, like this:
+@item
+Likewise, you can suppress the warning for a specific use of a
+variable @var{variable} by conditionalizing it on a @code{boundp}
+test:
 
 @example
 (if (boundp '@var{variable}) ...@var{variable}...)
@@ -492,7 +484,17 @@ The reference to @var{variable} must be in the @var{then-form} of the
 @code{if}, and @var{variable} must appear quoted in the call to
 @code{boundp}.
 
-  You can suppress any and all compiler warnings within a certain
+@item
+You can tell the compiler that a function is defined using
+@code{declare-function}. @xref{Declaring Functions}.
+
+@item
+Likewise, you can tell the compiler that a variable is defined using
+@code{defvar} with no initial value.  (Note that this marks the
+variable as special.)  @xref{Defining Variables}.
+@end itemize
+
+  You can also suppress any and all compiler warnings within a certain
 expression using the construct @code{with-no-warnings}:
 
 @c This is implemented with a defun, but conceptually it is
@@ -508,13 +510,15 @@ possible piece of code, to avoid missing possible warnings other than
 one you intend to suppress.
 @end defspec
 
-  More precise control of warnings is possible by setting the variable
-@code{byte-compile-warnings}.
+  Byte compiler warnings can be controlled more precisely by setting
+the variable @code{byte-compile-warnings}.  See its documentation
+string for details.
 
 @node Byte-Code Objects
 @section Byte-Code Function Objects
 @cindex compiled function
 @cindex byte-code function
+@cindex byte-code object
 
   Byte-compiled functions have a special data type: they are
 @dfn{byte-code function objects}.  Whenever such an object appears as
@@ -529,8 +533,19 @@ there is no maximum number, but only the first six elements have any
 normal use.  They are:
 
 @table @var
-@item arglist
-The list of argument symbols.
+@item argdesc
+The descriptor of the arguments.  This can either be a list of
+arguments, as described in @ref{Argument List}, or an integer encoding
+the required number of arguments.  In the latter case, the value of
+the descriptor specifies the minimum number of arguments in the bits
+zero to 6, and the maximum number of arguments in bits 8 to 14.  If
+the argument list uses @code{&rest}, then bit 7 is set; otherwise it's
+cleared.
+
+If @var{argdesc} is a list, the arguments will be dynamically bound
+before executing the byte code.  If @var{argdesc} is an integer, the
+arguments will be instead pushed onto the stack of the byte-code
+interpreter, before executing the code.
 
 @item byte-code
 The string containing the byte-code instructions.
@@ -558,11 +573,11 @@ representation.  It is the definition of the command
 @code{backward-sexp}.
 
 @example
-#[(&optional arg)
-  "^H\204^F^@@\301^P\302^H[!\207"
-  [arg 1 forward-sexp]
-  2
-  254435
+#[256
+  "\211\204^G^@@\300\262^A\301^A[!\207"
+  [1 forward-sexp]
+  3
+  1793299
   "^p"]
 @end example
 
@@ -607,8 +622,9 @@ name of an existing buffer.  Then the output goes there, at point, and
 point is left before the output.
 
 The argument @var{object} can be a function name, a lambda expression
-or a byte-code object.  If it is a lambda expression, @code{disassemble}
-compiles it and disassembles the resulting compiled code.
+(@pxref{Lambda Expressions}), or a byte-code object (@pxref{Byte-Code
+Objects}).  If it is a lambda expression, @code{disassemble} compiles
+it and disassembles the resulting compiled code.
 @end deffn
 
   Here are two examples of using the @code{disassemble} function.  We
@@ -637,41 +653,34 @@ Lisp source; these do not appear in the output of @code{disassemble}.
 @end group
 
 @group
-0   varref   integer        ; @r{Get the value of @code{integer}}
-                            ;   @r{and push it onto the stack.}
-1   constant 1              ; @r{Push 1 onto stack.}
+0   varref   integer      ; @r{Get the value of @code{integer} and}
+                          ;   @r{push it onto the stack.}
+1   constant 1            ; @r{Push 1 onto stack.}
 @end group
-
 @group
-2   eqlsign                 ; @r{Pop top two values off stack, compare}
-                            ;   @r{them, and push result onto stack.}
+2   eqlsign               ; @r{Pop top two values off stack, compare}
+                          ;   @r{them, and push result onto stack.}
 @end group
-
 @group
-3   goto-if-nil 1           ; @r{Pop and test top of stack;}
-                            ;   @r{if @code{nil}, go to 1,}
-                            ;   @r{else continue.}
-6   constant 1              ; @r{Push 1 onto top of stack.}
-7   return                  ; @r{Return the top element}
-                            ;   @r{of the stack.}
+3   goto-if-nil 1         ; @r{Pop and test top of stack;}
+                          ;   @r{if @code{nil}, go to 1, else continue.}
+6   constant 1            ; @r{Push 1 onto top of stack.}
+7   return                ; @r{Return the top element of the stack.}
 @end group
-
 @group
-8:1 varref   integer        ; @r{Push value of @code{integer} onto stack.}
-9   constant factorial      ; @r{Push @code{factorial} onto stack.}
-10  varref   integer        ; @r{Push value of @code{integer} onto stack.}
-11  sub1                    ; @r{Pop @code{integer}, decrement value,}
-                            ;   @r{push new value onto stack.}
-12  call     1              ; @r{Call function @code{factorial} using}
-                            ;   @r{the first (i.e., the top) element}
-                            ;   @r{of the stack as the argument;}
-                            ;   @r{push returned value onto stack.}
+8:1 varref   integer      ; @r{Push value of @code{integer} onto stack.}
+9   constant factorial    ; @r{Push @code{factorial} onto stack.}
+10  varref   integer      ; @r{Push value of @code{integer} onto stack.}
+11  sub1                  ; @r{Pop @code{integer}, decrement value,}
+                          ;   @r{push new value onto stack.}
+12  call     1            ; @r{Call function @code{factorial} using first}
+                          ;   @r{(i.e., top) stack element as argument;}
+                          ;   @r{push returned value onto stack.}
 @end group
-
 @group
-13 mult                     ; @r{Pop top two values off stack, multiply}
-                            ;   @r{them, and push result onto stack.}
-14 return                   ; @r{Return the top element of stack.}
+13 mult                   ; @r{Pop top two values off stack, multiply}
+                          ;   @r{them, and push result onto stack.}
+14 return                 ; @r{Return the top element of the stack.}
 @end group
 @end example
 
@@ -693,70 +702,55 @@ The @code{silly-loop} function is somewhat more complex:
      @print{} byte-code for silly-loop:
  doc: Return time before and after N iterations of a loop.
  args: (n)
+@end group
 
-0   constant current-time-string  ; @r{Push}
-                                  ;   @r{@code{current-time-string}}
+@group
+0   constant current-time-string  ; @r{Push @code{current-time-string}}
                                   ;   @r{onto top of stack.}
 @end group
-
 @group
-1   call     0              ; @r{Call @code{current-time-string}}
-                            ;   @r{with no argument,}
-                            ;   @r{pushing result onto stack.}
+1   call     0            ; @r{Call @code{current-time-string} with no}
+                          ;   @r{argument, push result onto stack.}
 @end group
-
 @group
-2   varbind  t1             ; @r{Pop stack and bind @code{t1}}
-                            ;   @r{to popped value.}
+2   varbind  t1           ; @r{Pop stack and bind @code{t1} to popped value.}
 @end group
-
 @group
-3:1 varref   n              ; @r{Get value of @code{n} from}
-                            ;   @r{the environment and push}
-                            ;   @r{the value onto the stack.}
-4   sub1                    ; @r{Subtract 1 from top of stack.}
+3:1 varref   n            ; @r{Get value of @code{n} from the environment}
+                          ;   @r{and push the value on the stack.}
+4   sub1                  ; @r{Subtract 1 from top of stack.}
 @end group
-
 @group
-5   dup                     ; @r{Duplicate the top of the stack;}
-                            ;   @r{i.e., copy the top of}
-                            ;   @r{the stack and push the}
-                            ;   @r{copy onto the stack.}
-6   varset   n              ; @r{Pop the top of the stack,}
-                            ;   @r{and bind @code{n} to the value.}
-
-                            ; @r{In effect, the sequence @code{dup varset}}
-                            ;   @r{copies the top of the stack}
-                            ;   @r{into the value of @code{n}}
-                            ;   @r{without popping it.}
+5   dup                   ; @r{Duplicate top of stack; i.e., copy the top}
+                          ;   @r{of the stack and push copy onto stack.}
+6   varset   n            ; @r{Pop the top of the stack,}
+                          ;   @r{and bind @code{n} to the value.}
+
+;; @r{(In effect, the sequence @code{dup varset} copies the top of the stack}
+;; @r{into the value of @code{n} without popping it.)}
 @end group
 
 @group
-7   constant 0              ; @r{Push 0 onto stack.}
-8   gtr                     ; @r{Pop top two values off stack,}
-                            ;   @r{test if @var{n} is greater than 0}
-                            ;   @r{and push result onto stack.}
+7   constant 0            ; @r{Push 0 onto stack.}
+8   gtr                   ; @r{Pop top two values off stack,}
+                          ;   @r{test if @var{n} is greater than 0}
+                          ;   @r{and push result onto stack.}
 @end group
-
 @group
-9   goto-if-not-nil 1       ; @r{Goto 1 if @code{n} > 0}
-                            ;   @r{(this continues the while loop)}
-                            ;   @r{else continue.}
+9   goto-if-not-nil 1     ; @r{Goto 1 if @code{n} > 0}
+                          ;   @r{(this continues the while loop)}
+                          ;   @r{else continue.}
 @end group
-
 @group
-12  varref   t1             ; @r{Push value of @code{t1} onto stack.}
+12  varref   t1           ; @r{Push value of @code{t1} onto stack.}
 13  constant current-time-string  ; @r{Push @code{current-time-string}}
-                                  ;   @r{onto top of stack.}
-14  call     0              ; @r{Call @code{current-time-string} again.}
+                                  ;   @r{onto the top of the stack.}
+14  call     0            ; @r{Call @code{current-time-string} again.}
 @end group
-
 @group
-15  unbind   1              ; @r{Unbind @code{t1} in local environment.}
-16  list2                   ; @r{Pop top two elements off stack,}
-                            ;   @r{create a list of them,}
-                            ;   @r{and push list onto stack.}
-17  return                  ; @r{Return value of the top of stack.}
+15  unbind   1            ; @r{Unbind @code{t1} in local environment.}
+16  list2                 ; @r{Pop top two elements off stack, create a}
+                          ;   @r{list of them, and push it onto stack.}
+17  return                ; @r{Return value of the top of stack.}
 @end group
 @end example
-