mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
Also, install the #\" macro in *xc-readtable* right away since we're not clobbering the default *readtable* any more.
198 lines
9.2 KiB
Plaintext
198 lines
9.2 KiB
Plaintext
This document was motivated by a request from Paolo Amoroso for notes
|
|
or other documentation on my work on SBCL. It's intended for
|
|
developers who are familiar with the guts of CMU CL, as an overview of
|
|
the changes made to CMU CL in order to produce SBCL. It was written
|
|
for the initial release (sbcl-0.5.0) and has not been updated since
|
|
then.
|
|
|
|
There are two sections in this report:
|
|
I. non-fundamental changes
|
|
II. fundamental changes
|
|
In this context, fundamental changes are changes which were
|
|
directly driven by the goal of making the system bootstrap itself.
|
|
|
|
|
|
Section I: non-fundamental changes
|
|
|
|
Before I describe the fundamental changes I had to make in order to
|
|
get the system to bootstrap itself, let me emphasize that there are
|
|
many non-fundamental changes as well. I won't try to summarize them
|
|
all, but I'll mention some to give some idea. (Some more information
|
|
about why I made some of these changes is in the PRINCIPLES file in
|
|
the distribution.)
|
|
|
|
Many, many extensions have been removed.
|
|
|
|
Packages have all been renamed; in the final system,
|
|
the system packages have names which begin with "SB-".
|
|
Mostly these correspond closely to CMU CL packages,
|
|
e.g. the "C" package of CMU CL has become the "SB-C" package,
|
|
and the "EXTENSIONS" package of CMU CL has become the "SB-EXT"
|
|
package.
|
|
|
|
Some other definitions and declarations have been centralized, too.
|
|
E.g. the build order is defined in one place, and all the COMMON-LISP
|
|
special variables are declared in one place.
|
|
|
|
I've made various reformatting changes in the comments, and
|
|
added a number of comments.
|
|
|
|
INFO is now implemented as a function instead of a macro,
|
|
using keywords as its first and second arguments, and is
|
|
no longer in the extensions package, but is considered a
|
|
private implementation detail.
|
|
|
|
The expected Lisp function arguments and command line arguments
|
|
for SAVE-LISP (now called SAVE-LISP-AND-DIE) and loading
|
|
the core back into a new Lisp have changed completely.
|
|
|
|
The SB-UNIX package no longer attempts to be a complete user interface
|
|
to Unix. Instead, it's considered a private part of the implementation
|
|
of SBCL, and tries to implement only what's needed by the current
|
|
implementation of SBCL.
|
|
|
|
Lots of stale conditional code was deleted, e.g. code to support
|
|
portability to archaic systems in the LOOP and PCL packages. (The
|
|
SB-PCL and SB-LOOP packages no longer aspire to portability.)
|
|
|
|
Various internal symbols, and even some externally-visible extensions,
|
|
have been given less-ambiguous or more-modern names, with more to
|
|
follow. (E.g. SAVE-LISP becoming SAVE-LISP-AND-DIE, both to avoid
|
|
surprising the user and to reserve the name SAVE-LISP in case we ever
|
|
manage to implement a SAVE-LISP which doesn't cause the system to die
|
|
afterwards. And GIVE-UP and ABORT-TRANSFORM have been renamed
|
|
to GIVE-UP-IR1-TRANSFORM and ABORT-IR1-TRANSFORM. And so on.)
|
|
|
|
Various internal names "NEW-FOO" have been changed to FOO, generally
|
|
after deleting the obsolete old version of FOO. This has happened both
|
|
with names at the Lisp level (e.g. "NEW-ASSEM") and at the Unix
|
|
filesystem level (e.g. "new-hash.lisp" and "new-assem.lisp").
|
|
|
|
A cultural change, rather than a technical one: The system no longer
|
|
tries to be binary compatible between releases.
|
|
|
|
Per-file credits for programs should move into a single
|
|
centralized CREDITS file Real Soon Now.
|
|
|
|
A lot of spelling errors have been corrected.:-)
|
|
|
|
|
|
Section II. fundamental changes
|
|
|
|
There were a number of things which I changed in order to get the
|
|
system to boot itself.
|
|
|
|
The source files have been extensively reordered to fix broken forward
|
|
references. In many cases, this required breaking one CMU CL source
|
|
file into more than one SBCL source file, and scattering the multiple
|
|
SBCL source files into multiple places in the build order. (Some of
|
|
the breakups were motivated by reasons which no longer exist, and
|
|
could be undone now, e.g. "class.lisp" could probably go back into
|
|
"classes.lisp". But I think most of the reasons still apply.)
|
|
|
|
The assembler and genesis were rewritten for portability, using
|
|
vectors for scratch space instead of using SAPs.
|
|
|
|
We define new readmacro syntax #!+ and #!- which acts like
|
|
the standard #+ and #- syntax, except that it switches on the
|
|
target feature list instead of the host feature list. We also
|
|
introduce temporary new features like :XC-HOST ("in the cross-compilation
|
|
host") and :XC ("in the cross-compiler") which will be used
|
|
to control some of the behavior below.
|
|
|
|
A new package SB-XC ("cross-compiler") was introduced to hold
|
|
affecting-the-target versions of various things like DEFMACRO,
|
|
DEFTYPE, FIND-CLASS, CONSTANTP, CLASS, etc. So e.g. when you're
|
|
building the cross-compiler in the cross-compilation host Lisp,
|
|
SB-XC:DEFMACRO defines a macro in the target Lisp; SB-XC:CONSTANTP
|
|
tells you whether something is known to be constant in the target
|
|
Lisp; and SB-XC:CLASS is the class of an object which represents a
|
|
class in the target Lisp. In order to make everything work out later
|
|
when running the cross-compiler to produce code for the target Lisp,
|
|
SB-XC turns into a sort of nickname for the COMMON-LISP package.
|
|
Except it's a little more complicated than that..
|
|
|
|
It doesn't quite work to make SB-XC into a nickname for COMMON-LISP
|
|
while building code for the target, because then much of the code in
|
|
EVAL-WHEN (:COMPILE-TOPLEVEL :EXECUTE) forms would break. Instead, we
|
|
read in code using the ordinary SB-XC package, and then when we
|
|
process code in any situation other than :COMPILE-TOPLEVEL, we run it
|
|
through the function UNCROSS to translate any SB-XC symbols into the
|
|
corresponding CL symbols. (This doesn't seem like a very elegant
|
|
solution, but it does seem to work.:-)
|
|
|
|
Even after we've implemented the UNCROSS hack, a lot of the code inside
|
|
EVAL-WHEN forms is still broken, because it does things like CL:DEFMACRO
|
|
to define macros which are intended to show up in the target, and
|
|
under the new system we really need it to do SB-XC:DEFMACRO instead
|
|
in order to achieve the desired effect. So we have to go through
|
|
all the EVAL-WHEN forms and convert various CL:FOO operations
|
|
to the corresponding SB-XC:FOO operations. Or sometimes instead we
|
|
convert code a la
|
|
(EVAL-WHEN (COMPILE EVAL)
|
|
(DEFMACRO FOO ..))
|
|
(code-using-foo)
|
|
into code a la
|
|
(MACROLET ((FOO ..))
|
|
(code-using-foo))
|
|
Or sometimes we even give up and write
|
|
(DEFMACRO FOO ..)
|
|
(code-using-foo)
|
|
instead, figuring it's not *that* important to try to save a few bytes
|
|
in the target Lisp by keeping FOO from being defined. And in a few
|
|
shameful instances we even did things like
|
|
#+XC (DEFMACRO FOO ..)
|
|
#-XC (DEFMACRO FOO ..
|
|
or
|
|
#+XC (code-using-foo)
|
|
#-XC (other-code-using-foo)
|
|
even though we know that we will burn in hell for it. (The really
|
|
horribly unmaintainable stuff along those lines is three compiler-building
|
|
macros which I hope to fix before anyone else notices them.:-)
|
|
|
|
In order to avoid trashing the host Common Lisp when cross-compiling
|
|
under another instance of ourself (and in order to avoid coming to
|
|
depend on its internals in various weird ways, like some systems we
|
|
could mention but won't:-) we make the system use different package
|
|
names at cold init time than afterwards. The internal packages are
|
|
named "SB!FOO" while we're building the system, and "SB-FOO"
|
|
afterwards.
|
|
|
|
In order to make the system work even when we're renaming its packages
|
|
out from underneath it, we need to seek out and destroy any nasty
|
|
hacks which refer to particular package names, like the one in
|
|
%PRIMITIVE which wants to reintern the symbols in its arguments into
|
|
the "C"/"SB-C"/"SB!C" package.
|
|
|
|
In order to keep track of layouts and other type and structure
|
|
information set up under the cross-compiler, we use a system built
|
|
around the DEF!STRUCT macro. (The #\! character is used to name a lot
|
|
of cold-boot-related stuff.) When building the cross-compiler, the
|
|
DEF!STRUCT macro is a wrapper around portable DEFSTRUCT which builds
|
|
its own portable information about the structures being created, and
|
|
arranges for host Lisp instances of the structures to be dumpable as
|
|
target Lisp instances as necessary. (This system uses MAKE-LOAD-FORM
|
|
heavily and is the reason that I say that bootstrapping under CLISP is
|
|
not likely to happen until CLISP supports MAKE-LOAD-FORM.) When
|
|
running the cross-compiler, DEF!STRUCT basically reduces to the
|
|
DEFSTRUCT macro.
|
|
|
|
In order to be able to make this system handle target Lisp code,
|
|
we need to be able to test whether a host Lisp value matches a
|
|
target Lisp type specifier. With the information available from
|
|
DEF!STRUCT, and various hackery, we can do that, implementing things
|
|
like SB-XC:TYPEP.
|
|
|
|
Now that we know how to represent target Lisp objects in the
|
|
cross-compiler running under vanilla ANSI Common Lisp, we need to make
|
|
the dump code portable. This is not too hard given that the cases
|
|
which would be hard tend not to be used in the implementation of SBCL
|
|
itself, so the cross-compiler doesn't need to be able to handle them
|
|
anyway. Specialized arrays are an exception, and currently we dodge
|
|
the issue by making the compiler use not-as-specialized-as-possible
|
|
array values. Probably this is fixable by bootstrapping in two passes,
|
|
one pass under vanilla ANSI Common Lisp and then another under the
|
|
SBCL created by the first pass. That way, the problem goes away in the
|
|
second pass pass, since we know that all types represented by the
|
|
target SBCL can be represented in the cross-compilation host SBCL.
|