Next: , Up: Compilation   [Contents][Index]


2.1 Compiling from the command line

Hoot extends Guile’s guild tool with a new subcommand: compile-wasm.

The general syntax is:

guild compile-wasm [options] file

Below is a basic example that compiles foo.scm to foo.wasm and allows access to third-party Scheme modules in the current directory:

guild compile-wasm --load-path=. --output=foo.wasm foo.scm

The available options are documented below.

--load-path=dir
-L dir

Add dir to the front of the module load path.

--output=out-file
-o out-file

Write output to out-file.

-x extension

Add extension to the set of source file extensions.

--warn=warning
-W warning

Emit warnings of type warning; use --warn=help for a list of available warnings.

--optimize=opt
-O opt

Specify optimization passes to run; use -Ohelp for a list of available optimizations

--mode=mode

Compile the Wasm in mode.

Available modes are:

primary

Compile a main module: one which defines runtime facilities and which by default makes them available to secondary modules. This is the default mode.

standalone

Like primary, but without the possibility of sharing runtime facilities with secondary modules.

secondary

Compile an auxiliary module: one which imports runtime facilities instead of defining and exporting them.

--run
--run=js

Run the compiled Wasm; by default, in the Hoot virtual machine, otherwise using js, a JavaScript shell such as NodeJS. Useful for quickly testing out small programs.

Consider this example program, example.scm:

(use-modules) ; use default Guile environment
(map 1+ '(1 2 3 4 5))

To compile and run the above program on the Hoot VM, discarding the Wasm at the end, run:

guild compile-wasm --run example.scm

To do the same with NodeJS, run:

guild compile-wasm --run=node example.scm
# => 42

The above example assumes that node is on $PATH so adjust accordingly if that is not the case for your NodeJS installation.

--async

When combined with --run, run program in async context.

Consider this example program, example.scm:

(use-modules (fibers promises)
             (fibers timers))
(lambda (resolve reject)
  (call-with-async-result
   resolve reject
   (lambda ()
     (sleep 1)
     42)))

Without the --async flag, the result of running the above program would be the procedure described by the lambda form and nothing would happen. When run in async mode, the runtime will wait until the program resolves successfully with some return values or is rejected due to an error.

guild compile-wasm --run --async example.scm
# => (42)
--user-imports=import-file

When combined with --run, load the Scheme/JavaScript (depending upon --run) source import-file and pass the result as additional imports when instantiating the Wasm module.

On the Hoot VM, the file should evaluate to a 2-tier association list of imports. For example:

(use-modules (rnrs bytevectors))

`(("uint8Array" . (("new"    . ,make-bytevector)
                   ("length" . ,bytevector-length)
                   ("ref"    . ,bytevector-u8-ref)
                   ("set"    . ,bytevector-u8-set!))))

On JavaScript, the file should define a 2-tier object of imports. For JavaScript runtimes that support module imports via require, like NodeJS, the imports above could be translated like this:

exports.user_imports = {
    uint8Array: {
        new: (length) => new Uint8Array(length),
        length: (array) => array.length,
        ref: (array, index) => array[index],
        set: (array, index, value) => array[index] = value
    }
};
--dump-tree-il

Print a debugging representation of the high-level expanded and optimized Scheme code.

--dump-cps

Print a debugging representation of the low-level CPS code, before generating WebAssembly.

--dump-wasm

Print a debugging representation of the generated WebAssembly code.

--emit-names

Emit a WebAssembly name section for debugging. For example, this allows browser developer tools to show human-readable Wasm function and type names.


Next: Compiling from Guile, Up: Compilation   [Contents][Index]