Known limits and status¶
Work in progress
This page is a draft. It describes Burroughs as of its latest release and may change. Where it disagrees with the engine's own documentation or CHANGELOG, those win.
This list is as of v0.12.0 (2026-10-28). It is drawn from that release's Known limits in
CHANGELOG.md, from the repository README, and from behaviour observed while writing these docs; observed items are
marked. The issue states were read from GitHub on 2026-10-28. For anything later, check the newest release block in
CHANGELOG.md.
Phase¶
Burroughs is in v1, the threads phase (decision 0099). v0's closure conditions were all discharged at v0.4.0.
v1 is not finished, and 1.0.0 is reserved: the project stays on 0.x. Releases map minors to milestones, so a
version number says which conformance milestone was reached.
What works¶
- Core WebAssembly, MVP and Wasm 2.0, plus SIMD, relaxed SIMD, and since
v0.12.0extended constant expressions, tail calls, multi-memory and memory64, throughInstantiate/Instance.Callandburroughs run. The spec suite's core board reported 0 failures atv0.12.0(see Conformance). - WASI preview 1 commands, such as Go programs built with
GOOS=wasip1, throughWASIP1Config.Runandburroughs run, with args, env, the standard streams, read-only preopens and writable scratch preopens. - Guest-started threads on that path (since
v0.12.0, #1122). A module that imports"burroughs" "spawn", with type(i32) -> ()or(i32) -> (i32), and exportsmstartof type(i32) -> (), starts a new agent on an OS thread over its shared memory each time it calls the import. Contract §2 T-1 names the door. The release's end-to-end witness is a fork-built Go program whose output matches stock Go's, with several agents executing at once. - Components: loading, typed calls with
u32/string/list/recordvalues, the async component ABI, cancellation throughcontext,Close, andwasi:cli/runworlds. - Component-model threads (
gate:cm-threads, phase 1) start through the component paths. They are cooperative and run one at a time per instance.
Limits on default-on paths (from v0.12.0's release notes)¶
- A guest that calls
runtime.LockOSThreadand then needs another M crashes on the Phase 4 fork (#1157, open), with "fatal error: on a locked thread with no template thread". The throw is the fork runtime's own, not the engine's, and the fix is the fork's. - Threads start only where a guest asks. The
"burroughs" "spawn"door is served on the WASI preview-1 paths (WASIP1Config.Run,burroughs run). The rest is unchanged fromv0.11.0: - core
Instantiatesupplies no imports, so a core module's shared memory has one agent, andmemory.atomic.waiton it can only time out (observed: tutorial 4); - the public API has no host-side spawn, join, stop or host-function registration (host-started threads are not built);
- a component's
thread.spawn-refis refused by name, andthread.spawn-indirectis refused at decode. - A shared-everything-threads table is refused as "malformed", not by name (#1120, open). It is still a refusal, but the category is wrong.
Closewith a zero bound returnsnilon Windows whereErrCloseIncompleteis wanted (#945, open). Windows is outside the support claim.- A Go guest's stop-the-world still depends on the fork compiler's inserted loop checks (#1064, open, parked). Contract §3 SP-1 says the guest should not need to instrument itself.
- A Go runtime fatal was seen once on CI's arm64 runner in
internal/spec(#1089, open). It has not recurred. array.new*'s backing allocation is not polled, so a stop can take more than 1 ms on a GC array of roughly 64 Ki elements or more (ADR 0104). This only matters with GC, which is gated off by default and cannot be turned on publicly.
Limits of the public surface¶
- No host imports on the core path.
Confighas no import set and no feature set. Any import isErrUnlinkableat load. The only host APIs a guest can reach are WASI preview 1 (viaWASIP1Config) and the WASI 0.2 subset for components. - Two proposals cannot be enabled at all through the public API: GC and exception handling. The only
Featureisthreads. (The four Wasm 3.0 proposals that flipped inv0.12.0are on by default, and can only be turned off, by their environment rollbacks.) - Core calls cannot be cancelled.
Instance.Calltakes nocontext. - No exported-global enumeration and no global writes. Memories and tables are not exposed.
- Component values: only
u32,string,listandrecordcross the boundary (atuplearrives as a record).bool, the other integer and float widths,char,variant,enum,option,result,flagsand resource handles are refused by name asErrUnsupported. - Calls into one
Componentexecute one at a time (ADR 0101), as the component model specifies. Instanceconcurrency is not documented.
WASI coverage¶
- Preview 1: reads under granted directories, the standard streams, args, env and
proc_exit. Under aWritablegrant,path_create_directory,path_unlink_file,path_remove_directory,fd_pwriteandpath_open's create and truncate modes also work. Twenty functions still answerENOSYS(ADR 0091's amendment counts 21; the host refuses 20). - WASI 0.2 for components is partial.
wasi:cli: run, exit, stdout, stderr and stdin.environment.get-argumentsreturnsComponentConfig.Args.get-environmentalways returns an empty list.wasi:io: output-streamwrite,check-write,blocking-write-and-flushandblocking-flush; input-streamblocking-read;error.to-debug-string.wasi:filesystem: onlypreopens.get-directories, which returns an empty list, and descriptor drop.- Absent: clocks, random, sockets and http, and filesystem operations beyond the above.
- WASI 0.3 (p3): the async component ABI is implemented and on by default, and
wasi:cli/run@0.3.0-style exports can be called by name. A complete WASI 0.3 host is the v3 rung, not yet built.
CLI quirks (observed)¶
versionalways printsv0.0.1(#1130, open).inspectdoes not understand components (it reports them as malformed).- A component takes no
--dir,--scratchor--env, and no function name: each is refused by name as a usage error (exit 2), and its arguments go after--. A core module refuses--featuresby name (exit 2). These were #1128, fixed inv0.12.0, which also routes a component correctly whatever flags are given. Details are in the CLI reference. - Caller mistakes on
Instance.Call(arity, type, unknown export) match no sentinel, and the CLI maps them to exit 1. Sincev0.12.0a mistypedComponent.Callargument is classed the same way, as the caller's error (#1129, fixed).
Stale doc comments (observed)¶
These package doc comments say something the code no longer does (#1130, open). The behaviour described in these docs is the code's:
ComponentConfigsays the value-carrying component surface "has not landed". It has.ComponentKindandComponentU32say onlyu32crosses.string,listandrecorddo too.FeatureThreadssaysgate:threads' default "is unchanged". It flipped on inv0.10.0.
Platforms¶
- Built and tested: 64-bit Linux (
ubuntu-24.04, x86-64 and arm64 runners) and macOS (development, plus a darwin CI job). - Windows runs the test suite in a separate CI workflow that is measured, not a gate, and does not block a merge. Treat it as unsupported.
- 32-bit targets: no claim.
- Threads default: ADR 0106's claim covers linux and darwin.
DefaultFeaturesitself does not check the OS, so a Windows build admits the grammar too, untested.
Not started¶
- Stack switching (contract §7, the v2 rung).
- A compiler. No rung of the ladder adds one.
- Production hardening against hostile modules is a stated non-goal of contract v0.1 (§1.4).