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
[]CONS
es or VECTOR
s, 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:
codevec
codevec
.
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.7, “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.93+ | Last modified: 2018-02-19 |