37.3. The structure of compiled functions
Prev | Chapter 37. The CLISP bytecode specification | Next

## 37.3. The structure of compiled functions

A compiled function consists of two objects: The function itself, containing the references to all CLISP objects needed for the bytecode, and a byte vector containing only immediate data, including the bytecode proper.

Typically, the byte vector is about twice as large as the function vector. The separation thus helps the garbage collector (since the byte vector does not need to be scanned for pointers).

A function looks like this (cf. the C type Cclosure):

name
  This is the name of the function, normally a symbol or a list of the form `(`SETF` `symbol`)`. It is used for printing the function and for error messages. This field is immutable.
`codevec`
  This is the byte-code vector, a `(`VECTOR` (`UNSIGNED-BYTE` 8))`. This field is immutable.
`consts`[]
  The remaining fields in the function object are references to other CLISP objects. These references are immutable, which is why they are called “constants”. (The referenced CLISP objects can be mutable objects, such as `CONS`es or `VECTOR`s, however.)

### The Exception to the Immutability Rule

When a generic function's dispatch code is installed, the `codevec` and `consts` fields are destructively modified.

Some of the `consts` can play special roles. A function looks like this, in more detail:

name
  see name.
`codevec`
  see `codevec`.
`venv-const`*
  At most one object, representing the closed-up variables, representing the variables of the lexical environment in which this function was defined. It is a `SIMPLE-VECTOR`, which looks like this: `#(`next` `value1` ... `valuen`)` where `value1`, ..., `valuen` are the values of the closed-up variables, and `next` is either `NIL` or a `SIMPLE-VECTOR` having the same structure.
`block-const`*
  Objects representing closed-up `BLOCK` tags, representing the `BLOCK` tags of the lexical environment in which this function was defined. Each is a `CONS` containing in the `CDR` part: either a frame pointer to the block frame, or `#<DISABLED>`. The `CAR` is the block's name, for error messages only.
`tagbody-const`*
  Objects representing closed-up `TAGBODY` tags, representing the `TAGBODY` tags of the lexical environment in which this function was defined. Each is a `CONS` containing in the `CDR` part: either a frame pointer to the `TAGBODY` frame, or `#<DISABLED>` if the `TAGBODY` has already been left. The `CAR` is a `SIMPLE-VECTOR` containing the names of the `TAGBODY` tags, for error messages only.
`keyword-const`*
  If the function was defined with a lambda list containing `&KEY`, here come the symbols ("keywords"), in their correct order. They are used by the interpreter during function call.
`other-const`*
  Other objects needed by the function's bytecode.

If `venv-const`, `block-const`, `tagbody-const` are all absent, the function is called autonomous. This is the case if the function does not refer to lexical variables, blocks or tags defined in compile code outside of the function. In particular, it is the case if the function is defined in a null lexical environment.

If some `venv-const`, `block-const`, or `tagbody-const` are present, the function (a “closure”) is created at runtime. The compiler only generates a prototype, containing `NIL` values instead of each `venv-const`, `block-const`, `tagbody-const`. At runtime, a function is created by copying this prototype and replacing the `NIL` values by the definitive ones.

The list `(`keyword-const`* `other-const`*)` normally does not contain duplicates, because the compiler removes duplicates when possible. (Duplicates can occur nevertheless, through the use of `LOAD-TIME-VALUE`.)

The `codevec` looks like this (cf. the C type Codevec):

`spdepth_1` (2 bytes)
  The 1st part of the maximal `SP` depth.
`spdepth_jmpbufsize` (2 bytes)
  The `jmpbufsize` part of the maximal `SP` depth. The maximal `SP` depth (precomputed by the compiler) is given by `spdepth_1 + spdepth_jmpbufsize * `jmpbufsize``.
`numreq` (2 bytes)
  Number of required parameters.
`numopt` (2 bytes)
  Number of optional parameters.
`flags` (1 byte)
  bit 0
    set if the function has the `&REST` parameter
  bit 7
    set if the function has `&KEY` parameters
  bit 6
    set if the function has `&ALLOW-OTHER-KEYS`
  bit 4
    set if the function is a generic function
  bit 3
    set if the function is a generic function and its effective method shall be returned (instead of being executed)
  bit 2
    set if the full original lambda list is kept in the closure object, see Section 3.3.6, “Declaration `SPACE`”
  bit 1
    set if the `FUNCTION` `DOCUMENTATION` `STRING` is kept in the closure object, see Section 3.3.6, “Declaration `SPACE`”
`signature` (1 byte)
  An abbreviation code depending on `numreq`, `numopt`, `flags`. It is used for speeding up the function call.
`numkey` (2 bytes, only if the function has `&KEY`)
  The number of `&KEY` parameters.
`keyconsts` (2 bytes, only if the function has `&KEY`)
  The offset of the `keyword-const` in the function.
`byte`* (any number of bytes)
  The bytecode instructions.

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
37.2. The virtual machine | Home | 37.4. The general structure of the instructions