Runtime model
mu programs compile to bytecode and run on a small, stack-based VM. The VM is the reference implementation for language semantics.
The execution pipeline
- Lexing and parsing produce an AST.
- The compiler lowers the AST into bytecode (via a small IR).
- The VM executes the bytecode on a stack machine.
Bytecode VM
- Fast startup and predictable execution.
- Easy to inspect and test.
- The REPL runs on the same VM pipeline.
Native backend
The native backend lowers the same IR into machine code without invoking external assemblers or linkers. Non-FFI programs stay self-contained; programs that call C libraries intentionally carry the dynamic-loader metadata they need. It keeps semantics aligned with the VM so programs behave the same in either mode.
Build with -B, and cross-compile with -p os/arch:
$ mu -B -o hello hello.mu
$ mu -B -p linux/riscv64 -o hello hello.mu
There are two native backends, and their target lists differ slightly:
| Target | Go backend (mu -B) |
Self-hosted backend |
|---|---|---|
darwin/arm64 |
yes | yes |
linux/amd64 |
yes | yes |
linux/riscv64 |
yes | yes |
linux/arm64 |
yes | not yet |
darwin/amd64 |
not yet | not yet |
Self-hosting
selfhost/ holds a lexer, parser, compiler, VM and native backend written in
mu. It is not the default build, but it is not a plan either: compiling it with
itself reaches a byte-identical fixpoint — the compiler reproduces itself
exactly, gcc-style, with no Go in the path — on darwin/arm64 and linux/amd64.
scripts/bootstrap.sh checks that on every change.
That gives four ways to run a mu program, and they are held to the same tests: the Go host’s VM, the Go native backend, the self-hosted VM, and the self-hosted native backend. Where they still differ is recorded below and on the FFI and concurrency pages rather than left to be discovered.
Deterministic concurrency
Tasks and channels use cooperative scheduling with FIFO queues. Blocking operations (send/recv/wait/sleep and I/O) yield so the scheduler can resume other work deterministically.
Concurrency is implemented across the four execution paths: Go VM, Go native,
self-hosted VM, and self-hosted native. The target matrix still matters: the
self-hosted native backend currently covers darwin/arm64, linux/amd64, and
linux/riscv64, while the Go native backend also covers linux/arm64.
Learn more
- The IR and assembler are documented in docs/ir.md.
- The VM and compiler pipeline are detailed in docs/Implementation.md.
Next steps
- Review the language tour for syntax context.
- Explore the standard library layers.
- Read the specification for the full runtime contract.