[fd4e91]: impnotes / comp-fun.html Maximize Restore History

Download this file

comp-fun.html    86 lines (85 with data), 17.9 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:cf="http://docbook.sourceforge.net/xmlns/chunkfast/1.0"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.3. The structure of compiled functions</title><link rel="stylesheet" href="impnotes.css" type="text/css" /><link rev="made" href="mailto:clisp-list@sf.net" /><meta name="generator" content="DocBook XSL Stylesheets V2005-07-12_04:47_snapshot" /><link rel="start" href="index.html" title="Implementation Notes for GNU CLISP." /><link rel="up" href="bytecode.html" title="Chapter 36. The CLISP bytecode specification" /><link rel="prev" href="vm.html" title="36.2. The virtual machine" /><link rel="next" href="intr-struct.html" title="36.4. The general structure of the instructions" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">36.3. The structure of compiled functions</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="vm.html">Prev</a> </td><th width="60%" align="center">Chapter 36. The <span><strong class="command">CLISP</strong></span> bytecode specification</th><td width="20%" align="right"> <a accesskey="n" href="intr-struct.html">Next</a></td></tr></table><hr /></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="comp-fun"></a>36.3. The structure of compiled functions</h2></div></div></div><p>A compiled function consists of two objects: The function itself,
containing the references to all <a href="http://clisp.cons.org" target="_top"><span><strong class="command">CLISP</strong></span></a> objects needed for the bytecode,
and a byte vector containing only immediate data, including the bytecode
proper.</p><p>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).</p><p>A function looks like this
(cf. the <a href="http://www.eskimo.com/~scs/C-faq/top.html" target="_top"><span><strong class="command">C</strong></span></a> type <span class="type">Cclosure</span>):
</p><div class="variablelist"><dl><dt><a id="func-name"></a>name</dt><dd>This is the name of the function, normally a symbol
or a list of the form <code class="code">(<a href="http://www.lisp.org/HyperSpec/Body/mac_setfcm_psetf.html" target="_top"><code class="function">SETF</code></a> <em class="replaceable"><code>symbol</code></em>)</code>.
It is used for printing the function and for error messages.
This field is immutable.</dd><dt><a id="func-codevec"></a><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">codevec</code></a></dt><dd>This is the byte-code vector, a <span class="type"><code class="literal">(<a href="http://www.lisp.org/HyperSpec/Body/typ_simple-array.html" target="_top"><code class="classname">SIMPLE-ARRAY</code></a> (<a href="http://www.lisp.org/HyperSpec/Body/typ_unsigned-byte.html" target="_top"><code class="classname">UNSIGNED-BYTE</code></a> 8) (*))</code></span>.
This field is immutable.</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">consts</code></a>[]</dt><dd>The remaining fields in the function object are
references to other <a href="http://clisp.cons.org" target="_top"><span><strong class="command">CLISP</strong></span></a> objects. These references are immutable,
which is why they are called “<span class="quote">constants</span>”.
(The referenced <a href="http://clisp.cons.org" target="_top"><span><strong class="command">CLISP</strong></span></a> objects can be mutable objects,
such as <a href="http://www.lisp.org/HyperSpec/Body/syscla_cons.html" target="_top"><code class="classname">CONS</code></a>es or <a href="http://www.lisp.org/HyperSpec/Body/syscla_vector.html" target="_top"><code class="classname">VECTOR</code></a>s, however.)
</dd></dl></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">The Exception to the Immutability Rule</h3><p>When a generic function's dispatch code is installed, the <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">codevec</code></a>
and <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">consts</code></a> fields are destructively modified.</p></div><p>Some of the <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">consts</code></a> can play special roles.
A function looks like this, in more detail:
</p><div class="variablelist"><dl><dt>name</dt><dd>see <a href="comp-fun.html#func-name">name</a>.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">codevec</code></a></dt><dd>see <a href="comp-fun.html#func-codevec"><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">codevec</code></a></a>.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">venv-const</code></a>*</dt><dd>At most one object, representing the closed-up
variables, representing the variables of the <a href="http://www.lisp.org/HyperSpec/Body/sec_3-1-1-3.html" target="_top">lexical environment</a> in
which this function was defined. It is a <a href="http://www.lisp.org/HyperSpec/Body/typ_simple-vector.html" target="_top"><code class="classname">SIMPLE-VECTOR</code></a>, which
looks like this: <span class="data"><code class="literal">#(<em class="replaceable"><code>next</code></em>
<em class="replaceable"><code>value<sub>1</sub></code></em> ...
<em class="replaceable"><code>value<sub>n</sub></code></em>)</code></span>
where <em class="replaceable"><code>value<sub>1</sub></code></em>, ...,
<em class="replaceable"><code>value<sub>n</sub></code></em>
are the values of the closed-up variables,
and <em class="replaceable"><code>next</code></em> is either <a href="http://www.lisp.org/HyperSpec/Body/convar_nil.html" target="_top"><code class="constant">NIL</code></a> or a <a href="http://www.lisp.org/HyperSpec/Body/typ_simple-vector.html" target="_top"><code class="classname">SIMPLE-VECTOR</code></a> having the same
structure.</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">block-const</code></a>*</dt><dd>Objects representing closed-up <a href="http://www.lisp.org/HyperSpec/Body/speope_block.html" target="_top"><code class="function">BLOCK</code></a> tags,
representing the <a href="http://www.lisp.org/HyperSpec/Body/speope_block.html" target="_top"><code class="function">BLOCK</code></a> tags of the <a href="http://www.lisp.org/HyperSpec/Body/sec_3-1-1-3.html" target="_top">lexical environment</a> in which
this function was defined. Each is a <a href="http://www.lisp.org/HyperSpec/Body/syscla_cons.html" target="_top"><code class="classname">CONS</code></a> containing in the
<a href="http://www.lisp.org/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" target="_top"><code class="function">CDR</code></a> part: either a frame pointer to the block frame, or <span class="data"><code class="literal">#&lt;DISABLED&gt;</code></span>.
The <a href="http://www.lisp.org/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" target="_top"><code class="function">CAR</code></a> is the block's name, for error messages only.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">tagbody-const</code></a>*</dt><dd>Objects representing closed-up <a href="http://www.lisp.org/HyperSpec/Body/speope_tagbody.html" target="_top"><code class="function">TAGBODY</code></a> tags,
representing the <a href="http://www.lisp.org/HyperSpec/Body/speope_tagbody.html" target="_top"><code class="function">TAGBODY</code></a> tags of the <a href="http://www.lisp.org/HyperSpec/Body/sec_3-1-1-3.html" target="_top">lexical environment</a> in which
this function was defined. Each is a <a href="http://www.lisp.org/HyperSpec/Body/syscla_cons.html" target="_top"><code class="classname">CONS</code></a> containing in the
<a href="http://www.lisp.org/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" target="_top"><code class="function">CDR</code></a> part: either a frame pointer to the <a href="http://www.lisp.org/HyperSpec/Body/speope_tagbody.html" target="_top"><code class="function">TAGBODY</code></a> frame, or
<span class="data"><code class="literal">#&lt;DISABLED&gt;</code></span> if the <a href="http://www.lisp.org/HyperSpec/Body/speope_tagbody.html" target="_top"><code class="function">TAGBODY</code></a> has already been left. The <a href="http://www.lisp.org/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" target="_top"><code class="function">CAR</code></a> is a
<a href="http://www.lisp.org/HyperSpec/Body/typ_simple-vector.html" target="_top"><code class="classname">SIMPLE-VECTOR</code></a> containing the names of the <a href="http://www.lisp.org/HyperSpec/Body/speope_tagbody.html" target="_top"><code class="function">TAGBODY</code></a> tags,
for error messages only.</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">keyword-const</code></a>*</dt><dd>If the function was defined with a <a href="lalist.html" title="3.4. Lambda Lists&#10; [CLHS-3.4]">lambda list</a>
containing <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;KEY</code></a>, here come the symbols ("keywords"), in their
correct order. They are used by the interpreter during function call.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">other-const</code></a>*</dt><dd>Other objects needed by the function's bytecode.
</dd></dl></div><p>
</p><p>If <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">venv-const</code></a>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">block-const</code></a>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">tagbody-const</code></a> are all absent,
the function is called <span class="emphasis"><em>autonomous</em></span>.
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
<a href="http://www.lisp.org/HyperSpec/Body/sec_3-1-1-3.html" target="_top">lexical environment</a>.</p><p>If some <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">venv-const</code></a>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">block-const</code></a>, or <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">tagbody-const</code></a> are
present, the function (a “<span class="quote">closure</span>”) is created at runtime.
The compiler only generates a prototype, containing <a href="http://www.lisp.org/HyperSpec/Body/convar_nil.html" target="_top"><code class="constant">NIL</code></a> values
instead of each <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">venv-const</code></a>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">block-const</code></a>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">tagbody-const</code></a>.
At runtime, a function is created by copying this prototype and
replacing the <a href="http://www.lisp.org/HyperSpec/Body/convar_nil.html" target="_top"><code class="constant">NIL</code></a> values by the definitive ones.</p><p>The list <span class="data"><code class="literal">(<a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">keyword-const</code></a>*
<a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">other-const</code></a>*)</code></span> normally does not contain duplicates, because
the compiler removes duplicates when possible. (Duplicates can occur
nevertheless, through the use of <a href="http://www.lisp.org/HyperSpec/Body/speope_load-time-value.html" target="_top"><code class="function">LOAD-TIME-VALUE</code></a>.)</p><p>The <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">codevec</code></a> looks like this
(cf. the <a href="http://www.eskimo.com/~scs/C-faq/top.html" target="_top"><span><strong class="command">C</strong></span></a> type <span class="type">Codevec</span>):
</p><div class="variablelist"><dl><dt><code class="literal">spdepth_1</code> (2 bytes)</dt><dd>The 1st part of the maximal <a href="vm.html" class="olink"><code class="literal">SP</code></a> depth.
</dd><dt><code class="literal">spdepth_jmpbufsize</code> (2 bytes)</dt><dd>The <a href="vm.html" title="36.2. The virtual machine"><code class="varname">jmpbufsize</code></a> part of the maximal <a href="vm.html" class="olink"><code class="literal">SP</code></a> depth.
The maximal <a href="vm.html" class="olink"><code class="literal">SP</code></a> depth (precomputed by the compiler) is given by
<code class="literal">spdepth_1 + spdepth_jmpbufsize * <a href="vm.html" title="36.2. The virtual machine"><code class="varname">jmpbufsize</code></a></code>.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">numreq</code></a> (2 bytes)</dt><dd>Number of required parameters.
</dd><dt><code class="literal">numopt</code> (2 bytes)</dt><dd>Number of optional parameters.
</dd><dt><a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">flags</code></a> (1 byte)</dt><dd><div class="variablelist"><dl><dt>bit 0</dt><dd>set if the function has the <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;REST</code></a> parameter
</dd><dt>bit 7</dt><dd>set if the function has <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;KEY</code></a> parameters
</dd><dt>bit 6</dt><dd>set if the function has <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;ALLOW-OTHER-KEYS</code></a>
</dd><dt>bit 4</dt><dd>set if the function is a generic function
</dd><dt>bit 3</dt><dd>set if the function is a generic function and its
effective method shall be returned (instead of being executed)
</dd></dl></div></dd><dt><code class="literal">signature</code> (1 byte)</dt><dd>An abbreviation code depending on
<a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">numreq</code></a>, <code class="literal">numopt</code>, <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">flags</code></a>.
It is used for speeding up the function
call.</dd><dt><code class="literal">numkey</code> (2 bytes, only if the
function has <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;KEY</code></a>)</dt><dd>The number of <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;KEY</code></a> parameters.
</dd><dt><code class="literal">keyconsts</code> (2 bytes, only if the
function has <a href="http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html" target="_top"><code class="literal">&amp;KEY</code></a>)</dt><dd>The offset of the <a href="comp-fun.html" title="36.3. The structure of compiled functions"><code class="literal">keyword-const</code></a> in the function.
</dd><dt><code class="literal">byte</code>* (any number of bytes)</dt><dd>The bytecode instructions.
</dd></dl></div></div><div class="bookinfo"><hr width="100%" /><table width="100%" summary="impnotes meta info"><th><td align="left">These notes document <a href="http://clisp.cons.org" target="_top"><span><strong class="command">CLISP</strong></span></a> version 2.34.</td><td align="right">Last modified: 2005-07-20</td></th></table></div><div class="custom-footer"><hr width="100%" /><table width="100%"><tr><td align="left"><a href="http://clisp.cons.org"><img src="clisp.png" width="48" height="48" alt="[CLISP home]" /></a></td><td align="center"><a href="http://www.gnu.org"><img src="http://www.gnu.org/graphics/gnubanner.jpg" width="468" height="60" alt="[Come and see what GNU creates for YOU]" /></a></td><td align="right"><a href="http://sourceforge.net"><img width="125" height="37" alt="[SourceForge]" src="http://sflogo.sourceforge.net/sflogo.php?group_id=1355&amp;type=2&amp;page=comp-fun" /></a></td></tr></table></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="vm.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bytecode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="intr-struct.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.2. The virtual machine </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 36.4. The general structure of the instructions</td></tr></table></div></body></html>