X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=man%2Flispref%2Fcompile.texi;h=d3f3cbe42d79a876265dab79314e1c7540e0f211;hb=682b150413bbb86eadb481299953bc42c8faca92;hp=47b3dd750ef53bd7a9da077e55ff9ab480fe27de;hpb=6883ee56ec887c2c48abe5b06b5e66aa74031910;p=chise%2Fxemacs-chise.git- diff --git a/man/lispref/compile.texi b/man/lispref/compile.texi index 47b3dd7..d3f3cbe 100644 --- a/man/lispref/compile.texi +++ b/man/lispref/compile.texi @@ -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{} #}. 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{#}. 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 -# @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.