I’ve just pushed a small change to the module registration method. Now, loading the generated .js file will run that file.
Marc
First of all, this change is for the universal backend. It is more of a temporary kludge to experiment with dynamically loading files generated by the universal backend. Here’s how it works…
At the end of the link file, the Gambit linker generates a table of the Scheme modules required by the program. The table is passed as a parameter to the g_module_registry_init function of the Gambit runtime system. For example, the link command:
gsc -link -l lib/_gambit.js a.js b.js
will generate at the end of the link file “b_.js”:
g_module_registry_init([new G_ModLinkInfo("_gambit",0),
new G_ModLinkInfo("a",1),
new G_ModLinkInfo("b",2)]);
At then end of a file generated for the compilation of a module there is a call to a runtime system function that registers the module in the module registry. For example, when “a.scm” is compiled with the command “gsc -target js -c a.scm”, the file “a.js” generated ends with:
g_module_register([g_make_interned_symbol("a"),g_bb1__ 20_a,1,null,false]);
The parameter of g_module_register is a “module descriptor” giving information on the module: name, main function (g_bb1__20_a), preload flag (1), module meta information (null), and a dummy field (false) that is only interesting for the C backend.
So when the files of generated code are loaded (incrementally) by the JS VM, g_module_register accumulates the modules in a table. When all the modules required by the program have beed loaded (in the example, _gambit, a and b) the function g_module_register will call the main function of the first module. This will run the Scheme code at the toplevel of the first module.
The first module contains a loop, in Scheme, that iterates over the module registry and calls the main function of each of the remaining modules in the registry (this information is available in Scheme in the global variable ##program-descr). Specifically, the first module is the Gambit universal library (lib/_univlib.scm), which ends with a call to ##load-vm (a procedure defined in lib/_kernel.scm that runs each module other than the first).
What my most recent change does is extend g_module_register so that any subsequent module that is loaded by the JS VM causes its immediate execution by calling the module's main function. In the C backend the mechanism is slightly different (and more flexible): the ##load-object-file procedure of the Gambit runtime library constructs a vector of module descriptors and this vector is passed to ##register-module-descrs-and-load! (defined in lib/_kernel.scm) which then runs the modules. It is more flexible because the loaded object file can contain more than one module, and also control goes through Scheme before the module is executed.
Marc