16.7 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.
  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
in calculations whose results are themselves pushed back on the stack.
When a byte-code function returns, it pops a value off the stack and
returns it as the value of the function.
  In addition to the stack, byte-code functions can use, bind, and set
ordinary Lisp variables, by transferring values between variables and
the stack.
- Command: disassemble object &optional stream
- This function prints the disassembled code for object.  If
stream is supplied, then output goes there.  Otherwise, the
disassembled code is printed to the stream standard-output.  The
argument object can be a function name or a lambda expression.
As a special exception, if this function is used interactively,
it outputs to a buffer named `*Disassemble*'.
 
  Here are two examples of using the 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 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.
|  | (defun factorial (integer)
  "Compute factorial of an integer."
  (if (= 1 integer) 1
    (* integer (factorial (1- integer)))))
     => factorial
(factorial 4)
     => 24
(disassemble 'factorial)
     -| byte-code for factorial:
 doc: Compute factorial of an integer.
 args: (integer)
0   constant 1              ; Push 1 onto stack.
1   varref   integer        ; Get value of integer;   from the environment
                            ;   and push the value
                            ;   onto the stack.
2   eqlsign                 ; Pop top two values off stack,
                            ;   compare them,
                            ;   and push result onto stack.
3   goto-if-nil 10          ; Pop and test top of stack;
                            ;   ifnil, go to 10,
                            ;   else continue.
6   constant 1              ; Push 1 onto top of stack.
7   goto     17             ; Go to 17 (in this case, 1 will be
                            ;   returned by the function).
10  constant *              ; Push symbol*onto stack.
11  varref   integer        ; Push value ofintegeronto stack.
12  constant factorial      ; Pushfactorialonto stack.
13  varref   integer        ; Push value ofintegeronto stack.
14  sub1                    ; Popinteger, decrement value,
                            ;   push new value onto stack.
                            ; Stack now contains:
                            ;   - decremented value ofinteger;   -factorial;   - value ofinteger;   -*15  call     1              ; Call functionfactorialusing
                            ;   the first (i.e., the top) element
                            ;   of the stack as the argument;
                            ;   push returned value onto stack.
                            ; Stack now contains:
                            ;   - result of recursive
                            ;        call tofactorial;   - value ofinteger;   -*16  call     2              ; Using the first two
                            ;   (i.e., the top two)
                            ;   elements of the stack
                            ;   as arguments,
                            ;   call the function*,
                            ;   pushing the result onto the stack.
17  return                  ; Return the top element
                            ;   of the stack.
     => nil | 
The 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)) 
              0))
    (list t1 (current-time-string))))
     => silly-loop
(disassemble 'silly-loop)
     -| byte-code for silly-loop:
 doc: Return time before and after N iterations of a loop.
 args: (n)
0   constant current-time-string  ; Push
                                  ;   current-time-string;   onto top of stack.
1   call     0              ; Callcurrent-time-string;    with no argument,
                            ;    pushing result onto stack.
2   varbind  t1             ; Pop stack and bindt1;   to popped value.
3   varref   n              ; Get value ofnfrom
                            ;   the environment and push
                            ;   the value onto the stack.
4   sub1                    ; Subtract 1 from top of stack.
5   dup                     ; Duplicate the top of the stack;
                            ;   i.e., copy the top of
                            ;   the stack and push the
                            ;   copy onto the stack.
6   varset   n              ; Pop the top of the stack,
                            ;   and bindnto the value.
                            ; In effect, the sequencedup varset;   copies the top of the stack
                            ;   into the value ofn;   without popping it.
7   constant 0              ; Push 0 onto stack.
8   gtr                     ; Pop top two values off stack,
                            ;   test if n is greater than 0
                            ;   and push result onto stack.
9   goto-if-nil-else-pop 17 ; Goto 17 ifn<= 0
                            ;   (this exits the while loop).
                            ;   else pop top of stack
                            ;   and continue
12  constant nil            ; Pushnilonto stack
                            ;   (this is the body of the loop).
13  discard                 ; Discard result of the body
                            ;   of the loop (a while loop
                            ;   is always evaluated for
                            ;   its side effects).
14  goto     3              ; Jump back to beginning
                            ;   of while loop.
17  discard                 ; Discard result of while loop
                            ;   by popping top of stack.
                            ;   This result is the valuenilthat
                            ;   was not popped by the goto at 9.
18  varref   t1             ; Push value oft1onto stack.
19  constant current-time-string  ; Push 
                                  ;current-time-string;   onto top of stack.
20  call     0              ; Callcurrent-time-stringagain.
21  list2                   ; Pop top two elements off stack,
                            ;   create a list of them,
                            ;   and push list onto stack.
22  unbind   1              ; Unbindt1in local environment.
23  return                  ; Return value of the top of stack.
     => nil | 
  
This document was generated
on May 2, 2002
using texi2html