Next: Different Behaviour, Previous: Compiled-Function Objects, Up: Byte Compilation [Contents][Index]

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 ifnis 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
```