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):
(SETF symbol).
   It is used for printing the function and for error messages.
   This field is immutable.codevec(VECTOR (UNSIGNED-BYTE 8)).
    This field is immutable.consts[]CONSes or VECTORs, however.)
 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:
codeveccodevec.
 venv-const*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*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*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*&KEY, here come the symbols ("keywords"), in their
   correct order.  They are used by the interpreter during function call.
  other-const*
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 ( normally does not contain duplicates, because
the compiler removes duplicates when possible.  (Duplicates can occur
nevertheless, through the use of keyword-const*
other-const*)LOAD-TIME-VALUE.)
The codevec looks like this
 (cf. the C type Codevec):
spdepth_1 (2 bytes)SP depth.
 spdepth_jmpbufsize (2 bytes)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)numopt (2 bytes)flags (1 byte)&REST parameter
    &KEY parameters
    &ALLOW-OTHER-KEYS
    SPACE”
    FUNCTION DOCUMENTATION STRING
       is kept in the closure object, see Section 3.3.6, “Declaration SPACE”
  signature (1 byte)numreq, numopt, flags.
    It is used for speeding up the function
    call.numkey (2 bytes, only if the
   function has &KEY)&KEY parameters.
 keyconsts (2 bytes, only if the
   function has &KEY)keyword-const in the function.
 byte* (any number of bytes)| These notes document CLISP version 2.49 | Last modified: 2010-07-07 |