$Revision: 5.0.2.4 $
The document introduction.htm provides an overview of the Allegro CL documentation with links to all major documents. The document index.htm is an index with pointers to every documented object (operators, variables, etc.) The revision number of this document is below the title. These documents may be revised from time to time between releases.
1.0 Introduction
2.0 The fasl reader/writer
3.0 Miscellaneous extensions
4.0 Creating and using pll files
This document describes functionality that does not naturally fit in any of the other overview documents.
The functions fasl-write and fasl-read provide a mechanism for writing Lisp data and subsequently reading it back into a Lisp image. It can handle many of the common Lisp data types. It can optionally detect circularity and structure sharing in the data and recreate the same topology up to eql-ness of components. The data is written in a binary file format similar to that used for compiled Lisp files, not in ASCII.
Among the advantages of fasl-read and fasl-write over standard Common Lisp read and print functions is that data does not have to be converted to its printed representation prior to being written (that conversion takes a significant amount of time for complex objects). The main disadvantage is that the files (unlike ASCII files with printed representations of Lisp objects) are not at all portable between versions of Lisp (or even between versions of Allegro CL on different platforms or between major releases of Allegro CL).
Not all Lisp objects may be written with fasl-write (and thus are not available to be read by fasl-read). The objects that cannot be written are CLOS objects, streams, stacks, or c-allocated data (cstructs). You can use fasl-open to open a file suitable for numerous fasl-write's. (fasl-read reads all of whatever file is specified to it.)
fasl-read reads the entire contents of its argument file. However, fasl-write, if its argument is a stream rather than a filename, writes data to the stream but does not close it. Thus you can open a stream and do multiple fasl-write's to it. The stream must have :element-type (unsigned-byte 8). fasl-open opens an appropriate stream, as shown in the example.
Here is a simple-minded example to show the correct syntax and give an idea of the effect:
(excl:fasl-write '(a b #1=#:c (#1#) #*1011 #(1 2 3)
1 1.1 1.1d0 1/2
#c(1 1) #c(1.5 1.5) "abc")
"test.fw")
(excl:fasl-read "test.fw")
(setq f (fasl-open "test2.fw"))
(excl:fasl-write '(a b c) f)
(excl:fasl-write '#1=(a b . #1#) f t)
(excl:fasl-write '#(1 2 3 4.5) f)
(close f)
(excl:fasl-read "test2.fw")
The table describes those extensions to Common Lisp that do not naturally fit elsewhere in the documentation. We only provide brief information in the table. Please follow the link to the documentation page for a full description.
Name | Arguments | Notes |
excl:dribble-bug | &optional file | This function is an extension of the Common Lisp function dribble. dribble-bug called with the optional file calls several information functions whose output is then placed at the beginning of the dribble file. See also excl:*dribble-bug-hooks*. |
excl:uncompile | function-name | If the function function-name was compiled with the compile function (as opposed to having been in a file that was compiled with compile-file and subsequently loaded), then the function is `uncompiled,' i.e. its function definition is replaced by the original interpreted definition. |
excl:bignump | object | These functions, like similar ones in standard Common Lisp return t if object is of the type specified, and nil otherwise. |
excl:fixnump | ||
excl:ratiop | ||
excl:single-float-p | ||
excl:file-older-p | file-1 file-2 | If file-1 and file-2 both exist, and if file-1 is older than file-2, this function returns t. Otherwise, it returns nil. |
excl:if* | test-form {then then-form+ | thenret} {elseif else-test-form {then else-then-form+ | thenret}}* [else else-form+] |
This extension to cl:if allows symbols like then, else, elseif, and thenret in the body allowing a complex number of cases and outcomes to be specified. |
excl:named-readtable | name &optional errorp | This function looks up a readtable by name. name must be a symbol, but it is coerced to a keyword (so readtables are named by keywords). setf may be used to associate a name to a readtable. The association can be broken by setting to nil. See also with-named-readtable. |
A pll file can be used in association with a Lisp image. It contains constant code vectors and strings that can be shared among many Lisp objects. When an image uses a pll file and a function is compiled, the new codevector is compared to codevectors in the pll file. If a match is found, the match is used and no new codevector is allocated. Similarly, if a constant string is specified (with excl:pure-string) and a matching string appears in the pll file, no new string is allocated and the match is used. Strings in a pll file cannot be modified. Attempting to do so causes an error. (Neither can codevectors be modified but there is no user-visible way to modify codevectors as there is with strings.)
Strings and codevectors in a pll file are not also (after being garbage collected) in the Lisp heap. Thus if a string has been successfully purified, it will not be in the heap after a global gc. A total count of strings and codevectors is shown in the output of (room t).
pll files are created with the cvdcvt program described next.
cvdcvt
Arguments: [-o outfilename] [-u] [file1 file2 ]
A .pll file, outfilename, is created holding all the unique code vectors and strings. If outfilename is omitted it defaults to code.blob.
If -u is specified, then no duplications of strings are done, otherwise for every string that has no lowercase characters in it and at least one uppercase character, a lowercase copy is added to the output file. This is the default and is useful for set-case-mode. If no files are specified, stdin is used.
.str (string) files and .cvs (code vector) files are combined without redundancies; if two files of the same extension have identical objects, the object from the file specified first to cvdcvt is retained, and the latter object is removed from the output. This allows for files (.cvs files especially) to be arranged by code vectors in order of execution, to provide for locality of reference. Those .cvs files that were produced by training techniques should be placed first in order to have the desired effect.
Some base .str and .cvs files are provided. If these provided files are given to cvdcvt as well as user-created files, then the resulting .pll file will be more complete. Most provided files are named in such a way as to make obvious what is in them; e.g. lisp.str contains all strings in the base product.
As said in the description, pll files are built out of cvs files and str files. cvs files are created with sys:write-codevectors and can be created by sys:flush-codevectors. str files are created with sys:record-strings. See also sys:record-training.
The following functions can be used to associate a pll file with an image, to find out which pll file is used with an image, and to use strings in the pll file.
Name | Arguments | Notes |
excl:pll-file |
[none] | Return the location of the current .pll file, or nil if there is no .pll file associated with this Lisp. |
excl:use-pll-file | name &key (global-gc t) | Associates the current Lisp with the pll file specified by name. It is an error to associate an image already using a pll file with another pll file. |
excl:pure-string | x | When not in the body of sys:record-strings, returns a pure-string if there is one identical to the argument and a heap-allocated string if there isn't. When in the body of sys:record-strings, also write the string to the str file being created. |
Copyright (C) 1998-1999, Franz Inc., Berkeley, CA. All Rights Reserved.