Initial revision
[sbcl.git] / doc / cmucl / internals / fasl.tex
1 \chapter{Fasload File Format}% -*- Dictionary: design -*-
2 \section{General}
3
4 The purpose of Fasload files is to allow concise storage and rapid
5 loading of Lisp data, particularly function definitions.  The intent
6 is that loading a Fasload file has the same effect as loading the
7 ASCII file from which the Fasload file was compiled, but accomplishes
8 the tasks more efficiently.  One noticeable difference, of course, is
9 that function definitions may be in compiled form rather than
10 S-expression form.  Another is that Fasload files may specify in what
11 parts of memory the Lisp data should be allocated.  For example,
12 constant lists used by compiled code may be regarded as read-only.
13
14 In some Lisp implementations, Fasload file formats are designed to
15 allow sharing of code parts of the file, possibly by direct mapping
16 of pages of the file into the address space of a process.  This
17 technique produces great performance improvements in a paged
18 time-sharing system.  Since the Mach project is to produce a
19 distributed personal-computer network system rather than a
20 time-sharing system, efficiencies of this type are explicitly {\it not}
21 a goal for the CMU Common Lisp Fasload file format.
22
23 On the other hand, CMU Common Lisp is intended to be portable, as it will
24 eventually run on a variety of machines.  Therefore an explicit goal
25 is that Fasload files shall be transportable among various
26 implementations, to permit efficient distribution of programs in
27 compiled form.  The representations of data objects in Fasload files
28 shall be relatively independent of such considerations as word
29 length, number of type bits, and so on.  If two implementations
30 interpret the same macrocode (compiled code format), then Fasload
31 files should be completely compatible.  If they do not, then files
32 not containing compiled code (so-called "Fasdump" data files) should
33 still be compatible.  While this may lead to a format which is not
34 maximally efficient for a particular implementation, the sacrifice of
35 a small amount of performance is deemed a worthwhile price to pay to
36 achieve portability.
37
38 The primary assumption about data format compatibility is that all
39 implementations can support I/O on finite streams of eight-bit bytes.
40 By "finite" we mean that a definite end-of-file point can be detected
41 irrespective of the content of the data stream.  A Fasload file will
42 be regarded as such a byte stream.
43
44 \section{Strategy}
45
46 A Fasload file may be regarded as a human-readable prefix followed by
47 code in a funny little language.  When interpreted, this code will
48 cause the construction of the encoded data structures.  The virtual
49 machine which interprets this code has a {\it stack} and a {\it table},
50 both initially empty.  The table may be thought of as an expandable
51 register file; it is used to remember quantities which are needed
52 more than once.  The elements of both the stack and the table are
53 Lisp data objects.  Operators of the funny language may take as
54 operands following bytes of the data stream, or items popped from the
55 stack.  Results may be pushed back onto the stack or pushed onto the
56 table.  The table is an indexable stack that is never popped; it is
57 indexed relative to the base, not the top, so that an item once
58 pushed always has the same index.
59
60 More precisely, a Fasload file has the following macroscopic
61 organization.  It is a sequence of zero or more groups concatenated
62 together.  End-of-file must occur at the end of the last group.  Each
63 group begins with a series of seven-bit ASCII characters terminated
64 by one or more bytes of all ones \verb|#xFF|; this is called the
65 {\it header}.  Following the bytes which terminate the header is the
66 {\it body}, a stream of bytes in the funny binary language.  The body
67 of necessity begins with a byte other than \verb|#xFF|.  The body is
68 terminated by the operation {\tt FOP-END-GROUP}.
69
70 The first nine characters of the header must be "{\tt FASL FILE}" in
71 upper-case letters.  The rest may be any ASCII text, but by
72 convention it is formatted in a certain way.  The header is divided
73 into lines, which are grouped into paragraphs.  A paragraph begins
74 with a line which does {\it not} begin with a space or tab character,
75 and contains all lines up to, but not including, the next such line.
76 The first word of a paragraph, defined to be all characters up to but
77 not including the first space, tab, or end-of-line character, is the
78 {\it name} of the paragraph.  A Fasload file header might look something like
79 this:
80 \begin{verbatim}
81 FASL FILE >SteelesPerq>User>Guy>IoHacks>Pretty-Print.Slisp
82 Package Pretty-Print
83 Compiled 31-Mar-1988 09:01:32 by some random luser
84 Compiler Version 1.6, Lisp Version 3.0.
85 Functions: INITIALIZE DRIVER HACK HACK1 MUNGE MUNGE1 GAZORCH
86            MINGLE MUDDLE PERTURB OVERDRIVE GOBBLE-KEYBOARD
87            FRY-USER DROP-DEAD HELP CLEAR-MICROCODE
88             %AOS-TRIANGLE %HARASS-READTABLE-MAYBE
89 Macros:    PUSH POP FROB TWIDDLE
90 \end{verbatim}
91 {\it one or more bytes of \verb|#xFF|}
92
93 The particular paragraph names and contents shown here are only intended as
94 suggestions.
95
96 \section{Fasload Language}
97
98 Each operation in the binary Fasload language is an eight-bit
99 (one-byte) opcode.  Each has a name beginning with "{\tt FOP-}".  In    
100 the following descriptions, the name is followed by operand
101 descriptors.  Each descriptor denotes operands that follow the opcode
102 in the input stream.  A quantity in parentheses indicates the number
103 of bytes of data from the stream making up the operand.  Operands
104 which implicitly come from the stack are noted in the text.  The
105 notation "$\Rightarrow$ stack" means that the result is pushed onto the
106 stack; "$\Rightarrow$ table" similarly means that the result is added to the
107 table.  A construction like "{\it n}(1) {\it value}({\it n})" means that
108 first a single byte {\it n} is read from the input stream, and this
109 byte specifies how many bytes to read as the operand named {\it value}.
110 All numeric values are unsigned binary integers unless otherwise
111 specified.  Values described as "signed" are in two's-complement form
112 unless otherwise specified.  When an integer read from the stream
113 occupies more than one byte, the first byte read is the least
114 significant byte, and the last byte read is the most significant (and
115 contains the sign bit as its high-order bit if the entire integer is
116 signed).
117
118 Some of the operations are not necessary, but are rather special
119 cases of or combinations of others.  These are included to reduce the
120 size of the file or to speed up important cases.  As an example,
121 nearly all strings are less than 256 bytes long, and so a special
122 form of string operation might take a one-byte length rather than a
123 four-byte length.  As another example, some implementations may
124 choose to store bits in an array in a left-to-right format within
125 each word, rather than right-to-left.  The Fasload file format may
126 support both formats, with one being significantly more efficient
127 than the other for a given implementation.  The compiler for any
128 implementation may generate the more efficient form for that
129 implementation, and yet compatibility can be maintained by requiring
130 all implementations to support both formats in Fasload files.
131
132 Measurements are to be made to determine which operation codes are
133 worthwhile; little-used operations may be discarded and new ones
134 added.  After a point the definition will be "frozen", meaning that
135 existing operations may not be deleted (though new ones may be added;
136 some operations codes will be reserved for that purpose).
137
138 \begin{description}
139 \item[0:] \hspace{2em} {\tt FOP-NOP} \\
140 No operation.  (This is included because it is recognized
141 that some implementations may benefit from alignment of operands to some
142 operations, for example to 32-bit boundaries.  This operation can be used
143 to pad the instruction stream to a desired boundary.)
144
145 \item[1:] \hspace{2em} {\tt FOP-POP} \hspace{2em} $\Rightarrow$ \hspace{2em} table \\
146 One item is popped from the stack and added to the table.
147
148 \item[2:] \hspace{2em} {\tt FOP-PUSH} \hspace{2em} {\it index}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
149 Item number {\it index} of the table is pushed onto the stack.
150 The first element of the table is item number zero.
151
152 \item[3:] \hspace{2em} {\tt FOP-BYTE-PUSH} \hspace{2em} {\it index}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
153 Item number {\it index} of the table is pushed onto the stack.
154 The first element of the table is item number zero.
155
156 \item[4:] \hspace{2em} {\tt FOP-EMPTY-LIST} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
157 The empty list ({\tt ()}) is pushed onto the stack.
158
159 \item[5:] \hspace{2em} {\tt FOP-TRUTH} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
160 The standard truth value ({\tt T}) is pushed onto the stack.
161
162 \item[6:] \hspace{2em} {\tt FOP-SYMBOL-SAVE} \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
163 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
164 The four-byte operand {\it n} specifies the length of the print name
165 of a symbol.  The name follows, one character per byte,
166 with the first byte of the print name being the first read.
167 The name is interned in the default package,
168 and the resulting symbol is both pushed onto the stack and added to the table.
169
170 \item[7:] \hspace{2em} {\tt FOP-SMALL-SYMBOL-SAVE} \hspace{2em} {\it n}(1) \hspace{2em} {\it name}({\it n}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
171 The one-byte operand {\it n} specifies the length of the print name
172 of a symbol.  The name follows, one character per byte,
173 with the first byte of the print name being the first read.
174 The name is interned in the default package,
175 and the resulting symbol is both pushed onto the stack and added to the table.
176
177 \item[8:] \hspace{2em} {\tt FOP-SYMBOL-IN-PACKAGE-SAVE} \hspace{2em} {\it index}(4)
178 \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
179 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
180 The four-byte {\it index} specifies a package stored in the table.
181 The four-byte operand {\it n} specifies the length of the print name
182 of a symbol.  The name follows, one character per byte,
183 with the first byte of the print name being the first read.
184 The name is interned in the specified package,
185 and the resulting symbol is both pushed onto the stack and added to the table.
186
187 \item[9:] \hspace{2em} {\tt FOP-SMALL-SYMBOL-IN-PACKAGE-SAVE}  \hspace{2em} {\it index}(4)
188 \hspace{2em} {\it n}(1) \hspace{2em} {\it name}({\it n}) \hspace{2em}
189 $\Rightarrow$ \hspace{2em} stack \& table\\
190 The four-byte {\it index} specifies a package stored in the table.
191 The one-byte operand {\it n} specifies the length of the print name
192 of a symbol.  The name follows, one character per byte,
193 with the first byte of the print name being the first read.
194 The name is interned in the specified package,
195 and the resulting symbol is both pushed onto the stack and added to the table.
196
197 \item[10:] \hspace{2em} {\tt FOP-SYMBOL-IN-BYTE-PACKAGE-SAVE} \hspace{2em} {\it index}(1)
198 \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
199 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
200 The one-byte {\it index} specifies a package stored in the table.
201 The four-byte operand {\it n} specifies the length of the print name
202 of a symbol.  The name follows, one character per byte,
203 with the first byte of the print name being the first read.
204 The name is interned in the specified package,
205 and the resulting symbol is both pushed onto the stack and added to the table.
206
207 \item[11:]\hspace{2em} {\tt FOP-SMALL-SYMBOL-IN-BYTE-PACKAGE-SAVE} \hspace{2em} {\it index}(1)
208 \hspace{2em} {\it n}(1) \hspace{2em} {\it name}({\it n}) \hspace{2em}
209 $\Rightarrow$ \hspace{2em} stack \& table\\
210 The one-byte {\it index} specifies a package stored in the table.
211 The one-byte operand {\it n} specifies the length of the print name
212 of a symbol.  The name follows, one character per byte,
213 with the first byte of the print name being the first read.
214 The name is interned in the specified package,
215 and the resulting symbol is both pushed onto the stack and added to the table.
216
217 \item[12:] \hspace{2em} {\tt FOP-UNINTERNED-SYMBOL-SAVE} \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
218 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
219 Like {\tt FOP-SYMBOL-SAVE}, except that it creates an uninterned symbol.
220
221 \item[13:] \hspace{2em} {\tt FOP-UNINTERNED-SMALL-SYMBOL-SAVE} \hspace{2em} {\it n}(1)
222 \hspace{2em} {\it name}({\it n}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack
223 \& table\\
224 Like {\tt FOP-SMALL-SYMBOL-SAVE}, except that it creates an uninterned symbol.
225
226 \item[14:] \hspace{2em} {\tt FOP-PACKAGE} \hspace{2em} $\Rightarrow$ \hspace{2em} table \\
227 An item is popped from the stack; it must be a symbol.  The package of
228 that name is located and pushed onto the table.
229
230 \item[15:] \hspace{2em} {\tt FOP-LIST} \hspace{2em} {\it length}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
231 The unsigned operand {\it length} specifies a number of
232 operands to be popped from the stack.  These are made into a list
233 of that length, and the list is pushed onto the stack.
234 The first item popped from the stack becomes the last element of
235 the list, and so on.  Hence an iterative loop can start with
236 the empty list and perform "pop an item and cons it onto the list"
237 {\it length} times.
238 (Lists of length greater than 255 can be made by using {\tt FOP-LIST*}
239 repeatedly.)
240
241 \item[16:] \hspace{2em} {\tt FOP-LIST*} \hspace{2em} {\it length}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
242 This is like {\tt FOP-LIST} except that the constructed list is terminated
243 not by {\tt ()} (the empty list), but by an item popped from the stack
244 before any others are.  Therefore {\it length}+1 items are popped in all.
245 Hence an iterative loop can start with
246 a popped item and perform "pop an item and cons it onto the list"
247 {\it length}+1 times.
248
249 \item[17-24:] \hspace{2em} {\tt FOP-LIST-1}, {\tt FOP-LIST-2}, ..., {\tt FOP-LIST-8} \\
250 {\tt FOP-LIST-{\it k}} is like {\tt FOP-LIST} with a byte containing {\it k}
251 following it.  These exist purely to reduce the size of Fasload files.
252 Measurements need to be made to determine the useful values of {\it k}.
253
254 \item[25-32:] \hspace{2em} {\tt FOP-LIST*-1}, {\tt FOP-LIST*-2}, ..., {\tt FOP-LIST*-8} \\
255 {\tt FOP-LIST*-{\it k}} is like {\tt FOP-LIST*} with a byte containing {\it k}
256 following it.  These exist purely to reduce the size of Fasload files.
257 Measurements need to be made to determine the useful values of {\it k}.
258
259 \item[33:] \hspace{2em} {\tt FOP-INTEGER} \hspace{2em} {\it n}(4) \hspace{2em} {\it value}({\it n}) \hspace{2em}
260 $\Rightarrow$ \hspace{2em} stack \\
261 A four-byte unsigned operand specifies the number of following
262 bytes.  These bytes define the value of a signed integer in two's-complement
263 form.  The first byte of the value is the least significant byte.
264
265 \item[34:] \hspace{2em} {\tt FOP-SMALL-INTEGER} \hspace{2em} {\it n}(1) \hspace{2em} {\it value}({\it n})
266 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
267 A one-byte unsigned operand specifies the number of following
268 bytes.  These bytes define the value of a signed integer in two's-complement
269 form.  The first byte of the value is the least significant byte.
270
271 \item[35:] \hspace{2em} {\tt FOP-WORD-INTEGER} \hspace{2em} {\it value}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
272 A four-byte signed integer (in the range $-2^{31}$ to $2^{31}-1$) follows the
273 operation code.  A LISP integer (fixnum or bignum) with that value
274 is constructed and pushed onto the stack.
275
276 \item[36:] \hspace{2em} {\tt FOP-BYTE-INTEGER} \hspace{2em} {\it value}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
277 A one-byte signed integer (in the range -128 to 127) follows the
278 operation code.  A LISP integer (fixnum or bignum) with that value
279 is constructed and pushed onto the stack.
280
281 \item[37:] \hspace{2em} {\tt FOP-STRING} \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
282 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
283 The four-byte operand {\it n} specifies the length of a string to
284 construct.  The characters of the string follow, one per byte.
285 The constructed string is pushed onto the stack.
286
287 \item[38:] \hspace{2em} {\tt FOP-SMALL-STRING} \hspace{2em} {\it n}(1) \hspace{2em} {\it name}({\it n}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
288 The one-byte operand {\it n} specifies the length of a string to
289 construct.  The characters of the string follow, one per byte.
290 The constructed string is pushed onto the stack.
291
292 \item[39:] \hspace{2em} {\tt FOP-VECTOR} \hspace{2em} {\it n}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
293 The four-byte operand {\it n} specifies the length of a vector of LISP objects
294 to construct.  The elements of the vector are popped off the stack;
295 the first one popped becomes the last element of the vector.
296 The constructed vector is pushed onto the stack.
297
298 \item[40:] \hspace{2em} {\tt FOP-SMALL-VECTOR} \hspace{2em} {\it n}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
299 The one-byte operand {\it n} specifies the length of a vector of LISP objects
300 to construct.  The elements of the vector are popped off the stack;
301 the first one popped becomes the last element of the vector.
302 The constructed vector is pushed onto the stack.
303
304 \item[41:] \hspace{2em} {\tt FOP-UNIFORM-VECTOR} \hspace{2em} {\it n}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
305 The four-byte operand {\it n} specifies the length of a vector of LISP objects
306 to construct.  A single item is popped from the stack and used to initialize
307 all elements of the vector.  The constructed vector is pushed onto the stack.
308
309 \item[42:] \hspace{2em} {\tt FOP-SMALL-UNIFORM-VECTOR} \hspace{2em} {\it n}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
310 The one-byte operand {\it n} specifies the length of a vector of LISP objects
311 to construct.  A single item is popped from the stack and used to initialize
312 all elements of the vector.  The constructed vector is pushed onto the stack.
313
314 \item[43:] \hspace{2em} {\tt FOP-INT-VECTOR} \hspace{2em} {\it len}(4) \hspace{2em}
315 {\it size}(1) \hspace{2em} {\it data}($\left\lceil len*count/8\right\rceil$)
316 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
317 The four-byte operand {\it n} specifies the length of a vector of
318 unsigned integers to be constructed.   Each integer is {\it size}
319 bits long, and is packed according to the machine's native byte ordering.
320 {\it size} must be a directly supported i-vector element size.  Currently
321 supported values are 1,2,4,8,16 and 32.
322
323 \item[44:] \hspace{2em} {\tt FOP-UNIFORM-INT-VECTOR} \hspace{2em} {\it n}(4) \hspace{2em} {\it size}(1) \hspace{2em}
324 {\it value}(@ceiling<{\it size}/8>) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
325 The four-byte operand {\it n} specifies the length of a vector of unsigned
326 integers to construct.
327 Each integer is {\it size} bits big, and is initialized to the value
328 of the operand {\it value}.
329 The constructed vector is pushed onto the stack.
330
331 \item[45:] Unused
332
333 \item[46:] \hspace{2em} {\tt FOP-SINGLE-FLOAT} \hspace{2em} {\it data}(4) \hspace{2em}
334 $\Rightarrow$ \hspace{2em} stack \\
335 The {\it data} bytes are read as an integer, then turned into an IEEE single
336 float (as though by {\tt make-single-float}).
337
338 \item[47:] \hspace{2em} {\tt FOP-DOUBLE-FLOAT} \hspace{2em} {\it data}(8) \hspace{2em}
339 $\Rightarrow$ \hspace{2em} stack \\
340 The {\it data} bytes are read as an integer, then turned into an IEEE double
341 float (as though by {\tt make-double-float}).
342
343 \item[48:] \hspace{2em} {\tt FOP-STRUCT} \hspace{2em} {\it n}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
344 The four-byte operand {\it n} specifies the length structure to construct.  The
345 elements of the vector are popped off the stack; the first one popped becomes
346 the last element of the structure.  The constructed vector is pushed onto the
347 stack.
348
349 \item[49:] \hspace{2em} {\tt FOP-SMALL-STRUCT} \hspace{2em} {\it n}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
350 The one-byte operand {\it n} specifies the length structure to construct.  The
351 elements of the vector are popped off the stack; the first one popped becomes
352 the last element of the structure.  The constructed vector is pushed onto the
353 stack.
354
355 \item[50-52:] Unused
356
357 \item[53:] \hspace{2em} {\tt FOP-EVAL} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
358 Pop an item from the stack and evaluate it (give it to {\tt EVAL}).
359 Push the result back onto the stack.
360
361 \item[54:] \hspace{2em} {\tt FOP-EVAL-FOR-EFFECT} \\
362 Pop an item from the stack and evaluate it (give it to {\tt EVAL}).
363 The result is ignored.
364
365 \item[55:] \hspace{2em} {\tt FOP-FUNCALL} \hspace{2em} {\it nargs}(1) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
366 Pop {\it nargs}+1 items from the stack and apply the last one popped
367 as a function to
368 all the rest as arguments (the first one popped being the last argument).
369 Push the result back onto the stack.
370
371 \item[56:] \hspace{2em} {\tt FOP-FUNCALL-FOR-EFFECT} \hspace{2em} {\it nargs}(1) \\
372 Pop {\it nargs}+1 items from the stack and apply the last one popped
373 as a function to
374 all the rest as arguments (the first one popped being the last argument).
375 The result is ignored.
376
377 \item[57:] \hspace{2em} {\tt FOP-CODE-FORMAT} \hspace{2em} {\it implementation}(1)
378 \hspace{2em} {\it version}(1) \\
379 This FOP specifiers the code format for following code objects.  The operations
380 {\tt FOP-CODE} and its relatives may not occur in a group until after {\tt
381 FOP-CODE-FORMAT} has appeared; there is no default format.  The {\it
382 implementation} is an integer indicating the target hardware and environment.
383 See {\tt compiler/generic/vm-macs.lisp} for the currently defined
384 implementations.  {\it version} for an implementation is increased whenever
385 there is a change that renders old fasl files unusable.
386
387 \item[58:] \hspace{2em} {\tt FOP-CODE} \hspace{2em} {\it nitems}(4) \hspace{2em} {\it size}(4) \hspace{2em}
388 {\it code}({\it size}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
389 A compiled function is constructed and pushed onto the stack.
390 This object is in the format specified by the most recent
391 occurrence of {\tt FOP-CODE-FORMAT}.
392 The operand {\it nitems} specifies a number of items to pop off
393 the stack to use in the "boxed storage" section.  The operand {\it code}
394 is a string of bytes constituting the compiled executable code.
395
396 \item[59:] \hspace{2em} {\tt FOP-SMALL-CODE} \hspace{2em} {\it nitems}(1) \hspace{2em} {\it size}(2) \hspace{2em}
397 {\it code}({\it size}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
398 A compiled function is constructed and pushed onto the stack.
399 This object is in the format specified by the most recent
400 occurrence of {\tt FOP-CODE-FORMAT}.
401 The operand {\it nitems} specifies a number of items to pop off
402 the stack to use in the "boxed storage" section.  The operand {\it code}
403 is a string of bytes constituting the compiled executable code.
404
405 \item[60-61:] Unused
406
407 \item[62:] \hspace{2em} {\tt FOP-VERIFY-TABLE-SIZE} \hspace{2em} {\it size}(4) \\
408 If the current size of the table is not equal to {\it size},
409 then an inconsistency has been detected.  This operation
410 is inserted into a Fasload file purely for error-checking purposes.
411 It is good practice for a compiler to output this at least at the
412 end of every group, if not more often.
413
414 \item[63:] \hspace{2em} {\tt FOP-VERIFY-EMPTY-STACK} \\
415 If the stack is not currently empty,
416 then an inconsistency has been detected.  This operation
417 is inserted into a Fasload file purely for error-checking purposes.
418 It is good practice for a compiler to output this at least at the
419 end of every group, if not more often.
420
421 \item[64:] \hspace{2em} {\tt FOP-END-GROUP} \\
422 This is the last operation of a group.  If this is not the
423 last byte of the file, then a new group follows; the next
424 nine bytes must be "{\tt FASL FILE}".
425
426 \item[65:] \hspace{2em} {\tt FOP-POP-FOR-EFFECT} \hspace{2em} stack \hspace{2em} $\Rightarrow$ \hspace{2em} \\
427 One item is popped from the stack.
428
429 \item[66:] \hspace{2em} {\tt FOP-MISC-TRAP} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
430 A trap object is pushed onto the stack.
431
432 \item[67:] Unused
433
434 \item[68:] \hspace{2em} {\tt FOP-CHARACTER} \hspace{2em} {\it character}(3) \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
435 The three bytes are read as an integer then converted to a character.  This FOP
436 is currently rather useless, as extended characters are not supported.
437
438 \item[69:] \hspace{2em} {\tt FOP-SHORT-CHARACTER} \hspace{2em} {\it character}(1) \hspace{2em}
439 $\Rightarrow$ \hspace{2em} stack \\
440 The one byte specifies the code of a Common Lisp character object.  A character
441 is constructed and pushed onto the stack.
442
443 \item[70:] \hspace{2em} {\tt FOP-RATIO} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
444 Creates a ratio from two integers popped from the stack.
445 The denominator is popped first, the numerator second.
446
447 \item[71:] \hspace{2em} {\tt FOP-COMPLEX} \hspace{2em} $\Rightarrow$ \hspace{2em} stack \\
448 Creates a complex number from two numbers popped from the stack.
449 The imaginary part is popped first, the real part second.
450
451 \item[72-73:] Unused
452
453 \item[74:] \hspace{2em} {\tt FOP-FSET} \hspace{2em} \\
454 Except in the cold loader (Genesis), this is a no-op with two stack arguments.
455 In the initial core this is used to make DEFUN functions defined at cold-load
456 time so that global functions can be called before top-level forms are run
457 (which normally installs definitions.)  Genesis pops the top two things off of
458 the stack and effectively does (SETF SYMBOL-FUNCTION).
459
460 \item[75:] \hspace{2em} {\tt FOP-LISP-SYMBOL-SAVE} \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
461 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
462 Like {\tt FOP-SYMBOL-SAVE}, except that it creates a symbol in the LISP
463 package.
464
465 \item[76:] \hspace{2em} {\tt FOP-LISP-SMALL-SYMBOL-SAVE} \hspace{2em} {\it n}(1)
466 \hspace{2em} {\it name}({\it n}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack
467 \& table\\
468 Like {\tt FOP-SMALL-SYMBOL-SAVE}, except that it creates a symbol in the LISP
469 package.
470
471 \item[77:] \hspace{2em} {\tt FOP-KEYWORD-SYMBOL-SAVE} \hspace{2em} {\it n}(4) \hspace{2em} {\it name}({\it n})
472 \hspace{2em} $\Rightarrow$ \hspace{2em} stack \& table\\
473 Like {\tt FOP-SYMBOL-SAVE}, except that it creates a symbol in the
474 KEYWORD package.
475
476 \item[78:] \hspace{2em} {\tt FOP-KEYWORD-SMALL-SYMBOL-SAVE} \hspace{2em} {\it n}(1)
477 \hspace{2em} {\it name}({\it n}) \hspace{2em} $\Rightarrow$ \hspace{2em} stack
478 \& table\\
479 Like {\tt FOP-SMALL-SYMBOL-SAVE}, except that it creates a symbol in the
480 KEYWORD package.
481
482 \item[79-80:] Unused
483
484 \item[81:] \hspace{2em} {\tt FOP-NORMAL-LOAD}\\
485 This FOP is used in conjunction with the cold loader (Genesis) to read
486 top-level package manipulation forms.  These forms are to be read as though by
487 the normal loaded, so that they can be evaluated at cold load time, instead of
488 being dumped into the initial core image.  A no-op in normal loading.
489
490 \item[82:] \hspace{2em} {\tt FOP-MAYBE-COLD-LOAD}\\
491 Undoes the effect of {\tt FOP-NORMAL-LOAD}. 
492
493 \item[83:] \hspace{2em} {\tt FOP-ARRAY} \hspace{2em} {\it rank}(4)
494 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
495 This operation creates a simple array header (used for simple-arrays with rank
496 /= 1).  The data vector is popped off of the stack, and then {\it rank}
497 dimensions are popped off of the stack (the highest dimensions is on top.)
498
499 \item[84-139:] Unused
500
501 \item[140:] \hspace{2em} {\tt FOP-ALTER-CODE} \hspace{2em} {\it index}(4)\\
502 This operation modifies the constants part of a code object (necessary for
503 creating certain circular function references.)  It pops the new value and code
504 object are off of the stack, storing the new value at the specified index.
505
506 \item[141:] \hspace{2em} {\tt FOP-BYTE-ALTER-CODE} \hspace{2em} {\it index}(1)\\
507 Like {\tt FOP-ALTER-CODE}, but has only a one byte offset.
508
509 \item[142:] \hspace{2em} {\tt FOP-FUNCTION-ENTRY} \hspace{2em} {\it index}(4)
510 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
511 Initializes a function-entry header inside of a pre-existing code object, and
512 returns the corresponding function descriptor.  {\it index} is the byte offset
513 inside of the code object where the header should be plunked down.  The stack
514 arguments to this operation are the code object, function name, function debug
515 arglist and function type.
516
517 \item[143:] Unused
518
519 \item[144:] \hspace{2em} {\tt FOP-ASSEMBLER-CODE} \hspace{2em} {\it length}(4)
520 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
521 This operation creates a code object holding assembly routines.  {\it length}
522 bytes of code are read and placed in the code object, and the code object
523 descriptor is pushed on the stack.  This FOP is only recognized by the cold
524 loader (Genesis.)
525
526 \item[145:] \hspace{2em} {\tt FOP-ASSEMBLER-ROUTINE} \hspace{2em} {\it offset}(4)
527 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
528 This operation records an entry point into an assembler code object (for use
529 with {\tt FOP-ASSEMBLER-FIXUP}).  The routine name (a symbol) is on stack top.
530 The code object is underneath.  The entry point is defined at {\it offset}
531 bytes inside the code area of the code object, and the code object is left on
532 stack top (allowing multiple uses of this FOP to be chained.)  This FOP is only
533 recognized by the cold loader (Genesis.)
534
535 \item[146:] Unused
536
537 \item[147:] \hspace{2em} {\tt FOP-FOREIGN-FIXUP} \hspace{2em} {\it len}(1)
538 \hspace{2em} {\it name}({\it len})
539 \hspace{2em} {\it offset}(4) \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
540 This operation resolves a reference to a foreign (C) symbol.  {\it len} bytes
541 are read and interpreted as the symbol {\it name}.  First the {\it kind} and the
542 code-object to patch are popped from the stack.  The kind is a target-dependent
543 symbol indicating the instruction format of the patch target (at {\it offset}
544 bytes from the start of the code area.)  The code object is left on
545 stack top (allowing multiple uses of this FOP to be chained.)
546
547 \item[148:] \hspace{2em} {\tt FOP-ASSEMBLER-FIXUP} \hspace{2em} {\it offset}(4)
548 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
549 This operation resolves a reference to an assembler routine.  The stack args
550 are ({\it routine-name}, {\it kind} and {\it code-object}).  The kind is a
551 target-dependent symbol indicating the instruction format of the patch target
552 (at {\it offset} bytes from the start of the code area.)  The code object is
553 left on stack top (allowing multiple uses of this FOP to be chained.)
554
555 \item[149-199:] Unused
556
557 \item[200:] \hspace{2em} {\tt FOP-RPLACA} \hspace{2em} {\it table-idx}(4)
558 \hspace{2em} {\it cdr-offset}(4)\\
559
560 \item[201:] \hspace{2em} {\tt FOP-RPLACD} \hspace{2em} {\it table-idx}(4)
561 \hspace{2em} {\it cdr-offset}(4)\\
562 These operations destructively modify a list entered in the table.  {\it
563 table-idx} is the table entry holding the list, and {\it cdr-offset} designates
564 the cons in the list to modify (like the argument to {\tt nthcdr}.)  The new
565 value is popped off of the stack, and stored in the {\tt car} or {\tt cdr},
566 respectively.
567
568 \item[202:] \hspace{2em} {\tt FOP-SVSET} \hspace{2em} {\it table-idx}(4)
569 \hspace{2em} {\it vector-idx}(4)\\
570 Destructively modifies a {\tt simple-vector} entered in the table.  Pops the
571 new value off of the stack, and stores it in the {\it vector-idx} element of
572 the contents of the table entry {\it table-idx.}
573
574 \item[203:] \hspace{2em} {\tt FOP-NTHCDR} \hspace{2em} {\it cdr-offset}(4)
575 \hspace{2em} $\Rightarrow$ \hspace{2em} stack\\
576 Does {\tt nthcdr} on the top-of stack, leaving the result there.
577
578 \item[204:] \hspace{2em} {\tt FOP-STRUCTSET} \hspace{2em} {\it table-idx}(4)
579 \hspace{2em} {\it vector-idx}(4)\\
580 Like {\tt FOP-SVSET}, except it alters structure slots.
581
582 \item[255:] \hspace{2em} {\tt FOP-END-HEADER} \\ Indicates the end of a group header,
583 as described above.
584 \end{description}