Previous: Byte-Code Objects, Up: Byte Compilation

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 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 buffer-or-name`

This command displays the disassembled code for

object. In interactive use, or ifbuffer-or-nameis`nil`

or omitted, the output goes in a buffer named*Disassemble*. Ifbuffer-or-nameis non-`nil`

, it must be a buffer or the name of an existing buffer. Then the output goes there, at point, and point is left before the output.The argument

objectcan be a function name, a lambda expression (see Lambda Expressions), or a byte-code object (see Byte-Code Objects). If it is a lambda expression,`disassemble`

compiles it and disassembles the resulting compiled code.

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 the value of`integer`

and ; push it 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 1, else continue. 6 constant 1 ; Push 1 onto top of stack. 7 return ; Return the top element of the stack. 8:1 varref integer ; Push value of`integer`

onto stack. 9 constant factorial ; Push`factorial`

onto stack. 10 varref integer ; Push value of`integer`

onto stack. 11 sub1 ; Pop`integer`

, decrement value, ; push new value onto stack. 12 call 1 ; Call function`factorial`

using first ; (i.e., top) stack element as argument; ; push returned value onto stack. 13 mult ; Pop top two values off stack, multiply ; them, and push result onto stack. 14 return ; Return the top element of the stack.

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, push 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 on the stack. 4 sub1 ; Subtract 1 from top of stack. 5 dup ; Duplicate top of stack; i.e., copy the top ; of the stack and push copy onto stack. 6 varset n ; Pop the top of the stack, ; and bind`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 1 if`n`

> 0 ; (this continues the while loop) ; else continue. 12 varref t1 ; Push value of`t1`

onto stack. 13 constant current-time-string ; Push`current-time-string`

; onto the top of the stack. 14 call 0 ; Call`current-time-string`

again. 15 unbind 1 ; Unbind`t1`

in local environment. 16 list2 ; Pop top two elements off stack, create a ; list of them, and push it onto stack. 17 return ; Return value of the top of stack.