Next: , Previous: , Up: Byte Compilation   [Contents][Index]


21.8 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.

(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   varref   integer        ; Get value of integer
                            ;   from the environment
                            ;   and push the value
                            ;   onto the stack.

1   constant 1              ; Push 1 onto stack.
2   eqlsign                 ; Pop top two values off stack,
                            ;   compare them,
                            ;   and push result onto stack.
3   goto-if-nil 1           ; Pop and test top of stack;
                            ;   if nil,
                            ;   go to label 1 (which is also byte 7),
                            ;   else continue.
5   constant 1              ; Push 1 onto top of stack.

6   return                  ; Return the top element
                            ;   of the stack.
7:1 varref   integer        ; Push value of integer onto stack.

8   constant factorial      ; Push factorial onto stack.

9   varref   integer        ; Push value of integer onto stack.

10  sub1                    ; Pop integer, decrement value,
                            ;   push new value onto stack.
                            ; Stack now contains:
                            ;   - decremented value of integer
                            ;   - factorial
                            ;   - value of integer
15  call     1              ; Call function factorial using
                            ;   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 to factorial
                            ;   - value of integer
12  mult                    ; Pop top two values off the stack,
                            ;   multiply them,
                            ;   pushing the result onto the stack.
13  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              ; Call current-time-string
                            ;    with no argument,
                            ;    pushing result onto stack.
2   varbind  t1             ; Pop stack and bind t1
                            ;   to popped value.
3:1 varref   n              ; Get value of n from
                            ;   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 set n to the value.

                            ; In effect, the sequence dup varset
                            ;   copies the top of the stack
                            ;   into the value of n
                            ;   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-not-nil 1       ; Goto label 1 (byte 3) if n <= 0
                            ;   (this exits the while loop).
                            ;   else pop top of stack
                            ;   and continue
11  varref   t1             ; Push value of t1 onto stack.
12  constant current-time-string  ; Push
                                  ;   current-time-string
                                  ;   onto top of stack.
13  call     0              ; Call current-time-string again.

14  unbind   1              ; Unbind t1 in local environment.
15  list2                   ; Pop top two elements off stack,
                            ;   create a list of them,
                            ;   and push list onto stack.
16  return                  ; Return the top element of the stack.

     ⇒ nil

Next: , Previous: , Up: Byte Compilation   [Contents][Index]