architecture.md raw

Moxie Architecture

Core Principle

The server is dumb. The client is smart. Each domain is sovereign.

Moxie enforces isolation at the language level. Domains are OS processes. There is no shared memory. Communication is serialized over IPC. Within each domain, goroutines cooperate on a single thread.

Compilation Pipeline

Moxie source (.mx files)
    │
    ▼
loader (package loading, MOXIEROOT overlays)
    │
    ▼
cgo (libclang processing for C interop)
    │
    ▼
SSA construction (via golang.org/x/tools/go/ssa)
    │
    ▼
compiler (Moxie SSA → LLVM IR)
    ├── spawn builtin → runtime.spawnDomain (Codec validation)
    ├── restriction checking: reject new, complex, etc.
    ├── goroutine lowering: go → task.start
    └── syscall intrinsics: inline assembly
    │
    ▼
transform (LLVM IR optimization passes)
    │
    ▼
interp (compile-time partial evaluation)
    │
    ▼
builder (orchestration)
    ├── compile musl, bdwgc, compiler-rt
    ├── compile extra .c files (signal.c, spawn_unix.c)
    └── link with ld.lld
    │
    ▼
Static ELF/Mach-O binary

For the JS target, jsbackend replaces the LLVM path:

Moxie SSA → jsbackend → JavaScript + jsruntime

Cooperative Scheduler

Each domain runs scheduler = "tasks" — a cooperative FIFO scheduler.

                ┌──────────┐
                │ Run Queue │ (FIFO)
                └─────┬────┘
                      │
          ┌───────────┼───────────┐
          ▼           ▼           ▼
     ┌────────┐  ┌────────┐  ┌────────┐
     │ Task 0 │  │ Task 1 │  │ Task 2 │
     │ stack  │  │ stack  │  │ stack  │
     └────────┘  └────────┘  └────────┘

Spawn: Domain Creation

spawn is a language builtin (like make, append). The type checker validates argument count and types. The SSA validator enforces moxie.Codec on all data arguments and channel element types.

spawn(fn, args...)
    │
    ▼ (compile time)
compiler/spawn.go
    │ validate all args implement moxie.Codec
    │ reject pointers, interfaces, functions
    │ emit: runtime.spawnDomain(wrapper, packedArgs)
    │
    ▼ (runtime)
src/runtime/spawn.go
    │
    ├── socketpair(AF_UNIX, SOCK_STREAM) → fds[2]
    ├── fork()
    │
    ├── child (pid == 0):
    │   ├── close(fds[0])
    │   ├── drain parent run queue
    │   ├── task.start(wrapper, args, 8KB)
    │   ├── scheduler(returnAtDeadlock=true)
    │   └── exit(0)
    │
    └── parent:
        ├── close(fds[1])
        └── continue execution

Memory Model

Build Tags

Moxie uses moxie and moxie.unicore build tags:

//go:build moxie.unicore    → cooperative single-core (always true)
//go:build moxie            → moxie compiler (always true)
//go:build gc.boehm         → Boehm GC (default on linux/darwin)
//go:build scheduler.tasks  → cooperative scheduler (always true)

Target Configuration

Moxie supports exactly 4 native targets plus JS:

GOOS/GOARCHSchedulerGCLibcLinker
linux/amd64tasksboehmmuslld.lld
linux/arm64tasksboehmmuslld.lld
darwin/amd64tasksboehmdarwin-libSystemld.lld
darwin/arm64tasksboehmdarwin-libSystemld.lld
jstasks

No embedded targets. No WASI. No Windows.