63 lines
3.0 KiB
HTML
63 lines
3.0 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<link rel="stylesheet" type="text/css" href="css.css">
|
|
</head>
|
|
<body>
|
|
<table class="doctable" border="0" cellspacing="0" summary=
|
|
"this table is just for layout">
|
|
<tr class="toprow"><td class=maintitle>the vx-scheme compiler
|
|
<p align="right">[ <a href="download.html">Download</a> ]</p>
|
|
</td></tr>
|
|
<tr><td class=body>
|
|
|
|
<p><img align="right" src="compiler.png"> When I first started out to
|
|
write the compiler I was only interested in doing it for its own sake,
|
|
to get the system running as fast as possible. Naturally, getting the
|
|
compiler going to the point where it would work for the complete
|
|
language was more work than I bargained for, and presented some
|
|
head-scratching puzzles too. For one thing, there was no way for the
|
|
interpreter, for example, to invoke a compiled procedure safely: doing
|
|
so would split the current continuation between the interpreter's data
|
|
structures and the virtual machine in a way that would be pretty
|
|
difficult to reassemble in such a way as to
|
|
permit <code>call-with-current-continuation</code>.</p>
|
|
<p>That being the case, I was forced to complete the VM implementation
|
|
to the bitter end. But that opened the possibility of detaching the
|
|
interpreter in steps, leaving behind a system with the interpreter
|
|
shorn away and no scheme source to read in order to initialize. To do
|
|
this the bytecode had to be serialized in a form that could be
|
|
executed without any help from the interpreter. The compiler emits
|
|
code in the form of scheme vectors containing ordinary integer
|
|
opcodes; the VM code contains a
|
|
routine <code>write-compiled-procedure</code> that tranforms this
|
|
representation into a static C data structure.
|
|
<p><code>bootstrap.scm</code>, which runs in a special version of the
|
|
interpreter is linked with a dormant copy of the VM code (to gain
|
|
access to <code>write-compiled-procedure</code>), sequences the
|
|
compilation of the compiler Scheme source and a small library of
|
|
support routines to a C file, <code>_compiler.cpp</code>. At this
|
|
point, that file can be compiled and linked with the VM, and now you
|
|
have a Scheme REPL with no interpreter in sight.</p>
|
|
<p>For compute-bound tasks, compiled code is more or less twice as
|
|
fast as the interpreter. For very small programs, or programs that
|
|
don't loop much, the effort of compiling can outweigh the
|
|
benefit. (See examples of both behaviors on
|
|
the <a href="benchmark.html">benchmark page</a>.
|
|
<p>Note that the trick of loading only the compiler and REPL with the
|
|
VM can be repeated with any Scheme
|
|
source. <code>scheme-compiler</code> is essentially a precompiled
|
|
helper to do this: it will transform Scheme code into the C
|
|
representation of bytecode in one step. Link this with the VM, and
|
|
now you have compiled scheme code running without either the
|
|
interpreter or the compiler!</p>
|
|
<p>To see this in action, just type <code>make pi</code>. This will
|
|
take <code>pi.scm</code> from the testcases directory all the way
|
|
through this process.</p>
|
|
|
|
</p>
|
|
</td></tr>
|
|
</table>
|
|
</body>
|
|
</html>
|