[gambit-list] How to create small standalone executable with
Taylor R Campbell
campbell at mumble.net
Mon Aug 17 19:46:59 EDT 2009
Date: Mon, 17 Aug 2009 17:19:30 -0400
From: Marc Feeley <feeley at iro.umontreal.ca>
I'm curious to know how this works. If you have a module which
implements several procedures, say the srfi-1 list library, and you
use only one of the self-contained procedures, say "xcons", will the
Scheme48 compiler or linker eliminate the rest of the code of srfi-1?
If so, how does it do that? What is the bytecode representation of
the compiled library?
For each global variable, an object called a location is allocated.
Locations have a little bit of structure, but primarily they have a
field for the value of the global variable. The representation of
procedures has two parts: an environment and a pointer to a
/template/. The environment holds the values, or cells for the
values, of local variables. The template is the static part of the
procedure: it holds the byte code, the literals, the locations for
global variables, and the templates for subprocedures, corresponding
to the lambdas that require heap allocation. Templates are thus
arranged into a tree like the tree of contours in the program, and
parents can be garbage- collected if they are no longer used.
Compiling a package is similar to compiling a big lambda containing
the forms in the package's source code, with the side effect of
filling a table mapping names to the meanings defined in the source
code. The procedure (and its template) thereby obtained can be
garbage-collected once it has been used, since nothing else will have
references to it.
If you write a program that uses XCONS, but nothing else defined in
the SRFI 1 package, then your program will remember the location for
with the global variable XCONS, which will remember the procedure that
was stored in the location when SRFI 1 was loaded, which will remember
all its own literals and locations and subtemplates, but nothing else
of the SRFI 1 package.
Also in Scheme48, if you are using the command processor, you can type
`,go <expression>', and most of the execution of Scheme48 will be
tail-recursively replaced by that of <expression> -- so that the
command processor can be garbage-collected. (There is a little bit of
the run-time system left on the stack, but that's all.)
Naturally, Gambit can't do quite this, if you want a single C object
or library per unit of source code (i.e., per file, in Gambit's case),
because you can't usefully garbage-collect a portion of an object you
have dlopened or statically linked; dlclose works at the granularity
of entire objects, and what is statically linked can't be eliminated.
But that's unrelated to whether one can just do (##GLOBAL-VAR-REF
(##MAKE-GLOBAL-VAR ...)) in a `Lisp-like language'. (In fact, it's a
little more closely related to whether one can do *((foo_t *) dlsym
(RTLD_DEFAULT, "foo")) in C...)
More information about the Gambit-list
mailing list