Repository navigation
runtime/AOT (refines #8508): Emscripten main+side-module loading (web-tree-sitter + grammars) and wasm-bindgen (photon) for OpenCode v1.18.30 #10102
Copy link
Copy link
Closed
Labels
enhancementNew capability or improvementNew capability or improvementparityCompatibility gap with Node.js, ECMAScript, or the supported ecosystemCompatibility gap with Node.js, ECMAScript, or the supported ecosystem
Description
Parent: #10107. Refines #8508 (open). Prior: #5234, #6558, changelog.d/8508-wasm-instance-constructor, changelog.d/8508-wasm-bindgen-live-state.
Exact modules in the reachable graph (9 .wasm)
| module | size | loaded by | binary facts (parsed 2026-09-12) |
|---|---|---|---|
web-tree-sitter/tree-sitter.wasm |
200 K | packages/opencode/src/tool/shell.ts:313-320 (Parser.init({ locateFile })), @opentui/core/parser.worker.js:3790-3794 (in a Worker) |
Emscripten MAIN_MODULE with dylink.0; imports env ×11 (tree_sitter_log_callback, tree_sitter_parse_callback, tree_sitter_progress_callback, tree_sitter_query_progress_callback, _abort_js, …), wasi_snapshot_preview1 ×4 (fd_close, fd_write, fd_seek, clock_time_get), GOT.mem (__heap_base); 153 exports |
tree-sitter-bash/tree-sitter-bash.wasm (1.3 M), tree-sitter-powershell/tree-sitter-powershell.wasm (0.9 M) |
shell tool: shell.ts:322-328 import("…wasm", { with: { type: "wasm" } }) → Language.load(path) |
Emscripten side modules: dylink.0 custom section, imports only env ×16 (malloc, calloc, realloc, free, iswspace, …), 3 exports (tree_sitter_<lang>, …) |
|
@opentui/core/assets/{javascript,typescript,markdown,markdown_inline,zig}/tree-sitter-*.wasm (+6 .scm query files) |
TUI syntax highlighting inside parser.worker.js (Language.load at :3875) |
same side-module shape | |
@silvia-odwyer/photon-node/photon_rs_bg.wasm |
1.8 M | packages/core/src/image/photon.ts:2 (with { type: "file" }, sets globalThis.__OPENCODE_PHOTON_WASM_PATH at :12) → photon_rs.js:4514-4518: readFileSync(path), synchronous new WebAssembly.Module(bytes) + new WebAssembly.Instance(module, imports) at module init |
wasm-bindgen: 41 imports all in __wbindgen_placeholder__ (__wbg_new_…, __wbg_newnoargs_… = new Function(str), DOM stubs), 191 exports |
Loader mechanics that must work (web-tree-sitter tree-sitter.js, copied into parser.worker.js):
- main:
WebAssembly.instantiate(bytes, imports)(async),locateFile→fs.readFileSync. - side (
loadWebAssemblyModule, :3071loadDynamicLibrary): parsedylink.0from the bytes (memory/table sizes, needed libs, TLS), grow the shared__indirect_function_table(WebAssembly.Table.grow,table.set), allocate__memory_basein the main module's heap, import objects built fromProxy(envresolves symbols lazily viaresolveGlobalSymbol;GOT.mem/GOT.funcreturn mutableWebAssembly.Globali32),__stack_pointer/__memory_base/__table_baseglobals,relocateExports,__wasm_apply_data_relocs,__wasm_call_ctors. Theeval-basedaddEmAsm/addEmJspaths are dead (no shipped module exports__start_em_asm/__em_js__*). - wasm-bindgen: sync Module/Instance constructors,
TextDecoder/TextEncoderovermemory.buffer, closures via the__wbindgen_export_*table, error handling throughhandleError.
Scope
WebAssembly.Global(mutable i32/i64,.value),WebAssembly.Table(grow,get,set, funcref),Memoryshared between main and side instances, Proxy-backed import objects (propertygettrap per symbol, functions and globals),Module.customSections, syncnew Module/new Instance,instantiate(bytes|module, imports).- Minimal
wasi_snapshot_preview1(fd_writeto stdout/stderr,fd_close,fd_seek,clock_time_get) as the loader provides them through theenv/wasi proxies (JS-side implementations; the host only needs to call back). - Asset packaging for both spellings: dynamic
import("pkg/x.wasm", { with: { type: "wasm" } })resolving to a path string (shell.tspasses it throughresolveWasm), andwith { type: "file" }static imports returning an absolute on-disk (or extracted) path;.scmtext assets for the highlighter. - The same loader runs inside the opentui Worker (AOT/runtime: verify the three Worker entrypoints of OpenCode v1.18.30 end-to-end (TUI server worker, OpenTUI parser worker, thread-stream) #10103): wasm + Proxy imports + Table growth on a worker thread.
- Performance guard: grammar load must not dominate TUI startup (tree-sitter-typescript is 1.4 M); measure
Language.loadtime vs bun.
Acceptance
- Native binary: shell tool parses
ls -la | grep foo && echo donewith the Bash grammar and a PowerShell snippet (parity with bun on the parsed command tree used bypackages/opencode/src/tool/shell.ts). - TUI highlights a TypeScript and a Markdown block through
parser.worker.js. - Image attach path: photon decodes/resizes a PNG (
packages/core/src/image/photon.ts) with byte-identical output to bun. -
@silvia-odwyer/photon-nodemodule init succeeds synchronously (no async instantiate required). - No runtime JS engine involved;
PERRY_WASM_*diagnostics list the loaded modules.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew capability or improvementNew capability or improvementparityCompatibility gap with Node.js, ECMAScript, or the supported ecosystemCompatibility gap with Node.js, ECMAScript, or the supported ecosystem
Activity
proggeramlug commentedon Sep 12, 2026
Fixed by #10138, landed on
mainvia merge train #10140 at1828fd691a.The close keyword does not fire through a train branch, so closing manually.