@end group
@group
-(silly-loop 100000)
-@result{} ("Fri Mar 18 17:25:57 1994"
- "Fri Mar 18 17:26:28 1994") ; @r{31 seconds}
+(silly-loop 50000000)
+@result{} ("Wed Mar 11 21:10:19 2009"
+ "Wed Mar 11 21:10:41 2009") ; @r{22 seconds}
@end group
@group
@end group
@group
-(silly-loop 100000)
-@result{} ("Fri Mar 18 17:26:52 1994"
- "Fri Mar 18 17:26:58 1994") ; @r{6 seconds}
+(silly-loop 50000000)
+@result{} ("Wed Mar 11 21:12:26 2009"
+ "Wed Mar 11 21:12:32 2009") ; @r{6 seconds}
@end group
@end example
- In this example, the interpreted code required 31 seconds to run,
+ 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.
@section Disassembled Byte-Code
@cindex disassembled byte-code
- People do not write byte-code; that job is left to the byte compiler.
-But we provide a disassembler to satisfy a cat-like curiosity. The
-disassembler converts the byte-compiled code into humanly readable
-form.
+ People do not write byte-code; that job is left to the byte
+compiler. But we provide a disassembler to satisfy a cat-like
+curiosity. The disassembler converts the byte-compiled code into
+human-readable form.
The byte-code interpreter is implemented as a simple stack machine.
It pushes values onto a stack of its own, then pops them off to use them
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
@end group
@group
-0 constant 1 ; @r{Push 1 onto stack.}
-
-1 varref integer ; @r{Get value of @code{integer}}
- ; @r{from the environment}
- ; @r{and push the value}
- ; @r{onto the stack.}
+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.}
@end group
@group
-2 eqlsign ; @r{Pop top two values off stack,}
- ; @r{compare them,}
- ; @r{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 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}, go to 1,}
; @r{else continue.}
-@end group
-
-@group
6 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).}
-@end group
-
-@group
-10 constant * ; @r{Push symbol @code{*} onto stack.}
-
-11 varref integer ; @r{Push value of @code{integer} onto stack.}
+7 return ; @r{Return the top element}
+ ; @r{of the stack.}
@end group
@group
-12 constant factorial ; @r{Push @code{factorial} onto stack.}
-
-13 varref integer ; @r{Push value of @code{integer} onto stack.}
-
-14 sub1 ; @r{Pop @code{integer}, decrement value,}
+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.}
-@end group
-
-@group
- ; @r{Stack now contains:}
- ; @minus{} @r{decremented value of @code{integer}}
- ; @minus{} @r{@code{factorial}}
- ; @minus{} @r{value of @code{integer}}
- ; @minus{} @r{@code{*}}
-@end group
-
-@group
-15 call 1 ; @r{Call function @code{factorial} using}
+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.}
@end group
@group
- ; @r{Stack now contains:}
- ; @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{*},}
- ; @r{pushing the result onto the stack.}
-@end group
-
-@group
-17 return ; @r{Return the top element}
- ; @r{of the stack.}
- @result{} nil
+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.}
@end group
@end example
@group
1 call 0 ; @r{Call @code{current-time-string}}
- ; @r{ with no argument,}
- ; @r{ pushing result onto stack.}
+ ; @r{with no argument,}
+ ; @r{pushing result onto stack.}
@end group
@group
@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
-
-@group
4 sub1 ; @r{Subtract 1 from top of stack.}
@end group
; @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.}
@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}
- ; @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.}
-@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.}
+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
-19 constant current-time-string ; @r{Push}
- ; @r{@code{current-time-string}}
+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.}
@end group
@group
-20 call 0 ; @r{Call @code{current-time-string} again.}
-@end group
-
-@group
-21 list2 ; @r{Pop top two elements off stack,}
+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.}
-@end group
-
-@group
-22 unbind 1 ; @r{Unbind @code{t1} in local environment.}
-
-23 return ; @r{Return value of the top of stack.}
-
- @result{} nil
+17 return ; @r{Return value of the top of stack.}
@end group
@end example