Next: , Up: fasl


E.1 Binary format of a FASL file

A FASL object is a header followed by one or more object fields followed by an end–of–FASL marker. After the end–of–FASL marker the file must be at its EOF.

The header is the string #@IK0, followed by 1 if fixnum width is 30 bits, else followed by 2; the end of fasl marker is @.

If the same object is referenced multiple times in the FASL file: it can be included only once and “marked” with a fixnum; such mark is later dereferenced to insert a reference to the object in the loaded code.

A data word is an exact signed integer of 32-bit or 64-bit depending on the word size of the underlying platform.

An object field is a character in ASCII encoding, optionally followed by data representing the serialisation of a Scheme value:

"N"
Denotes the empty list.
"T"
Denotes #t.
"F"
Denotes #f.
"E"
Denotes the end of file object.
"U"
Denotes the unspecified value (void).
"I" + word
A fixnum stored as a big endian word.
"s" + word(N) + octet ...
An ASCII string of N characters followed by N octets representing the characters in ASCII encoding. The data word N must represent an exact integer in the range of fixnums.
"S" + word(N) + int32 ...
A Unicode string of N characters followed by N 32-bit integers in native order representing the characters as Unicode code points. The data word N must represent an exact integer in the range of fixnums.
"M" + symbol-name
A symbol. symbol-name is a string field.
"G" + pretty-name + unique-name
A gensym. Both pretty-name and unique-name are strings.
"c" + octet
A character in the ASCII range (<= 255).
"C" + int32
A character store as 32-bit integer representing a Unicode code point.
"P" + object1 + object2
A pair.
"V" + word(N) + object ...
A vector of length N followed by N object fields. The data word N must represent an exact integer in the range of fixnums.
"v" + word(N) + octet ...
A bytevector of length N followed by N octets. The data word N must represent an exact integer in the range of fixnums.
"R" + rtd-name + rtd-symbol + field-count + name ...
A struct type descriptor. rtd-name must be a symbol. rtd-symbol must be a symbol. field-count must be a word in the fixnum range. The name object fields must be symbols representing the field name and there must be field-count of them.
"{" + field-count + rtd + field ...
A structure instance. field-count must be a word in the fixnum range. rtd must be a struct type descriptor. The field object fields must be the fields of the structure instance and there must be field-count of them.
"r" + denominator + numerator
Ratnum.
"f" + 8-byte
IEEE double precision flonum. The bytes are stored: most significant first, least significant last.
"b" + word(N) + octet ...
Denotes a bignum. N is a signed integer word whose sign is the sign of the bignum and whose modulo is the number of octets representing the bignum.
"i" + real-part + imag-part
Complex numbers, both cflonum and compnum.
"l" + octet(N) + object ...
A list of N <= 255 elements followed by the elements.
"L" + word(N) + object ...
A list of N > 255 elements followed by the elements.
"h" + vector + vector
eq? hashtable, first vector keys, second vector values.
"H" + vector + vector
eqv? hashtable, first vector keys, second vector values.
"W" + name + parent + uid + sealed? + opaque? + count + (bool + field) ...
An R6RS record type descriptor.
name
Must be the return value of record-type-name.
parent
Must be the return value of record-type-parent.
uid
Must be the return value of record-type-uid.
sealed?
Must be the return value of record-type-sealed?.
opaque?
Must be the return value of record-type-opaque?.
count
Must be a fixnum representing the number of fields.

Each bool + field sequence must be a boolean representing the mutability of the record field, followed by symbol representing the name of the record field.

"x" + int + int + annotation + bytes + relocation vector
Denotes code. A serialised code object is represented as follows, after the ‘x’ header:
  1. An exact integer representing the number of bytes actually used in the data area of the code object. On 32-bit platforms: a big endian 32-bit integer. On 64-bit platforms: a sequence of two big endian 32-bit integers.
  2. An exact integer representing the number of free variables in the code. On 32-bit platforms: a big endian 32-bit integer. On 64-bit platforms: a sequence of two big endian 32-bit integers.
  3. A Scheme object representing the code annotation.
  4. An array of bytes being the binary code.
  5. The code relocation vector as an ordinary Scheme vector.

"Q" + "x" + code object
Procedure. A procedure is represented by the header Q followed by the serialisation of a code object, header x included.
">" + int32(I)
Mark the next object with index I.
"<" + int32(I)
Dereference the object marked with index I.
"O" + libid
Foreign library identifier. libid must be a string representing the foreign shared library identifier: on Unix–like systems it is prefixed with lib and suffixed with .so to compose a library file name.