(A-RUI6-E079): New abstract node.
[chise/xemacs-chise.git.1] / man / lispref / compile.texi
index 47b3dd7..d3f3cbe 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the XEmacs Lisp Reference Manual.
-@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 
+@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
 @c See the file lispref.texi for copying conditions.
 @setfilename ../../info/compile.info
 @node Byte Compilation, Debugging, Loading, Top
@@ -24,6 +24,13 @@ In general, any version of Emacs can run byte-compiled code produced
 by recent earlier versions of Emacs, but the reverse is not true.  In
 particular, if you compile a program with XEmacs 20, the compiled code
 may not run in earlier versions.
+
+The first time a compiled-function object is executed, the byte-code
+instructions are validated and the byte-code is further optimized.  An
+@code{invalid-byte-code} error is signaled if the byte-code is invalid,
+for example if it contains invalid opcodes.  This usually means a bug in
+the byte compiler.
+
 @iftex
 @xref{Docs and Compilation}.
 @end iftex
@@ -34,11 +41,13 @@ byte compilation.
 @menu
 * Speed of Byte-Code::          An example of speedup from byte compilation.
 * Compilation Functions::       Byte compilation functions.
+* Compilation Options::         Controlling the byte compiler's behavior.
 * Docs and Compilation::        Dynamic loading of documentation strings.
 * Dynamic Loading::             Dynamic loading of individual functions.
 * Eval During Compile::        Code to be evaluated when you compile.
 * Compiled-Function Objects::  The data type used for byte-compiled functions.
 * Disassembly::                 Disassembling byte-code; how to read byte-code.
+* Different Behavior::          When compiled code gives different results.
 @end menu
 
 @node Speed of Byte-Code
@@ -53,7 +62,7 @@ Here is an example:
 (defun silly-loop (n)
   "Return time before and after N iterations of a loop."
   (let ((t1 (current-time-string)))
-    (while (> (setq n (1- n)) 
+    (while (> (setq n (1- n))
               0))
     (list t1 (current-time-string))))
 @result{} silly-loop
@@ -61,14 +70,13 @@ Here is an example:
 
 @group
 (silly-loop 5000000)
-@result{} ("Fri Nov 28 20:56:16 1997"
-    "Fri Nov 28 20:56:39 1997")  ; @r{23 seconds}
+@result{} ("Mon Sep 14 15:51:49 1998"
+    "Mon Sep 14 15:52:07 1998")  ; @r{18 seconds}
 @end group
 
 @group
 (byte-compile 'silly-loop)
 @result{} #<compiled-function
-(from "loadup.el")
 (n)
 "...(23)"
 [current-time-string t1 n 0]
@@ -78,12 +86,12 @@ Here is an example:
 
 @group
 (silly-loop 5000000)
-@result{} ("Fri Nov 28 20:57:49 1997"
-    "Fri Nov 28 20:57:55 1997")  ; @r{6 seconds}
+@result{} ("Mon Sep 14 15:53:43 1998"
+    "Mon Sep 14 15:53:49 1998")  ; @r{6 seconds}
 @end group
 @end example
 
-  In this example, the interpreted code required 23 seconds to run,
+  In this example, the interpreted code required 18 seconds to run,
 whereas the byte-compiled code required 6 seconds.  These results are
 representative, but actual results will vary greatly.
 
@@ -109,7 +117,7 @@ for proper compilation.  For more details, see @ref{Compiling Macros}.
   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
+are available during compilation is to @code{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
@@ -141,7 +149,6 @@ way to ``compile the same definition again.''
 @group
 (byte-compile 'factorial)
 @result{} #<compiled-function
-(from "loadup.el")
 (integer)
 "...(21)"
 [integer 1 factorial]
@@ -202,24 +209,30 @@ for the file name.
 @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
+-rw-r--r--  1 lewis     638 Oct  8 20:25 push.elc
 @end group
 @end example
 @end deffn
 
 @c flag is not optional in FSF Emacs
-@deffn Command byte-recompile-directory directory &optional flag
+@deffn Command byte-recompile-directory directory &optional flag norecursion force
 @cindex library compilation
 This function recompiles every @samp{.el} file in @var{directory} that
 needs recompilation.  A file needs recompilation if a @samp{.elc} file
 exists but is older than the @samp{.el} file.
 
+Files in subdirectories of @var{directory} are also processed unless
+optional argument @var{norecursion} is non-@code{nil}.
+
 When a @samp{.el} file has no corresponding @samp{.elc} file, then
 @var{flag} says what to do.  If it is @code{nil}, these files are
 ignored.  If it is non-@code{nil}, the user is asked whether to compile
 each such file.
 
-The returned value of this command is unpredictable.
+If the fourth optional argument @var{force} is non-@code{nil},
+recompile every @samp{.el} file that already has a @samp{.elc} file.
+
+The return value of this command is unpredictable.
 @end deffn
 
 @defun batch-byte-compile
@@ -230,7 +243,7 @@ prevent processing of subsequent files.  (The file that gets the error
 will not, of course, produce any compiled code.)
 
 @example
-% emacs -batch -f batch-byte-compile *.el
+% xemacs -batch -f batch-byte-compile *.el
 @end example
 @end defun
 
@@ -243,22 +256,311 @@ command line.
 
 @c XEmacs feature
 @defvar byte-recompile-directory-ignore-errors-p
-  If non-@code{nil}, this specifies that @code{byte-recompile-directory}
-will continue compiling even when an error occurs in a file.  This is
-normally @code{nil}, but is bound to @code{t} by
-@code{batch-byte-recompile-directory}.
+  When non-@code{nil}, @code{byte-recompile-directory} will continue
+compiling even when an error occurs in a file.  Default: @code{nil}, but
+bound to @code{t} by @code{batch-byte-recompile-directory}.
 @end defvar
 
-@defun byte-code code-string data-vector max-stack
+@c XEmacs feature (?)
+@defvar byte-recompile-directory-recursively
+   When non-@code{nil}, @code{byte-recompile-directory} will recurse on
+subdirectories.  Default: @code{t}.
+@end defvar
+
+
+@defun byte-code instructions constants stack-depth
 @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.
+This function actually interprets byte-code.
+Don't call this function yourself.  Only the byte compiler knows how to
+generate valid calls to this function.
 
-In newer Emacs versions (19 and up), byte-code is usually executed as
+In newer Emacs versions (19 and up), byte code is usually executed as
 part of a compiled-function object, and only rarely due to an explicit
-call to @code{byte-code}.
+call to @code{byte-code}.  A byte-compiled function was once actually
+defined with a body that calls @code{byte-code}, but in recent versions
+of Emacs @code{byte-code} is only used to run isolated fragments of lisp
+code without an associated argument list.
+@end defun
+
+@node Compilation Options
+@section Options for the Byte Compiler
+@cindex compilation options
+
+Warning: this node is a quick draft based on docstrings.  There may be
+inaccuracies, as the docstrings occasionally disagree with each other.
+This has not been checked yet.
+
+The byte compiler and optimizer are controlled by the following
+variables.  The @code{byte-compiler-options} macro described below
+provides a convenient way to set most of them on a file-by-file basis.
+
+@defvar emacs-lisp-file-regexp
+Regexp which matches Emacs Lisp source files.
+You may want to redefine @code{byte-compile-dest-file} if you change
+this.  Default: @code{"\\.el$"}.
+@end defvar
+
+@defun byte-compile-dest-file filename
+Convert an Emacs Lisp source file name to a compiled file name.  This
+function may be redefined by the user, if necessary, for compatibility
+with @code{emacs-lisp-file-regexp}.
+@end defun
+
+@c ;; This can be the 'byte-compile property of any symbol.
+@c (autoload 'byte-compile-inline-expand "byte-optimize")
+
+@defvar byte-compile-verbose
+When non-@code{nil}, print messages describing progress of
+byte-compiler.  Default: @code{t} if interactive on a not-too-slow
+terminal (see @code{search-slow-speed}), otherwise @code{nil}.
+@end defvar
+
+@defvar byte-optimize
+Level of optimization in the byte compiler.
+
+@table @code
+@item nil
+Do no optimization.
+
+@item t
+Do all optimizations.
+
+@item source
+Do optimizations manipulating the source code only.
+
+@item byte
+Do optimizations manipulating the byte code (actually, LAP code) only.
+@end table
+Default: @code{t}.
+@end defvar
+
+@defvar byte-compile-delete-errors
+When non-@code{nil}, the optimizer may delete forms that may signal an
+error if that is the only change in the function's behavior.
+This includes variable references and calls to functions such as
+@code{car}.
+Default: @code{t}.
+@end defvar
+
+@defvar byte-optimize-log nil
+When non-@code{nil}, the byte-compiler logs optimizations into
+@file{*Compile-Log*}.
+
+@table @code
+@item nil
+Log no optimization.
+
+@item t
+Log all optimizations.
+
+@item source
+Log optimizations manipulating the source code only.
+
+@item byte
+Log optimizations manipulating the byte code (actually, LAP code) only.
+@end table
+Default: @code{nil}.
+@end defvar
+
+@defvar byte-compile-error-on-warn
+When non-@code{nil}, the byte-compiler reports warnings with @code{error}.
+Default:  @code{nil}.
+@end defvar
+
+@defvar byte-compile-default-warnings
+The warnings used when @code{byte-compile-warnings} is @code{t}.  Called
+@code{byte-compile-warning-types} in GNU Emacs.
+Default: @code{(redefine callargs subr-callargs free-vars unresolved
+unused-vars obsolete)}.
+@end defvar
+
+@defvar byte-compile-warnings
+
+List of warnings that the compiler should issue (@code{t} for the
+default set).  Elements of the list may be:
+
+@table @code
+@item free-vars
+References to variables not in the current lexical scope.
+
+@item unused-vars
+References to non-global variables bound but not referenced.
+
+@item unresolved
+Calls to unknown functions.
+
+@item callargs
+Lambda calls with args that don't match the definition.
+
+@item subr-callargs
+Calls to subrs with args that don't match the definition.
+
+@item redefine
+Function cell redefined from a macro to a lambda or vice
+versa, or redefined to take a different number of arguments.
+
+@item obsolete
+Use of an obsolete function or variable.
+
+@item pedantic
+Warn of use of compatible symbols.
+@end table
+
+The default set is specified by @code{byte-compile-default-warnings} and
+normally encompasses all possible warnings.
+
+See also the macro @code{byte-compiler-options}.  Default: @code{t}.
+@end defvar
+
+The compiler can generate a call graph, which gives information about
+which functions call which functions.
+
+@defvar byte-compile-generate-call-tree
+When non-@code{nil}, the compiler generates a call graph.  This records
+functions that were called and from where.  If the value is @code{t},
+compilation displays the call graph when it finishes.  If the value is
+neither @code{t} nor @code{nil}, compilation asks you whether to display
+the graph.
+
+The call tree only lists functions called, not macros used. Those
+functions which the byte-code interpreter knows about directly
+(@code{eq}, @code{cons}, etc.) are not reported.
+
+The call tree also lists those functions which are not known to be called
+(that is, to which no calls have been compiled).  Functions which can be
+invoked interactively are excluded from this list.  Default: @code{nil}.
+@end defvar
+
+@defvar byte-compile-call-tree nil
+
+Alist of functions and their call tree, used internally.
+Each element takes the form
+
+  (@var{function} @var{callers} @var{calls})
+
+where @var{callers} is a list of functions that call @var{function}, and
+@var{calls} is a list of functions for which calls were generated while
+compiling @var{function}.
+@end defvar
+
+@defvar byte-compile-call-tree-sort
+When non-@code{nil}, sort the call tree.  The values @code{name},
+@code{callers}, @code{calls}, and @code{calls+callers} specify different
+fields to sort on.")  Default: @code{name}.
+@end defvar
+
+@code{byte-compile-overwrite-file} controls treatment of existing
+compiled files.
+
+@defvar byte-compile-overwrite-file
+When non-@code{nil}, do not preserve backups of @file{.elc}s.
+Precisely, if @code{nil}, old @file{.elc} files are deleted before the
+new one is saved, and @file{.elc} files will have the same modes as the
+corresponding @file{.el} file.  Otherwise, existing @file{.elc} files
+will simply be overwritten, and the existing modes will not be changed.
+If this variable is @code{nil}, then an @file{.elc} file which is a
+symbolic link will be turned into a normal file, instead of the file
+which the link points to being overwritten.  Default: @code{t}.
+@end defvar
+
+Variables controlling recompiling directories are described elsewhere
+@xref{Compilation Functions}.  They are
+@code{byte-recompile-directory-ignore-errors-p} and
+@code{byte-recompile-directory-recursively}.
+
+The dynamic loading features are described elsewhere.  These are
+controlled by the variables @code{byte-compile-dynamic} (@pxref{Dynamic
+Loading}) and @code{byte-compile-dynamic-docstrings} (@pxref{Docs and
+Compilation}).
+
+The byte compiler is a relatively recent development, and has evolved
+significantly over the period covering Emacs versions 19 and 20.  The
+following variables control use of newer functionality by the byte
+compiler.  These are rarely needed since the release of XEmacs 21.
+
+Another set of compatibility issues arises between Mule and non-Mule
+XEmacsen; there are no known compatibility issues specific to the byte
+compiler.  There are also compatibility issues between XEmacs and GNU
+Emacs's versions of the byte compiler.  While almost all of the byte
+codes are the same, and code compiled by one version often runs
+perfectly well on the other, this is very dangerous, and can result in
+crashes or data loss.  Always recompile your Lisp when moving between
+XEmacs and GNU Emacs.
+
+@defvar byte-compile-single-version nil
+When non-@code{nil}, the choice of emacs version (v19 or v20) byte-codes
+will be hard-coded into bytecomp when it compiles itself.  If the
+compiler itself is compiled with optimization, this causes a speedup.
+Default: @code{nil}.
+@end defvar
+
+@defvar byte-compile-emacs19-compatibility
+When non-@code{nil} generate output that can run in Emacs 19.
+Default: @code{nil} when Emacs version is 20 or above, otherwise
+@code{t}.
+@end defvar
+
+@defvar byte-compile-print-gensym
+When non-@code{nil}, the compiler may generate code that creates unique
+symbols at run-time.  This is achieved by printing uninterned symbols
+using the @code{#:@var{}} notation, so that they will be read uninterned
+when run.
+
+With this feature, code that uses uninterned symbols in macros will
+not be runnable under pre-21.0 XEmacsen.
+
+Default: When @code{byte-compile-emacs19-compatibility} is non-nil, this
+variable is ignored and considered to be @code{nil}.  Otherwise
+@code{t}.
+@end defvar
+
+@defvar byte-compile-new-bytecodes
+This is completely ignored.  For backwards compatibility.
+@end defvar
+
+@defun byte-compiler-options &rest args
+Set some compilation-parameters for this file.  
+This will affect only the file in which it appears; this does nothing when
+evaluated, or when loaded from a @file{.el} file.
+
+Each argument to this macro must be a list of a key and a value.
+(#### Need to check whether the newer variables are settable here.)
+
+@example
+  Keys:                  Values:               Corresponding variable:
+
+  verbose        t, nil                byte-compile-verbose
+  optimize       t, nil, source, byte  byte-optimize
+  warnings       list of warnings      byte-compile-warnings
+  file-format    emacs19, emacs20      byte-compile-emacs19-compatibility
+@end example
+
+The value specified with the @code{warnings}option must be a list,
+containing some subset of the following flags:
+
+@example
+  free-vars    references to variables not in the current lexical scope.
+  unused-vars  references to non-global variables bound but not referenced.
+  unresolved   calls to unknown functions.
+  callargs     lambda calls with args that don't match the definition.
+  redefine     function cell redefined from a macro to a lambda or vice
+               versa, or redefined to take a different number of arguments.
+@end example
+
+If the first element if the list is @code{+} or `@code{} then the
+specified elements are added to or removed from the current set of
+warnings, instead of the entire set of warnings being overwritten.
+(#### Need to check whether the newer warnings are settable here.)
+
+For example, something like this might appear at the top of a source file:
+
+@example
+    (byte-compiler-options
+      (optimize t)
+      (warnings (- callargs))          ; Don't warn about arglist mismatch
+      (warnings (+ unused-vars))       ; Do warn about unused bindings
+      (file-format emacs19))
+@end example
 @end defun
 
 @node Docs and Compilation
@@ -297,13 +599,14 @@ 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.
 
-  Byte-compiled files made with Emacs 19.29 will not load into older
-versions because the older versions don't support this feature.  You can
-turn off this feature by setting @code{byte-compile-dynamic-docstrings}
-to @code{nil}.  Once this is done, you can compile files that will load
-into older Emacs versions.  You can do this globally, or for one source
-file by specifying a file-local binding for the variable.  Here's one
-way to do that:
+  Versions of Emacs up to and including XEmacs 19.14 and FSF Emacs 19.28
+do not support the dynamic docstrings feature, and so will not be able
+to load bytecode created by more recent Emacs versions.  You can turn
+off the dynamic docstring feature by setting
+@code{byte-compile-dynamic-docstrings} to @code{nil}.  Once this is
+done, you can compile files that will load into older Emacs versions.
+You can do this globally, or for one source file by specifying a
+file-local binding for the variable.  Here's one way to do that:
 
 @example
 -*-byte-compile-dynamic-docstrings: nil;-*-
@@ -312,6 +615,7 @@ way to do that:
 @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.
+Default: t.
 @end defvar
 
 @cindex @samp{#@@@var{count}}
@@ -372,6 +676,7 @@ specific source files with file-local variable bindings, like this:
 @defvar byte-compile-dynamic
 If this is non-@code{nil}, the byte compiler generates compiled files
 that are set up for dynamic function loading.
+Default: nil.
 @end defvar
 
 @defun fetch-bytecode function
@@ -415,23 +720,21 @@ At top level, this is analogous to the Common Lisp idiom
 @cindex byte-code function
 
   Byte-compiled functions have a special data type: they are
-@dfn{compiled-function objects}.
-
-  A compiled-function object is a bit 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 compiled-function
-object normally begins with @samp{#<compiled-function} and ends with
-@samp{>}.  However, if the variable @code{print-readably} is
-non-@code{nil}, the object is printed beginning with @samp{#[} and
-ending with @samp{]}.  This representation can be read directly
-by the Lisp reader, and is used in byte-compiled files (those ending
-in @samp{.elc}).
+@dfn{compiled-function objects}. The evaluator handles this data type
+specially when it appears as a function to be called.
+
+  The printed representation for a compiled-function object normally
+begins with @samp{#<compiled-function} and ends with @samp{>}.  However,
+if the variable @code{print-readably} is non-@code{nil}, the object is
+printed beginning with @samp{#[} and ending with @samp{]}.  This
+representation can be read directly by the Lisp reader, and is used in
+byte-compiled files (those ending in @samp{.elc}).
 
   In Emacs version 18, there was no compiled-function object data type;
 compiled functions used the function @code{byte-code} to run the byte
 code.
 
-  A compiled-function object has a number of different elements.
+  A compiled-function object has a number of different attributes.
 They are:
 
 @table @var
@@ -445,7 +748,7 @@ The string containing the byte-code instructions.
 The vector of Lisp objects referenced by the byte code.  These include
 symbols used as function names and variable names.
 
-@item stacksize
+@item stack-depth
 The maximum stack size this function needs.
 
 @item doc-string
@@ -470,8 +773,8 @@ representation.  It is the definition of the command
 @code{backward-sexp}.
 
 @example
-#<compiled-function
-(from "lisp.elc")
+(symbol-function 'backward-sexp)
+@result{} #<compiled-function
 (&optional arg)
 "...(15)" [arg 1 forward-sexp] 2 854740 "_p">
 @end example
@@ -479,9 +782,9 @@ representation.  It is the definition of the command
   The primitive way to create a compiled-function object is with
 @code{make-byte-code}:
 
-@defun make-byte-code &rest elements
+@defun make-byte-code arglist instructions constants stack-depth &optional doc-string interactive
 This function constructs and returns a compiled-function object
-with @var{elements} as its elements.
+with the specified attributes.
 
 @emph{Please note:} Unlike all other Emacs-lisp functions, calling this with
 five arguments is @emph{not} the same as calling it with six arguments,
@@ -516,7 +819,7 @@ This function returns the vector of Lisp objects referenced by
 compiled-function object @var{function}.
 @end defun
 
-@defun compiled-function-stack-size function
+@defun compiled-function-stack-depth function
 This function returns the maximum stack size needed by compiled-function
 object @var{function}.
 @end defun
@@ -571,9 +874,6 @@ it outputs to a buffer named @samp{*Disassemble*}.
   Here are two examples of using the @code{disassemble} function.  We
 have added explanatory comments to help you relate the byte-code to the
 Lisp source; these do not appear in the output of @code{disassemble}.
-These examples show unoptimized byte-code.  Nowadays byte-code is
-usually optimized, but we did not want to rewrite these examples, since
-they still serve their purpose.
 
 @example
 @group
@@ -597,12 +897,12 @@ they still serve their purpose.
 @end group
 
 @group
-0   constant 1              ; @r{Push 1 onto stack.}
-
-1   varref   integer        ; @r{Get value of @code{integer}} 
+0   varref   integer        ; @r{Get value of @code{integer}}
                             ;   @r{from the environment}
                             ;   @r{and push the value}
                             ;   @r{onto the stack.}
+
+1   constant 1              ; @r{Push 1 onto stack.}
 @end group
 
 @group
@@ -612,39 +912,35 @@ they still serve their purpose.
 @end group
 
 @group
-3   goto-if-nil 10          ; @r{Pop and test top of stack;}
-                            ;   @r{if @code{nil}, go to 10,}
+3   goto-if-nil 1           ; @r{Pop and test top of stack;}
+                            ;   @r{if @code{nil},}
+                            ;   @r{go to label 1 (which is also byte 7),}
                             ;   @r{else continue.}
 @end group
 
 @group
-6   constant 1              ; @r{Push 1 onto top of stack.}
+5   constant 1              ; @r{Push 1 onto top of stack.}
 
-7   goto     17             ; @r{Go to 17 (in this case, 1 will be}
-                            ;   @r{returned by the function).}
+6   return                  ; @r{Return the top element}
+                            ;   @r{of the stack.}
 @end group
 
-@group
-10  constant *              ; @r{Push symbol @code{*} onto stack.}
-
-11  varref   integer        ; @r{Push value of @code{integer} onto stack.}
-@end group
+7:1 varref   integer        ; @r{Push value of @code{integer} onto stack.}
 
 @group
-12  constant factorial      ; @r{Push @code{factorial} onto stack.}
+8   constant factorial      ; @r{Push @code{factorial} onto stack.}
 
-13  varref   integer        ; @r{Push value of @code{integer} onto stack.}
+9   varref   integer        ; @r{Push value of @code{integer} onto stack.}
 
-14  sub1                    ; @r{Pop @code{integer}, decrement value,}
+10  sub1                    ; @r{Pop @code{integer}, decrement value,}
                             ;   @r{push new value onto stack.}
 @end group
 
 @group
                             ; @r{Stack now contains:}
                             ;   @minus{} @r{decremented value of @code{integer}}
-                            ;   @minus{} @r{@code{factorial}} 
+                            ;   @minus{} @r{@code{factorial}}
                             ;   @minus{} @r{value of @code{integer}}
-                            ;   @minus{} @r{@code{*}}
 @end group
 
 @group
@@ -659,20 +955,16 @@ they still serve their purpose.
                             ;   @minus{} @r{result of recursive}
                             ;        @r{call to @code{factorial}}
                             ;   @minus{} @r{value of @code{integer}}
-                            ;   @minus{} @r{@code{*}}
 @end group
 
 @group
-16  call     2              ; @r{Using the first two}
-                            ;   @r{(i.e., the top two)}
-                            ;   @r{elements of the stack}
-                            ;   @r{as arguments,}
-                            ;   @r{call the function @code{*},}
+12  mult                    ; @r{Pop top two values off the stack,}
+                            ;   @r{multiply them,}
                             ;   @r{pushing the result onto the stack.}
 @end group
 
 @group
-17  return                  ; @r{Return the top element}
+13  return                  ; @r{Return the top element}
                             ;   @r{of the stack.}
      @result{} nil
 @end group
@@ -685,7 +977,7 @@ The @code{silly-loop} function is somewhat more complex:
 (defun silly-loop (n)
   "Return time before and after N iterations of a loop."
   (let ((t1 (current-time-string)))
-    (while (> (setq n (1- n)) 
+    (while (> (setq n (1- n))
               0))
     (list t1 (current-time-string))))
      @result{} silly-loop
@@ -714,7 +1006,7 @@ The @code{silly-loop} function is somewhat more complex:
 @end group
 
 @group
-3   varref   n              ; @r{Get value of @code{n} from}
+3:1 varref   n              ; @r{Get value of @code{n} from}
                             ;   @r{the environment and push}
                             ;   @r{the value onto the stack.}
 @end group
@@ -728,11 +1020,9 @@ The @code{silly-loop} function is somewhat more complex:
                             ;   @r{i.e., copy the top of}
                             ;   @r{the stack and push the}
                             ;   @r{copy onto the stack.}
-@end group
 
-@group
 6   varset   n              ; @r{Pop the top of the stack,}
-                            ;   @r{and bind @code{n} to the value.}
+                            ;   @r{and set @code{n} to the value.}
 
                             ; @r{In effect, the sequence @code{dup varset}}
                             ;   @r{copies the top of the stack}
@@ -742,72 +1032,76 @@ The @code{silly-loop} function is somewhat more complex:
 
 @group
 7   constant 0              ; @r{Push 0 onto stack.}
-@end group
 
-@group
 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-nil-else-pop 17 ; @r{Goto 17 if @code{n} <= 0}
+9   goto-if-not-nil 1       ; @r{Goto label 1 (byte 3) if @code{n} <= 0}
                             ;   @r{(this exits the while loop).}
                             ;   @r{else pop top of stack}
                             ;   @r{and continue}
 @end group
 
 @group
-12  constant nil            ; @r{Push @code{nil} onto stack}
-                            ;   @r{(this is the body of the loop).}
-@end group
-
-@group
-13  discard                 ; @r{Discard result of the body}
-                            ;   @r{of the loop (a while loop}
-                            ;   @r{is always evaluated for}
-                            ;   @r{its side effects).}
-@end group
-
-@group
-14  goto     3              ; @r{Jump back to beginning}
-                            ;   @r{of while loop.}
+11  varref   t1             ; @r{Push value of @code{t1} onto stack.}
 @end group
 
 @group
-17  discard                 ; @r{Discard result of while loop}
-                            ;   @r{by popping top of stack.}
-                            ;   @r{This result is the value @code{nil} that}
-                            ;   @r{was not popped by the goto at 9.}
-@end group
-
-@group
-18  varref   t1             ; @r{Push value of @code{t1} onto stack.}
-@end group
-
-@group
-19  constant current-time-string  ; @r{Push} 
+12  constant current-time-string  ; @r{Push}
                                   ;   @r{@code{current-time-string}}
                                   ;   @r{onto top of stack.}
 @end group
 
 @group
-20  call     0              ; @r{Call @code{current-time-string} again.}
+13  call     0              ; @r{Call @code{current-time-string} again.}
+
+14  unbind   1              ; @r{Unbind @code{t1} in local environment.}
 @end group
 
 @group
-21  list2                   ; @r{Pop top two elements off stack,}
+15  list2                   ; @r{Pop top two elements off stack,}
                             ;   @r{create a list of them,}
                             ;   @r{and push list onto stack.}
 @end group
 
 @group
-22  unbind   1              ; @r{Unbind @code{t1} in local environment.}
-
-23  return                  ; @r{Return value of the top of stack.}
+16  return                  ; @r{Return the top element of the stack.}
 
      @result{} nil
 @end group
 @end example
 
 
+@node Different Behavior
+@section Different Behavior
+
+The intent is that compiled byte-code and the corresponding code
+executed by the Lisp interpreter produce identical results.  However,
+there are some circumstances where the results will differ.
+
+@itemize @bullet
+@item
+Arithmetic operations may be rearranged for efficiency or compile-time
+evaluation.  When floating point numbers are involved, this may produce
+different values or an overflow.
+@item
+Some arithmetic operations may be optimized away.  For example, the
+expression @code{(+ x)} may be optimized to simply @code{x}.  If the
+value of @code{x} is a marker, then the value will be a marker instead
+of an integer.  If the value of @samp{x} is a cons cell, then the
+interpreter will issue an error, while the bytecode will not.
+
+If you're trying to use @samp{(+ @var{object} 0)} to convert
+@var{object} to integer, consider using an explicit conversion function,
+which is clearer and guaranteed to work.
+Instead of @samp{(+ @var{marker} 0)}, use @samp{(marker-position @var{marker})}.
+Instead of @samp{(+ @var{char} 0)}, use @samp{(char-int @var{char})}.
+@end itemize
+
+For maximal equivalence between interpreted and compiled code, the
+variables @code{byte-compile-delete-errors} and
+@code{byte-compile-optimize} can be set to @code{nil}, but this is not
+recommended.