wasm-idle 1.0.0-next.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +369 -159
  2. package/dist/playground/applicationAssets.d.ts +4 -0
  3. package/dist/playground/applicationAssets.js +277 -0
  4. package/dist/playground/assemblyscript.d.ts +16 -2
  5. package/dist/playground/assemblyscript.js +533 -61
  6. package/dist/playground/assetBridge.d.ts +18 -7
  7. package/dist/playground/assetBridge.js +821 -95
  8. package/dist/playground/assets.d.ts +482 -13
  9. package/dist/playground/assets.js +1178 -56
  10. package/dist/playground/awk.js +46 -2
  11. package/dist/playground/bash.d.ts +36 -26
  12. package/dist/playground/bash.js +1057 -152
  13. package/dist/playground/bashWorkerProtocol.d.ts +88 -0
  14. package/dist/playground/bashWorkerProtocol.js +135 -0
  15. package/dist/playground/bqn.js +42 -2
  16. package/dist/playground/bqnPreflight.d.ts +26 -0
  17. package/dist/playground/bqnPreflight.js +399 -0
  18. package/dist/playground/c3.d.ts +15 -0
  19. package/dist/playground/c3.js +154 -0
  20. package/dist/playground/clang.d.ts +27 -7
  21. package/dist/playground/clang.js +208 -31
  22. package/dist/playground/clangAssetIntegrity.d.ts +32 -0
  23. package/dist/playground/clangAssetIntegrity.js +8 -0
  24. package/dist/playground/clojurescript.js +45 -2
  25. package/dist/playground/clojurescriptPreflight.d.ts +26 -0
  26. package/dist/playground/clojurescriptPreflight.js +383 -0
  27. package/dist/playground/cobol.d.ts +18 -2
  28. package/dist/playground/cobol.js +619 -101
  29. package/dist/playground/d.d.ts +23 -3
  30. package/dist/playground/d.js +562 -83
  31. package/dist/playground/dOuterAssets.d.ts +16 -0
  32. package/dist/playground/dOuterAssets.js +163 -0
  33. package/dist/playground/dotnet.d.ts +28 -3
  34. package/dist/playground/dotnet.js +976 -138
  35. package/dist/playground/duckdb.d.ts +16 -2
  36. package/dist/playground/duckdb.js +497 -67
  37. package/dist/playground/elixir.d.ts +11 -2
  38. package/dist/playground/elixir.js +613 -94
  39. package/dist/playground/elixirAssets.d.ts +6 -0
  40. package/dist/playground/elixirAssets.js +33 -0
  41. package/dist/playground/executionObservation.d.ts +22 -0
  42. package/dist/playground/executionObservation.js +65 -0
  43. package/dist/playground/forth.js +39 -2
  44. package/dist/playground/forthPreflight.d.ts +24 -0
  45. package/dist/playground/forthPreflight.js +198 -0
  46. package/dist/playground/fortran.d.ts +19 -2
  47. package/dist/playground/fortran.js +557 -99
  48. package/dist/playground/fortranAssets.d.ts +6 -0
  49. package/dist/playground/fortranAssets.js +27 -0
  50. package/dist/playground/gleam.d.ts +1 -0
  51. package/dist/playground/gleam.js +18 -2
  52. package/dist/playground/go.d.ts +8 -2
  53. package/dist/playground/go.js +329 -61
  54. package/dist/playground/haskell.d.ts +19 -2
  55. package/dist/playground/haskell.js +588 -100
  56. package/dist/playground/haskellAssets.d.ts +24 -0
  57. package/dist/playground/haskellAssets.js +93 -0
  58. package/dist/playground/index.d.ts +1 -1
  59. package/dist/playground/index.js +78 -60
  60. package/dist/playground/j.js +45 -2
  61. package/dist/playground/jPreflight.d.ts +26 -0
  62. package/dist/playground/jPreflight.js +372 -0
  63. package/dist/playground/janet.js +51 -2
  64. package/dist/playground/java.d.ts +20 -2
  65. package/dist/playground/java.js +697 -82
  66. package/dist/playground/javaSource.d.ts +5 -0
  67. package/dist/playground/javaSource.js +16 -0
  68. package/dist/playground/javaStdin.d.ts +1 -1
  69. package/dist/playground/javaStdin.js +13 -4
  70. package/dist/playground/julia.js +52 -2
  71. package/dist/playground/lfortran.d.ts +8 -0
  72. package/dist/playground/lfortran.js +30 -0
  73. package/dist/playground/lfortranAssets.d.ts +21 -0
  74. package/dist/playground/lfortranAssets.js +118 -0
  75. package/dist/playground/lisp.d.ts +20 -2
  76. package/dist/playground/lisp.js +558 -83
  77. package/dist/playground/lispAssets.d.ts +9 -0
  78. package/dist/playground/lispAssets.js +74 -0
  79. package/dist/playground/lldbManifest.d.ts +3 -0
  80. package/dist/playground/lldbManifest.js +155 -0
  81. package/dist/playground/lldbSession.d.ts +115 -0
  82. package/dist/playground/lldbSession.js +1347 -0
  83. package/dist/playground/loadingProgress.d.ts +5 -11
  84. package/dist/playground/loadingProgress.js +147 -57
  85. package/dist/playground/lua.d.ts +19 -2
  86. package/dist/playground/lua.js +547 -82
  87. package/dist/playground/nim.js +64 -2
  88. package/dist/playground/objectivec.js +52 -19
  89. package/dist/playground/ocaml.d.ts +24 -2
  90. package/dist/playground/ocaml.js +805 -243
  91. package/dist/playground/octave.d.ts +11 -2
  92. package/dist/playground/octave.js +659 -69
  93. package/dist/playground/options.d.ts +11 -1
  94. package/dist/playground/pascal.js +46 -2
  95. package/dist/playground/perl.js +47 -2
  96. package/dist/playground/php.d.ts +19 -2
  97. package/dist/playground/php.js +584 -81
  98. package/dist/playground/prolog.d.ts +1 -0
  99. package/dist/playground/prolog.js +61 -2
  100. package/dist/playground/python.d.ts +12 -2
  101. package/dist/playground/python.js +429 -100
  102. package/dist/playground/pythonPackageLock.d.ts +6 -0
  103. package/dist/playground/pythonPackageLock.js +56 -0
  104. package/dist/playground/r.d.ts +19 -2
  105. package/dist/playground/r.js +553 -83
  106. package/dist/playground/ruby.d.ts +20 -2
  107. package/dist/playground/ruby.js +651 -85
  108. package/dist/playground/rubyAssets.d.ts +23 -0
  109. package/dist/playground/rubyAssets.js +68 -0
  110. package/dist/playground/rubyTestPreflight.d.ts +2 -0
  111. package/dist/playground/rubyTestPreflight.js +18 -0
  112. package/dist/playground/rust.d.ts +36 -6
  113. package/dist/playground/rust.js +673 -78
  114. package/dist/playground/rustExecutableGraph.d.ts +85 -0
  115. package/dist/playground/rustExecutableGraph.js +946 -0
  116. package/dist/playground/rustWorkerLimits.d.ts +17 -0
  117. package/dist/playground/rustWorkerLimits.js +34 -0
  118. package/dist/playground/sandbox.d.ts +15 -7
  119. package/dist/playground/sqlite.d.ts +17 -2
  120. package/dist/playground/sqlite.js +504 -71
  121. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
  122. package/dist/playground/staticRuntimeModuleVersion.js +1 -1
  123. package/dist/playground/staticRuntimePreflight.d.ts +13 -0
  124. package/dist/playground/staticRuntimePreflight.js +231 -0
  125. package/dist/playground/staticRuntimePreflightExecute.d.ts +8 -0
  126. package/dist/playground/staticRuntimePreflightExecute.js +66 -0
  127. package/dist/playground/staticRuntimePreflightProtocol.d.ts +68 -0
  128. package/dist/playground/staticRuntimePreflightProtocol.js +339 -0
  129. package/dist/playground/staticStdinRing.d.ts +45 -0
  130. package/dist/playground/staticStdinRing.js +158 -0
  131. package/dist/playground/staticWorkerRuntime.d.ts +89 -6
  132. package/dist/playground/staticWorkerRuntime.js +1729 -168
  133. package/dist/playground/stdinBuffer.js +6 -18
  134. package/dist/playground/swift.js +4 -1
  135. package/dist/playground/tcl.js +48 -2
  136. package/dist/playground/tinygo.d.ts +43 -5
  137. package/dist/playground/tinygo.js +1201 -230
  138. package/dist/playground/tinygoExecutableGraph.d.ts +44 -0
  139. package/dist/playground/tinygoExecutableGraph.js +449 -0
  140. package/dist/playground/typescript.d.ts +26 -3
  141. package/dist/playground/typescript.js +834 -86
  142. package/dist/playground/wasm.d.ts +19 -2
  143. package/dist/playground/wasm.js +528 -71
  144. package/dist/playground/wasmAwkVersion.d.ts +59 -1
  145. package/dist/playground/wasmAwkVersion.js +31 -1
  146. package/dist/playground/wasmBashVersion.d.ts +63 -1
  147. package/dist/playground/wasmBashVersion.js +36 -1
  148. package/dist/playground/wasmBqnVersion.d.ts +24 -1
  149. package/dist/playground/wasmBqnVersion.js +24 -1
  150. package/dist/playground/wasmC3Version.d.ts +20 -0
  151. package/dist/playground/wasmC3Version.js +21 -0
  152. package/dist/playground/wasmClojureScriptVersion.d.ts +21 -1
  153. package/dist/playground/wasmClojureScriptVersion.js +21 -1
  154. package/dist/playground/wasmDIntegrity.d.ts +15 -0
  155. package/dist/playground/wasmDIntegrity.js +15 -0
  156. package/dist/playground/wasmDVersion.d.ts +1 -1
  157. package/dist/playground/wasmDVersion.js +1 -1
  158. package/dist/playground/wasmDebugVersion.d.ts +6 -0
  159. package/dist/playground/wasmDebugVersion.js +6 -0
  160. package/dist/playground/wasmDotnetVersion.d.ts +1 -1
  161. package/dist/playground/wasmDotnetVersion.js +1 -1
  162. package/dist/playground/wasmElixirVersion.d.ts +21 -1
  163. package/dist/playground/wasmElixirVersion.js +21 -1
  164. package/dist/playground/wasmForthVersion.d.ts +18 -1
  165. package/dist/playground/wasmForthVersion.js +18 -1
  166. package/dist/playground/wasmFortranExecutionAssets.d.ts +15 -0
  167. package/dist/playground/wasmFortranExecutionAssets.js +15 -0
  168. package/dist/playground/wasmGleamVersion.d.ts +5 -1
  169. package/dist/playground/wasmGleamVersion.js +5 -1
  170. package/dist/playground/wasmHaskellVersion.d.ts +1 -1
  171. package/dist/playground/wasmHaskellVersion.js +1 -1
  172. package/dist/playground/wasmJVersion.d.ts +24 -1
  173. package/dist/playground/wasmJVersion.js +24 -1
  174. package/dist/playground/wasmJanetVersion.d.ts +53 -1
  175. package/dist/playground/wasmJanetVersion.js +30 -1
  176. package/dist/playground/wasmJuliaVersion.d.ts +71 -1
  177. package/dist/playground/wasmJuliaVersion.js +39 -1
  178. package/dist/playground/wasmLfortranVersion.d.ts +28 -0
  179. package/dist/playground/wasmLfortranVersion.js +29 -0
  180. package/dist/playground/wasmLispVersion.d.ts +1 -1
  181. package/dist/playground/wasmLispVersion.js +1 -1
  182. package/dist/playground/wasmNimVersion.d.ts +125 -1
  183. package/dist/playground/wasmNimVersion.js +66 -1
  184. package/dist/playground/wasmObjectiveCVersion.d.ts +27 -1
  185. package/dist/playground/wasmObjectiveCVersion.js +27 -1
  186. package/dist/playground/wasmOcamlVersion.d.ts +12 -1
  187. package/dist/playground/wasmOcamlVersion.js +12 -1
  188. package/dist/playground/wasmOctaveVersion.d.ts +1 -1
  189. package/dist/playground/wasmOctaveVersion.js +1 -1
  190. package/dist/playground/wasmPascalVersion.d.ts +61 -1
  191. package/dist/playground/wasmPascalVersion.js +34 -1
  192. package/dist/playground/wasmPerlVersion.d.ts +71 -1
  193. package/dist/playground/wasmPerlVersion.js +39 -1
  194. package/dist/playground/wasmPrologVersion.d.ts +31 -1
  195. package/dist/playground/wasmPrologVersion.js +31 -1
  196. package/dist/playground/wasmRustVersion.d.ts +1306 -1
  197. package/dist/playground/wasmRustVersion.js +1458 -1
  198. package/dist/playground/wasmTclVersion.d.ts +85 -1
  199. package/dist/playground/wasmTclVersion.js +46 -1
  200. package/dist/playground/wasmTinyGoVersion.d.ts +98 -1
  201. package/dist/playground/wasmTinyGoVersion.js +107 -1
  202. package/dist/playground/wasmTypeScriptVersion.d.ts +5 -1
  203. package/dist/playground/wasmTypeScriptVersion.js +5 -1
  204. package/dist/playground/wasmZigVersion.d.ts +13 -1
  205. package/dist/playground/wasmZigVersion.js +13 -1
  206. package/dist/playground/wat.d.ts +19 -2
  207. package/dist/playground/wat.js +540 -80
  208. package/dist/playground/worker/assemblyscript.js +8 -0
  209. package/dist/playground/worker/assets.d.ts +7 -0
  210. package/dist/playground/worker/assets.js +288 -39
  211. package/dist/playground/worker/bash.d.ts +1 -0
  212. package/dist/playground/worker/bash.js +338 -0
  213. package/dist/playground/worker/bashNestedBootstrap.d.ts +6 -0
  214. package/dist/playground/worker/bashNestedBootstrap.js +59 -0
  215. package/dist/playground/worker/bashRuntime.d.ts +89 -0
  216. package/dist/playground/worker/bashRuntime.js +982 -0
  217. package/dist/playground/worker/clang.js +49 -9
  218. package/dist/playground/worker/cobol.js +6 -3
  219. package/dist/playground/worker/d.js +61 -18
  220. package/dist/playground/worker/dotnet.js +15 -2
  221. package/dist/playground/worker/duckdb.js +8 -0
  222. package/dist/playground/worker/elixir.js +135 -33
  223. package/dist/playground/worker/fortran.js +47 -19
  224. package/dist/playground/worker/go.js +39 -8
  225. package/dist/playground/worker/haskell.js +197 -95
  226. package/dist/playground/worker/java.js +58 -21
  227. package/dist/playground/worker/lisp.js +50 -16
  228. package/dist/playground/worker/lua.js +8 -0
  229. package/dist/playground/worker/objectivec.js +3 -1
  230. package/dist/playground/worker/ocaml.js +184 -36
  231. package/dist/playground/worker/php.js +111 -3
  232. package/dist/playground/worker/python.js +114 -11
  233. package/dist/playground/worker/r.js +8 -0
  234. package/dist/playground/worker/ruby.js +90 -39
  235. package/dist/playground/worker/runtimeAssetFetch.d.ts +15 -0
  236. package/dist/playground/worker/runtimeAssetFetch.js +375 -0
  237. package/dist/playground/worker/rust.js +352 -24
  238. package/dist/playground/worker/sqlite.js +8 -0
  239. package/dist/playground/worker/staticRuntimePreflight.d.ts +1 -0
  240. package/dist/playground/worker/staticRuntimePreflight.js +56 -0
  241. package/dist/playground/worker/tinygo.js +34 -9
  242. package/dist/playground/worker/typescript.js +102 -11
  243. package/dist/playground/worker/wasm.js +8 -0
  244. package/dist/playground/worker/wat.js +8 -0
  245. package/dist/playground/worker/zig.d.ts +7 -0
  246. package/dist/playground/worker/zig.js +268 -66
  247. package/dist/playground/workerProgress.d.ts +9 -2
  248. package/dist/playground/workerProgress.js +60 -1
  249. package/dist/playground/workerSession.d.ts +6 -2
  250. package/dist/playground/workerSession.js +67 -10
  251. package/dist/playground/zig.d.ts +20 -2
  252. package/dist/playground/zig.js +605 -91
  253. package/dist/playground/zigAssets.d.ts +6 -0
  254. package/dist/playground/zigAssets.js +49 -0
  255. package/package.json +47 -13
package/README.md CHANGED
@@ -2,12 +2,18 @@
2
2
 
3
3
  ![wasm-idle](static/image.jpeg)
4
4
 
5
- Executes C, C++, Python, Java, Rust, Go, D, C#, F#, VB.NET, Elixir, Erlang, Prolog,
6
- Gleam, Perl, Tcl, AWK, Pascal, Forth, J, BQN, Janet, Julia, Nim, Bash, ClojureScript, TinyGo, OCaml, JavaScript, TypeScript,
5
+ Executes C, C++, Objective-C, Fortran, COBOL, Python, Java, Rust, Go, D, C#, F#, VB.NET, Elixir, Erlang, Prolog,
6
+ Gleam, Perl, Tcl, AWK, Pascal, Forth, J, BQN, Janet, Julia, Nim, Bash, ClojureScript, OCaml, JavaScript, TypeScript,
7
7
  AssemblyScript, WAT, WASM, Lua, Zig, Scheme, Ruby, Haskell, R, Octave, SQLite, DuckDB,
8
8
  and PHP code.
9
9
 
10
- Refer to src/lib/clang.
10
+ Experimental LFortran execution is available separately from f2c Fortran; see
11
+ [the LFortran consumer contract and local setup](docs/lfortran.md).
12
+
13
+ The browser-side C-family host is provided by [`@wasm-idle/llvm-core`](packages/llvm-core).
14
+ Compiler source pins, patches, and reproducible asset builds live in
15
+ [`seo-rii/wasm-llvm`](https://github.com/seo-rii/wasm-llvm); wasm-idle loads the generated
16
+ artifacts from external URLs instead of embedding them in npm packages.
11
17
 
12
18
  ## Language support policy
13
19
 
@@ -21,17 +27,18 @@ documented stdin limitation, is covered by tests.
21
27
 
22
28
  All execution entries run in the browser through real runtime, compiler, or interpreter
23
29
  implementations. `Editor support` lists browser LSP/compiler diagnostics when wired; `syntax`
24
- means Monaco syntax highlighting only. `Debug` means wasm-idle's trace/debug controls, not a
25
- native debugger.
30
+ means Monaco syntax highlighting only. C, C++, and `wasm32-wasip1` Rust use the browser LLDB/WAMR
31
+ debug runtime; the remaining debug-enabled languages retain wasm-idle's trace controls.
26
32
 
27
33
  | Language | Browser runtime/compiler | Stdin | Editor support | Debug |
28
34
  | -------------- | --------------------------------------- | ----- | -------------------- | ----- |
29
- | C | @wasm-idle/llvm-core / Clang WASI | Yes | clangd | Trace |
30
- | C++ | @wasm-idle/llvm-core / Clang WASI | Yes | clangd | Trace |
35
+ | C3 | C3 0.8.3 + LLVM/lld WASM (byte ABI) | Yes | compiler diagnostics | - |
36
+ | C | @wasm-idle/llvm-core / Clang WASI | Yes | clangd | LLDB |
37
+ | C++ | @wasm-idle/llvm-core / Clang WASI | Yes | clangd | LLDB |
31
38
  | Objective-C | GNUstep libobjc2 + @wasm-idle/llvm-core | Yes | clangd | Trace |
32
39
  | Python | Pyodide | Yes | Python LSP | Trace |
33
40
  | Java | TeaVM | Yes | syntax | - |
34
- | Rust | wasm-rust / browser rustc | Yes | rustc diagnostics | Trace |
41
+ | Rust | wasm-rust / browser rustc | Yes | rustc diagnostics | LLDB |
35
42
  | Go | wasm-go / browser Go compiler | Yes | compiler diagnostics | Trace |
36
43
  | D | wasm-d | Yes | syntax | - |
37
44
  | C# | wasm-dotnet | Yes | compiler diagnostics | - |
@@ -49,7 +56,7 @@ native debugger.
49
56
  | J | J playground WASM worker | Yes | syntax | - |
50
57
  | BQN | CBQN WASM worker | Yes | syntax | - |
51
58
  | Janet | Janet VM WASM worker | Yes | syntax | - |
52
- | Julia | Julia 1.0.4 WASM worker | Yes | syntax | - |
59
+ | Julia | Julia 1.3.0-DEV.560 legacy WASM worker | Yes | syntax | - |
53
60
  | Nim | Nim 2.2.4 WASM + clang/lld WASM | Yes | syntax | - |
54
61
  | Bash | GNU Bash WASIX / Wasmer SDK | Yes | syntax | - |
55
62
  | ClojureScript | cljs.js self-hosted compiler | Yes | syntax | - |
@@ -65,6 +72,7 @@ native debugger.
65
72
  | Scheme | Puppy Scheme / wasm-lisp | Yes | syntax | - |
66
73
  | Ruby | CRuby WASI | Yes | syntax | - |
67
74
  | Haskell | ghc-in-browser | Yes | syntax | - |
75
+ | LFortran | LFortran LLVM evaluator (experimental) | Yes | compiler diagnostics | - |
68
76
  | Fortran | f2c + @wasm-idle/llvm-core | Yes | Fortran LSP | - |
69
77
  | COBOL | GnuCOBOL 3.2 + @wasm-idle/llvm-core | Yes | syntax | - |
70
78
  | R | WebR | Yes | syntax | - |
@@ -73,6 +81,133 @@ native debugger.
73
81
  | SQLite | sql.js | n/a | syntax | - |
74
82
  | PHP | PHP 8.4 / php-wasm | Yes | syntax | - |
75
83
 
84
+ ## Browser LLDB debug runtime
85
+
86
+ Normal execution still compiles and instantiates the user module with the browser WebAssembly
87
+ engine and the existing WASI host. C, C++, and `wasm32-wasip1` Rust debug sessions use a separate,
88
+ lazy-loaded path:
89
+
90
+ ```text
91
+ Monaco / debug UI
92
+ ↕ DAP over a SharedArrayBuffer byte stream
93
+ LLDB worker (ProcessWasm + DWARF)
94
+ ↕ GDB RSP over a separate SharedArrayBuffer byte stream
95
+ WAMR target worker (classic interpreter + source-debug stub)
96
+ ↕
97
+ program.wasm + embedded DWARF + WASI
98
+ ```
99
+
100
+ The compiler writes stable `/workspace/...` paths and embedded DWARF at `-O0`. The target is loaded
101
+ before LLDB attaches; breakpoints and `configurationDone` are completed before WAMR starts the
102
+ guest. Program output, input, lifecycle control, DAP, and RSP use separate logical streams.
103
+ Breakpoints are retained per source path, so switching between C/C++ workspace files does not leak
104
+ line numbers into another file and changes made while compilation is in flight are applied when the
105
+ debug target connects.
106
+ `@wasm-idle/debug` remains a code-only UI/adapter package, while
107
+ `@wasm-idle/llvm-core/debug` owns the browser session and `wasm-llvm` owns the pinned LLDB/WAMR
108
+ producers and binary manifests.
109
+
110
+ Debugging requires `SharedArrayBuffer` and a cross-origin-isolated deployment. Because verified
111
+ runtime bytes are executed through Blob-backed ES modules and nested pthread Workers, the deployed
112
+ Content Security Policy's `script-src`, `worker-src`, and `connect-src` must permit `blob:`. The
113
+ LLDB and WAMR assets are not downloaded until a supported debug session starts. The bundled raw manifest is
114
+ checked against its release receipt before parsing, and custom runtime locations must provide an
115
+ explicit expected manifest SHA-256. The six executable assets are then streamed, bounded, and
116
+ hash-verified exactly once before their owned bytes are transferred to the Workers. Workers do not
117
+ re-fetch executable runtime URLs. Clean Pages builds fetch the exact pinned producer revision and
118
+ manifest receipt through the shared release profile before the application build. The deployment
119
+ refuses publication when any logical LLDB/WAMR asset is missing or mismatched after re-verifying
120
+ raw or compressed logical bytes. If transactional publication cannot safely restore or identify an
121
+ owned generation, its `.wasm-debug.next-*` and `.wasm-debug.previous-*` recovery artifacts are
122
+ preserved for operator inspection. Later synchronization and the final Pages verifier fail closed
123
+ until those artifacts (or a leftover `.wasm-debug.sync.lock*`) are manually inspected and resolved;
124
+ they are never silently deleted or published. This build-time preparation does not change lazy browser loading:
125
+ clients fetch the debugger payload only when a supported debug session starts. If the LLDB manifest
126
+ is absent, invalid, or does not advertise
127
+ the required breakpoint/step/stack/local capabilities, the
128
+ playground labels that run as a trace fallback and keeps the existing instrumentation debugger
129
+ available. LLDB-designated browser fixtures reject trace fallback, while a separate missing-asset
130
+ fixture qualifies the pre-session trace alternative. Build and verify both producers
131
+ using [`producer/lldb-browser`](../wasm-llvm/producer/lldb-browser) and
132
+ [`producer/wamr-browser`](../wasm-llvm/producer/wamr-browser), then assemble them with the Clang
133
+ release:
134
+
135
+ Stable v1 is release-qualified on 64-bit desktop Chromium on Linux. It supports one active debug
136
+ session for `wasm32-wasi` Preview 1 C/C++ and `wasm32-wasip1` Rust artifacts produced by the
137
+ pinned toolchains at `-O0` with embedded DWARF. Debug starts a new, single-threaded WAMR classic
138
+ interpreter instance; it does not attach to a browser-engine run or preserve that run's live state,
139
+ and runtime-specific behavior can differ. Trace fallback is selected only before an LLDB session is
140
+ established; an LLDB or WAMR failure ends that session instead of silently changing debugger
141
+ semantics.
142
+
143
+ Stable v2 inherits that exact release boundary: 64-bit desktop Chromium on Linux, a
144
+ cross-origin-isolated deployment, one active session, pinned C/C++ and `wasm32-wasip1` Rust
145
+ producer artifacts at `-O0` with embedded DWARF, and a new WAMR debug execution rather than an
146
+ attachment to an existing browser-engine run. DAP is an internal product protocol boundary; v2
147
+ does not claim compatibility with arbitrary third-party DAP clients or arbitrary externally
148
+ produced Wasm/DWARF artifacts.
149
+
150
+ Pause is bounded but is not guaranteed to yield an inspectable stop while WAMR is blocked in a
151
+ synchronous host call. In particular, a synchronous WAMR stdin read may time out instead of
152
+ producing an inspectable pause. After that explicit timeout, **Stop Debug** still performs bounded
153
+ Worker cleanup and permits a fresh debug execution; the session never remains indefinitely pending.
154
+
155
+ Stable v2 adds bounded variable-path watches and a paused-target memory inspector.
156
+ Watch fallback accepts identifiers, nested fields, and non-negative indexes without enabling general
157
+ expression evaluation. The memory panel can select a variable's DAP `memoryReference`, reads at most
158
+ 256 bytes per request, pages by the selected byte count, renders hexadecimal/ASCII data and unreadable
159
+ bytes as `??`, and discards a response when the target resumes or the selected frame changes. While
160
+ paused, it also accepts 1–256 two-digit hexadecimal bytes for a raw target-memory write and refreshes
161
+ the displayed range after a successful write. This edits memory only; it does not provide typed
162
+ `setVariable` semantics, validate that a value is safe for the guest, or preserve the mutation after
163
+ restart. The complete UI write path is qualified in real Chromium with `wasm32-wasi` C/C++ and
164
+ `wasm32-wasip1` Rust programs.
165
+ While paused, the same panel can install one session-scoped LLDB data breakpoint over a 1–256 byte
166
+ memory range. The browser gate qualifies `wasm32-wasi` C write, C++ read/write, and
167
+ `wasm32-wasip1` Rust read access. Setting a new data breakpoint replaces the previous set, and
168
+ **Clear** sends an empty replacement set to the target. Its opaque DAP data ID is never persisted
169
+ across restart or a new debug execution. Because WAMR reports a completed memory access, the stopped
170
+ source location can be the next executable line after the watched instruction.
171
+ If a replacement or clear request times out, is rejected, or returns malformed DAP data, the debug
172
+ execution stops and disposes both Workers so the UI cannot continue with an uncertain watchpoint
173
+ set; **Restart Debug** then starts a clean execution. A successful but unverified replacement remains
174
+ nonfatal and is reported as unverified.
175
+ The Chromium qualification includes an indexed one-byte watched subrange that overlaps a four-byte scalar store.
176
+ LLDB uses modify semantics for write mode: a write data breakpoint stops when at least one watched byte changes;
177
+ a same-value store is reported by WAMR but automatically resumed by LLDB.
178
+ Data breakpoints cover scalar classic-interpreter loads and stores only.
179
+ Bulk-memory operations and host-side memory writes do not trigger data breakpoints; guest threads
180
+ and memories outside the supported linear-memory configuration remain out of scope. Trace fallback
181
+ does not advertise or emulate data breakpoints.
182
+ The v2 **Restart Debug** action fully disposes the active LLDB and WAMR Workers, waits for the old
183
+ execution to settle, and launches a fresh debug execution from the current workspace. It does not
184
+ preserve target state or advertise the DAP `restart` capability.
185
+
186
+ Full expression evaluation, conditional/log breakpoints, typed variable mutation through DAP
187
+ `setVariable`, DAP in-session restart, standalone terminate, optimized-debug guarantees, C++
188
+ exception support, STL pretty-printers, `wasm64`, guest threads, reverse debugging, SIMD,
189
+ multi-module guests, and Rust WASI Preview 2/3 debugging remain outside the supported boundary.
190
+
191
+ ```sh
192
+ cd ../wasm-llvm
193
+ WASM_LLVM_LLDB_ARTIFACT_DIR=/path/to/lldb-artifacts \
194
+ WASM_LLVM_WAMR_ARTIFACT_DIR=/path/to/wamr-artifacts \
195
+ pnpm prepare:clang-release
196
+
197
+ cd ../wasm-idle
198
+ WASM_RUST_PRODUCER_OUTPUT_ROOT=/path/to/rust-producer-output \
199
+ pnpm --dir runtimes/wasm-rust build:producer
200
+ pnpm sync:wasm-rust
201
+ pnpm sync:wasm-debug ../wasm-llvm/out/clang-browser
202
+ WASM_IDLE_BROWSER_SERVER_MODE=dev pnpm test:browser:debug:lldb
203
+ ```
204
+
205
+ The synchronized manifest rejects missing hashes, incompatible Clang/LLDB revisions, and stale
206
+ worker sidecars. The strict browser test covers real C, C++, and Rust breakpoint, step, output, and
207
+ termination paths and rejects trace fallback or a missing debug asset. The Rust producer build is
208
+ required for LLDB metadata; the historical split-runtime build intentionally lacks exact compiler
209
+ provenance and is rejected instead of starting a potentially incompatible debugger.
210
+
76
211
  ### Runtime details
77
212
 
78
213
  `Package/version base` names the deployed static module or manifest and its producer package,
@@ -83,54 +218,56 @@ targets and flags wasm-idle applies, plus the public per-run options that change
83
218
  `Customization` lists the `runtimeAssets` fields and matching `PUBLIC_WASM_*` env overrides
84
219
  when they exist.
85
220
 
86
- | Language / IDs | Package/version base | Execution defaults / flags | Customization |
87
- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
88
- | C<br>`C` | @wasm-idle/llvm-core@1.0.0-next.0 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang` for `wasm32-wasi`; default `-std=gnu11`; native gzip delivery for compiler Wasm and sysroot tar assets; trace debug uses wasm-idle controls; WASI preview1 execution supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cVersion`, `activePath`, `workspaceFiles`, `debug`, `breakpoints`, `pauseOnEntry` |
89
- | C++<br>`CPP` | @wasm-idle/llvm-core@1.0.0-next.0 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang++` for `wasm32-wasi`; default `-std=gnu++2a`; native gzip delivery for compiler Wasm and sysroot tar assets; trace debug uses wasm-idle controls; supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cppVersion`, `activePath`, `workspaceFiles`, `debug`, `breakpoints`, `pauseOnEntry` |
90
- | Objective-C<br>`OBJC` | GNUstep libobjc2 v2.3 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.0-next.0 | `clang -x objective-c -fobjc-runtime=gnustep-2.0 -fblocks` for `wasm32-wasi`; links `libobjc.a`, `libgnustep-base.a`, and `libffi.a` when Foundation is imported; Foundation headers are inlined from `foundation-headers.json`; includes a constructor wrapper for Objective-C class registration; auto-compiles `.m` and `.c` workspace sources; trace debug instruments active source and uses wasm-idle controls; supports `stdin` and `programArgs`; large Objective-C assets may be served as gzip-only `.gz` files through the service worker or worker fallback | `runtimeAssets.objectivec.baseUrl`/`libobjcUrl`/`headersUrl`/`libgnustepBaseUrl`/`libgnustepBaseObjectUrl`/`foundationHeadersUrl`/`libffiUrl` or `PUBLIC_WASM_OBJECTIVEC_*`; `runtimeAssets.clang.baseUrl`/`loader` for the clang toolchain; `activePath`, `workspaceFiles`, `compileArgs`, `debug`, `breakpoints`, `pauseOnEntry` |
91
- | Python<br>`PYTHON3`, `PYPY3` | static ESM `static/pyodide/pyodide.mjs` / pyodide@0.29.3 | loads `pyodide.mjs`, `pyodide.asm.js`, `pyodide.asm.wasm`, and `python_stdlib.zip` from the configured static asset tree on demand; supports `stdin`, workspace files, and trace debugging | `runtimeAssets.python.baseUrl`/`loader` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles`, `debug`, `breakpoints`, `pauseOnEntry`, `debugPath` |
92
- | Java<br>`JAVA` | @wasm-idle/runtime-teavm@0.0.0 / TeaVM compiler assets | `compiler.wasm` compiles Java to browser WASM/JS; supports `stdin` and `programArgs` | `runtimeAssets.java.baseUrl`/`loader` or `rootUrl` |
93
- | Rust<br>`RUST` | wasm-rust@0.1.0 / rust-1.99.0-browser-integrated-v1 + integrated LLVM/LLD 22.1.8 from the `wasm-llvm` producer; `debug-instrumenter.js` is a separately generated static asset | browser host `wasm32-wasip1-threads`; `rustc -Zthreads=1 -Zcodegen-backend=llvm --crate-type=bin --edition=2024 -Cpanic=abort -Ccodegen-units=1 --emit=link`; default target `wasm32-wasip1`, selectable `wasm32-wasip1`, `wasm32-wasip2`, `wasm32-wasip3`; Preview 1 emits core Wasm and Preview 2/3 are component-encoded; supports `stdin` and `programArgs`; the debug instrumenter is fetched only for debug runs | `runtimeAssets.rust.compilerUrl`, `runtimeAssets.rust.debugModuleUrl`, or `PUBLIC_WASM_RUST_COMPILER_URL`; `rootUrl`, `rustTargetTriple`, `programArgs`; compiler requests accept `edition`, `crateType`, `extendedTimeout`, `log`, and `onProgress`; runtime manifest controls compiler memory, timeout, and shared workspace size |
94
- | Go<br>`GO` | wasm-go@0.1.0 / go1.26.1 | default target `wasip1/wasm`; selectable `wasip1/wasm`, `wasip2/wasm`, `wasip3/wasm`, `js/wasm`; supports `stdin` and `programArgs` | `runtimeAssets.go.compilerUrl` or `PUBLIC_WASM_GO_COMPILER_URL`; `goTarget`, `programArgs` |
95
- | D<br>`D` | wasm-d@0.1.0 / ldc-1.42.0-wasi-smoke | `ldc2 -conf=/toolchain/etc/ldc2.conf -mtriple=wasm32-wasi -c` then `wasm-ld` to WASI preview1; supports `stdin` and `programArgs` | `runtimeAssets.d.moduleUrl` or `PUBLIC_WASM_D_MODULE_URL`; `activePath`, `programArgs` |
96
- | C#<br>`CSHARP` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / Roslyn C# 4.14.0 | `CSharpCompilationOptions(OutputKind.ConsoleApplication)`; `concurrentBuild=false`; target `browser-wasm`; language-specific AOT bundle `runtime/csharp/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
97
- | F#<br>`FSHARP` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / FCS 43.12.204 / FSharp.Core 10.1.204 | `fsc.exe --target:exe --targetprofile:netcore --noframework --simpleresolution --nowin32manifest --debug- --optimize-`; language-specific AOT bundle `runtime/fsharp/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
98
- | VB.NET<br>`VBNET` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / Roslyn Visual Basic 4.14.0 | `VisualBasicCompilationOptions(OutputKind.ConsoleApplication)`; `concurrentBuild=false`, `OptionStrict=Off`, `OptionInfer=On`, `OptionExplicit=On`; target `browser-wasm`; language-specific AOT bundle `runtime/vbnet/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
99
- | Elixir<br>`ELIXIR` | wasm-elixir asset bundle / @swmansion/popcorn@0.2.2 | Popcorn/AtomVM bundle `bundle.avm`; supports `stdin` | `runtimeAssets.elixir.bundleUrl` or `PUBLIC_WASM_ELIXIR_BUNDLE_URL` |
100
- | Erlang<br>`ERLANG` | wasm-elixir asset bundle / @swmansion/popcorn@0.2.2 | Popcorn/AtomVM bundle `bundle.avm`; supports `stdin` | `runtimeAssets.erlang.bundleUrl` or `PUBLIC_WASM_ERLANG_BUNDLE_URL`; falls back to Elixir bundle URL |
101
- | Prolog<br>`PROLOG` | swipl-wasm@8.0.1 synced into `static/wasm-prolog` | static worker runs SWI-Prolog; supports `stdin` and `programArgs` | `runtimeAssets.prolog.baseUrl`/`runtimeAssets.prolog.workerUrl` or `PUBLIC_WASM_PROLOG_BASE_URL`/`PUBLIC_WASM_PROLOG_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
102
- | Gleam<br>`GLEAM` | @live-codes/gleam-precompiled@0.5.0 static worker | Gleam worker compiles/runs browser output with source manifest; supports `stdin` | `runtimeAssets.gleam.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_GLEAM_*`; `programArgs`, `workspaceFiles` |
103
- | Perl<br>`PERL` | WebPerl v0.09-beta (webperl_prebuilt_v0.09-beta.zip) | static worker runs `emperl`; supports `stdin` and `programArgs` | `runtimeAssets.perl.baseUrl`/`runtimeAssets.perl.workerUrl` or `PUBLIC_WASM_PERL_BASE_URL`/`PUBLIC_WASM_PERL_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
104
- | Tcl<br>`TCL` | Wacl Tcl 2017-05-29 (wacl.zip) | static worker runs Wacl Tcl; supports `stdin` and `programArgs` | `runtimeAssets.tcl.baseUrl`/`runtimeAssets.tcl.workerUrl` or `PUBLIC_WASM_TCL_BASE_URL`/`PUBLIC_WASM_TCL_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
105
- | AWK<br>`AWK` | GoAWK v1.31.0 / go1.25.3 | static worker runs `goawk.wasm`; supports `stdin` and `programArgs` | `runtimeAssets.awk.baseUrl`/`runtimeAssets.awk.workerUrl` or `PUBLIC_WASM_AWK_BASE_URL`/`PUBLIC_WASM_AWK_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
106
- | Pascal<br>`PASCAL` | pas2js 3.2.1 (9ac46614dc82) | static worker compiles with pas2js then runs JS; supports `stdin` | `runtimeAssets.pascal.baseUrl`/`runtimeAssets.pascal.workerUrl` or `PUBLIC_WASM_PASCAL_BASE_URL`/`PUBLIC_WASM_PASCAL_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
107
- | Forth<br>`FORTH` | waforth@0.20.1 / static worker | WAForth worker; supports `stdin` and `programArgs` | `runtimeAssets.forth.baseUrl`/`runtimeAssets.forth.workerUrl` or `PUBLIC_WASM_FORTH_BASE_URL`/`PUBLIC_WASM_FORTH_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
108
- | J<br>`J` | jsoftware-j-playground static worker | J playground worker; supports `stdin` and `programArgs` | `runtimeAssets.j.baseUrl`/`runtimeAssets.j.workerUrl` or `PUBLIC_WASM_J_BASE_URL`/`PUBLIC_WASM_J_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
109
- | BQN<br>`BQN` | CBQN static worker / Emscripten 3.1.8 | CBQN worker; supports `stdin` and `programArgs` | `runtimeAssets.bqn.baseUrl`/`runtimeAssets.bqn.workerUrl` or `PUBLIC_WASM_BQN_BASE_URL`/`PUBLIC_WASM_BQN_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
110
- | Janet<br>`JANET` | Janet static worker / Emscripten 3.1.8 | Janet VM worker; supports `stdin` and `programArgs` | `runtimeAssets.janet.baseUrl`/`runtimeAssets.janet.workerUrl` or `PUBLIC_WASM_JANET_BASE_URL`/`PUBLIC_WASM_JANET_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
111
- | Julia<br>`JULIA` | @chriskoch/julia-wasm@1.0.4 | Julia WASM worker; supports `stdin` and `programArgs` | `runtimeAssets.julia.baseUrl`/`runtimeAssets.julia.workerUrl` or `PUBLIC_WASM_JULIA_BASE_URL`/`PUBLIC_WASM_JULIA_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
112
- | Nim<br>`NIM` | Nim 2.2.4 / benagastov Nim-WASM-Compiler with clang/lld WASM | static worker compiles Nim to C, then clang/lld to WASM; supports `stdin` | `runtimeAssets.nim.baseUrl`/`runtimeAssets.nim.workerUrl` or `PUBLIC_WASM_NIM_BASE_URL`/`PUBLIC_WASM_NIM_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
113
- | Bash<br>`BASH` | @wasm-idle/runtime-bash@0.1.0 / GNU Bash WASIX + static ESM `static/wasm-bash/sdk/index.mjs` produced from @wasmer/sdk@0.9.0 | runs the pinned `bash.webc` locally through the on-demand Wasmer SDK asset; invokes `bash -c <code> <activePath> ...programArgs` and supports `stdin`, `programArgs`, `activePath`, and `workspaceFiles` | `runtimeAssets.bash.moduleUrl`/`workerUrl`/`webcUrl` or `rootUrl`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
114
- | ClojureScript<br>`CLOJURESCRIPT` | @wasm-idle/runtime-clojurescript@0.1.0 / ClojureScript 1.12.134 | static worker compiles and evaluates with the official `cljs.js` self-hosted compiler; supports `stdin`, `programArgs`, `activePath`, and `workspaceFiles` | `runtimeAssets.clojurescript.baseUrl`/`runtimeAssets.clojurescript.workerUrl` or `PUBLIC_WASM_CLOJURESCRIPT_BASE_URL`/`PUBLIC_WASM_CLOJURESCRIPT_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
115
- | TinyGo<br>`TINYGO` | wasm-tinygo@0.0.0 / TinyGo 0.40.1 browser toolchain | default target `wasm`; selectable `wasm`, `wasip1`, `wasip2`, `wasip3`; supports `stdin` and `programArgs` | `runtimeAssets.tinygo.moduleUrl`/`appUrl`/`assetLoader`/`assetPacks`; `PUBLIC_WASM_TINYGO_*`, `tinygoTarget`, `programArgs` |
116
- | OCaml<br>`OCAML` | wasm-of-js-of-ocaml@0.1.0 / js_of_ocaml + wasm_of_ocaml | default backend `wasm`; selectable `wasm`, `js`; `ocamlWasmBinaryenMode` `fast`, `full`; supports `stdin` | `runtimeAssets.ocaml.moduleUrl`/`manifestUrl` or `PUBLIC_WASM_OCAML_*`; `ocamlBackend` |
117
- | JavaScript<br>`JAVASCRIPT` | wasm-typescript@0.1.0 / @swc/wasm-typescript@1.15.33 | TypeScript service transpiles JS/TS and runs in browser sandbox; supports `stdin` and `programArgs` | `runtimeAssets.typescript.moduleUrl`/`libUrl` or `PUBLIC_WASM_TYPESCRIPT_MODULE_URL` |
118
- | TypeScript<br>`TYPESCRIPT` | wasm-typescript@0.1.0 / @swc/wasm-typescript@1.15.33 | TypeScript service transpiles then runs in browser sandbox; supports `stdin` and `programArgs` | `runtimeAssets.typescript.moduleUrl`/`libUrl` or `PUBLIC_WASM_TYPESCRIPT_MODULE_URL` |
119
- | AssemblyScript<br>`ASSEMBLYSCRIPT` | static ESM `static/wasm-assemblyscript/runtime.mjs` produced from assemblyscript@0.28.17 + @assemblyscript/loader@0.28.17 | `asc <activePath> --outFile module.wasm --runtime incremental --bindings raw --optimize --exportRuntime`; runs the emitted WASM through WASI/browser imports and supports `stdin` | `runtimeAssets.assemblyscript.moduleUrl` or `PUBLIC_WASM_ASSEMBLYSCRIPT_MODULE_URL` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles` |
120
- | WAT<br>`WAT` | wasm-wat@0.1.0 / wabt@1.0.39 | WABT parses WAT to WASM then runs through WASI shim; supports `stdin` and `programArgs` | `runtimeAssets.wat.moduleUrl` or `PUBLIC_WASM_WAT_MODULE_URL`; `programArgs` |
121
- | WASM<br>`WASM` | Browser WebAssembly + @bjorn3/browser_wasi_shim@0.4.2 | loads provided WASM bytes and executes with WASI preview1 imports; supports `stdin` and `programArgs` | `programArgs`, `stdin`, `activePath` |
122
- | Lua<br>`LUA` | wasm-lua@0.1.0 / wasmoon@1.16.0 | Wasmoon Lua VM; supports `stdin` and `programArgs` | `runtimeAssets.lua.moduleUrl` or `PUBLIC_WASM_LUA_MODULE_URL`; `programArgs` |
123
- | Zig<br>`ZIG` | static wasm-zig assets / `zig_small.wasm` + `std.tar.gz` | native gzip delivery for the tar standard library; default target `wasm64-wasi`; Zig compile args are appended; supports `stdin`, `compileArgs`, `programArgs` | `runtimeAssets.zig.compilerUrl`/`stdlibUrl` or `PUBLIC_WASM_ZIG_*`; `zigTargetTriple`, `activePath`, `workspaceFiles` |
124
- | Scheme<br>`LISP` | wasm-lisp@0.1.0 / Puppy Scheme WASM component | Puppy Scheme compiler/runtime; supports `stdin` and `programArgs` | `runtimeAssets.lisp.moduleUrl` or `PUBLIC_WASM_LISP_MODULE_URL`; `programArgs` |
125
- | Ruby<br>`RUBY` | static ESM `static/wasm-ruby/runtime.mjs` produced from @ruby/3.4-wasm-wasi@2.9.3-2.9.4 + @ruby/wasm-wasi@2.9.3-2.9.4 | CRuby 3.4 WASI runtime loads `ruby+stdlib.wasm` on demand; supports `stdin`, `programArgs`, and workspace files | `runtimeAssets.ruby.moduleUrl`/`wasmUrl` or `PUBLIC_WASM_RUBY_MODULE_URL`/`PUBLIC_WASM_RUBY_WASM_URL` or `rootUrl`; `stdin`, `programArgs`, `workspaceFiles` |
126
- | Haskell<br>`HASKELL` | ghc-in-browser / GHC 9.14.0.20251031 WASI rootfs | loads `dyld.mjs`, `rootfs.tar.zst`, `bsdtar.wasm`; `compileArgs` become GHC args, otherwise legacy `args` become GHC args | `runtimeAssets.haskell.moduleUrl`/`rootfsUrl`/`bsdtarUrl`; `mainSoPath`, `searchDirs`, `activePath`, `workspaceFiles` |
127
- | Fortran<br>`FORTRAN` | Netlib f2c 2022-09-09 + `@cowasm/f2c 1.0.0` libf2c + @wasm-idle/llvm-core@1.0.0-next.0 | runs `f2c.wasm` in WASI, compiles generated C with the llvm-core Clang host, links `libf2c.a`, then executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.fortran.baseUrl`/`f2cWasmUrl`/`libf2cUrl`/`f2cHeaderUrl`/`analyzerUrl` or `PUBLIC_WASM_FORTRAN_*`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
128
- | COBOL<br>`COBOL` | GnuCOBOL 3.2 + GMP 6.3.0 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.0-next.0 | native gzip delivery for the frontend Wasm and filesystem tar assets; translates free-format COBOL with the real GnuCOBOL `cobc` frontend, compiles the generated C with the llvm-core Clang host, links libcob/GMP, and executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.cobol.baseUrl` or `PUBLIC_WASM_COBOL_BASE_URL`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
129
- | R<br>`R` | versioned static `static/webr/<hash>/webr.js` / webr@0.6.0 | loads the browser ESM entry `webr.js` and its WebR runtime files from the configured static asset tree on demand; supports `stdin`, `programArgs`, and workspace files | `runtimeAssets.r.baseUrl` or `PUBLIC_WASM_R_BASE_URL`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
130
- | Octave<br>`OCTAVE` | Octave 10.3.0 (octave-10.3.0-pl5321h996e327_3.tar.bz2) | Octave CLI Emscripten worker; supports `stdin` and `programArgs` | `runtimeAssets.octave.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_OCTAVE_*` |
131
- | DuckDB<br>`DUCKDB` | static ESM `static/wasm-duckdb/runtime.mjs` produced from @duckdb/duckdb-wasm@1.33.1-dev45.0 | selects the best DuckDB-Wasm MVP/EH bundle on demand and creates a fresh in-memory database per run; `stdin` is registered as `stdin.txt` and `/dev/stdin` rather than terminal stdin | `runtimeAssets.duckdb.moduleUrl` or `PUBLIC_WASM_DUCKDB_MODULE_URL` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles` |
132
- | SQLite<br>`SQLITE` | static ESM `static/wasm-sqlite/runtime.mjs` produced from sql.js@1.14.1 | sql.js loads `sql-wasm.wasm` on demand and executes SQL in a fresh in-memory database; terminal stdin is not applicable | `runtimeAssets.sqlite.moduleUrl`/`wasmUrl` or `PUBLIC_WASM_SQLITE_MODULE_URL`/`PUBLIC_WASM_SQLITE_WASM_URL` or `rootUrl`; `workspaceFiles` |
133
- | PHP<br>`PHP` | static ESM `static/wasm-php/runtime.mjs` prebuilt by the standalone `producers/wasm-php` producer from @php-wasm/web-8-4@3.1.34 + @php-wasm/universal@3.1.34 | fixed PHP `8.4` php-wasm runtime; injects `$argv`/`$argc` and runs the active workspace script with `php.run`; supports `stdin` and `programArgs`; there is no runtime version selector | `runtimeAssets.php.moduleUrl` or `PUBLIC_WASM_PHP_MODULE_URL` or `rootUrl`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
221
+ | Language / IDs | Package/version base | Execution defaults / flags | Customization |
222
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
223
+ | C3<br>`C3` | wasm-llvm/c3-browser: C3 0.8.3 / LLVM 22.1.8 | Verified c3c and builtin LLD compile real C3 in a fresh browser Worker; UTF-8 env.readByte/env.writeByte ABI and exported main; std::io and WASI unavailable | `runtimeAssets.c3.baseUrl`, `stdin`, `activePath`, `workspaceFiles`; fixed compiler flags and bounded Wasm memories |
224
+ | C<br>`C` | @wasm-idle/llvm-core@1.0.0 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang` for `wasm32-wasi`; default `-std=gnu11`; LLDB mode compiles untouched source with embedded DWARF at `-g -O0` and runs it in WAMR; normal runs still use the browser WASI host; supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cVersion`, `activePath`, `workspaceFiles`, `debugMode`, `breakpoints`, `pauseOnEntry` |
225
+ | C++<br>`CPP` | @wasm-idle/llvm-core@1.0.0 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang++` for `wasm32-wasi`; default `-std=gnu++20`; LLDB mode compiles untouched source with embedded DWARF at `-g -O0` and runs it in WAMR; normal runs still use the browser WASI host; supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cppVersion`, `activePath`, `workspaceFiles`, `debugMode`, `breakpoints`, `pauseOnEntry` |
226
+ | Objective-C<br>`OBJC` | GNUstep libobjc2 v2.3 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.0 | `clang -x objective-c -fobjc-runtime=gnustep-2.0 -fblocks` for `wasm32-wasi`; links `libobjc.a`, `libgnustep-base.a`, and `libffi.a` when Foundation is imported; Foundation headers are inlined from `foundation-headers.json`; includes a constructor wrapper for Objective-C class registration; auto-compiles `.m`/`.mm`/`.c` workspace files; trace debug instruments active source and uses wasm-idle controls; supports `stdin` and `programArgs`; large Objective-C assets may be served as gzip-only `.gz` files through the service worker or worker fallback | `runtimeAssets.objectivec.baseUrl`/`libobjcUrl`/`headersUrl`/`libgnustepBaseUrl`/`libgnustepBaseObjectUrl`/`foundationHeadersUrl`/`libffiUrl` or `PUBLIC_WASM_OBJECTIVEC_*`; `runtimeAssets.clang.baseUrl`/`loader` for the clang toolchain; `activePath`, `workspaceFiles`, `compileArgs`, `debug`, `breakpoints`, `pauseOnEntry` |
227
+ | Python<br>`PYTHON3` | static ESM `static/pyodide/pyodide.mjs` / pyodide@0.29.3 | loads `pyodide.mjs`, `pyodide.asm.js`, `pyodide.asm.wasm`, and `python_stdlib.zip` from the configured static asset tree on demand; supports `stdin`, workspace files, and trace debugging | `runtimeAssets.python.baseUrl`/`loader` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles`, `debug`, `breakpoints`, `pauseOnEntry`, `debugPath` |
228
+ | Java<br>`JAVA` | @wasm-idle/runtime-teavm@0.0.0 / TeaVM compiler assets | `compiler.wasm` compiles Java to browser WASM/JS; supports `stdin` and `programArgs` | `runtimeAssets.java.baseUrl`/`loader` or `rootUrl` |
229
+ | Rust<br>`RUST` | wasm-rust@0.1.0 / rust-1.99.0-browser-integrated-v1 + integrated LLVM/LLD 22.1.8 from the `wasm-llvm` producer; exact rustc/LLVM provenance is recorded for LLDB compatibility | browser host `wasm32-wasip1-threads`; default target `wasm32-wasip1`, selectable `wasm32-wasip1`, `wasm32-wasip2`, `wasm32-wasip3`; LLDB mode is currently limited to `wasm32-wasip1` and emits embedded DWARF with `-C debuginfo=2 -C opt-level=0`; normal Preview 1/2/3 execution remains unchanged; supports `stdin` and `programArgs` | `runtimeAssets.rust.compilerUrl`, `runtimeAssets.rust.debugModuleUrl`, or `PUBLIC_WASM_RUST_COMPILER_URL`; `rootUrl`, `rustTargetTriple`, `programArgs`, `debugMode`; compiler requests accept `edition`, `crateType`, `extendedTimeout`, `log`, and `onProgress`; runtime manifest controls compiler memory, timeout, and shared workspace size |
230
+ | Go<br>`GO` | wasm-go@0.1.0 / go1.26.1 | default target `wasip1/wasm`; selectable `wasip1/wasm`, `wasip2/wasm`, `wasip3/wasm`, `js/wasm`; supports `stdin` and `programArgs` | `runtimeAssets.go.compilerUrl` or `PUBLIC_WASM_GO_COMPILER_URL`; `goTarget`, `programArgs` |
231
+ | D<br>`D` | wasm-d@0.1.0 / ldc-1.42.0-wasi-smoke | `ldc2 -conf=/toolchain/etc/ldc2.conf -mtriple=wasm32-wasi -c` then `wasm-ld` to WASI preview1; supports `stdin` and `programArgs` | `runtimeAssets.d.moduleUrl` or `PUBLIC_WASM_D_MODULE_URL`; `activePath`, `programArgs` |
232
+ | C#<br>`CSHARP` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / Roslyn C# 4.14.0 | `CSharpCompilationOptions(OutputKind.ConsoleApplication)`; `concurrentBuild=false`; target `browser-wasm`; language-specific AOT bundle `runtime/csharp/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
233
+ | F#<br>`FSHARP` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / FCS 43.12.204 / FSharp.Core 10.1.204 | `fsc.exe --target:exe --targetprofile:netcore --noframework --simpleresolution --nowin32manifest --debug- --optimize-`; language-specific AOT bundle `runtime/fsharp/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
234
+ | VB.NET<br>`VBNET` | wasm-dotnet@0.1.0 / .NET 9.0.16 browser-wasm / Roslyn Visual Basic 4.14.0 | `VisualBasicCompilationOptions(OutputKind.ConsoleApplication)`; `concurrentBuild=false`, `OptionStrict=Off`, `OptionInfer=On`, `OptionExplicit=On`; target `browser-wasm`; language-specific AOT bundle `runtime/vbnet/`; supports `stdin` and `programArgs` | `runtimeAssets.dotnet.moduleUrl` or `PUBLIC_WASM_DOTNET_MODULE_URL`; `programArgs`, LSP on/off |
235
+ | Elixir<br>`ELIXIR` | wasm-elixir asset bundle / @swmansion/popcorn@0.2.2 | Popcorn/AtomVM bundle `bundle.avm`; supports `stdin` | `runtimeAssets.elixir.bundleUrl` or `PUBLIC_WASM_ELIXIR_BUNDLE_URL` |
236
+ | Erlang<br>`ERLANG` | wasm-elixir asset bundle / @swmansion/popcorn@0.2.2 | Popcorn/AtomVM bundle `bundle.avm`; supports `stdin` | `runtimeAssets.erlang.bundleUrl` or `PUBLIC_WASM_ERLANG_BUNDLE_URL`; falls back to Elixir bundle URL |
237
+ | Prolog<br>`PROLOG` | swipl-wasm@8.0.1 synced into `static/wasm-prolog` | static worker runs SWI-Prolog; supports `stdin` and `programArgs` | `runtimeAssets.prolog.baseUrl`/`runtimeAssets.prolog.workerUrl` or `PUBLIC_WASM_PROLOG_BASE_URL`/`PUBLIC_WASM_PROLOG_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
238
+ | Gleam<br>`GLEAM` | @live-codes/gleam-precompiled@0.5.0 static worker | Gleam worker compiles/runs browser output with source manifest; supports `stdin` | `runtimeAssets.gleam.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_GLEAM_*`; `programArgs`, `workspaceFiles` |
239
+ | Perl<br>`PERL` | WebPerl v0.09-beta (webperl_prebuilt_v0.09-beta.zip) | host-verifies the manifest, stored assets, logical hashes, and profile-bound one-shot runner before executing `emperl`; supports `stdin` and `programArgs` | explicit `runtimeAssets.perl.baseUrl`/`workerUrl`/`manifestUrl` overrides require one complete profile-and-runner receipt bundle; URL-only `PUBLIC_WASM_PERL_*` overrides fail closed; `programArgs`, `activePath`, `workspaceFiles` |
240
+ | Tcl<br>`TCL` | Wacl Tcl 2017-05-29 (wacl.zip) | host-verifies the manifest, stored assets, logical hashes, and profile-bound one-shot runner before executing Wacl Tcl; supports `stdin` and `programArgs` | bundled mirrors may set `runtimeAssets.tcl.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_TCL_BASE_URL`/`PUBLIC_WASM_TCL_WORKER_URL`; custom executable bytes require one complete profile-and-runner receipt bundle; `programArgs`, `activePath`, `workspaceFiles` |
241
+ | AWK<br>`AWK` | GoAWK v1.31.0 / go1.25.3 | static worker runs `goawk.wasm`; supports `stdin` and `programArgs` | `runtimeAssets.awk.baseUrl`/`runtimeAssets.awk.workerUrl` or `PUBLIC_WASM_AWK_BASE_URL`/`PUBLIC_WASM_AWK_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
242
+ | Pascal<br>`PASCAL` | pas2js 3.2.1 (9ac46614dc82) | static worker compiles with pas2js then runs JS; supports `stdin` | `runtimeAssets.pascal.baseUrl`/`runtimeAssets.pascal.workerUrl` or `PUBLIC_WASM_PASCAL_BASE_URL`/`PUBLIC_WASM_PASCAL_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
243
+ | Forth<br>`FORTH` | waforth@0.20.1 / static worker | WAForth worker; supports `stdin` and `programArgs` | `runtimeAssets.forth.baseUrl`/`runtimeAssets.forth.workerUrl` or `PUBLIC_WASM_FORTH_BASE_URL`/`PUBLIC_WASM_FORTH_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
244
+ | J<br>`J` | jsoftware-j-playground static worker | J playground worker; supports `stdin` and `programArgs` | `runtimeAssets.j.baseUrl`/`runtimeAssets.j.workerUrl` or `PUBLIC_WASM_J_BASE_URL`/`PUBLIC_WASM_J_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
245
+ | BQN<br>`BQN` | CBQN static worker / Emscripten 3.1.8 | CBQN worker; supports `stdin` and `programArgs` | `runtimeAssets.bqn.baseUrl`/`runtimeAssets.bqn.workerUrl` or `PUBLIC_WASM_BQN_BASE_URL`/`PUBLIC_WASM_BQN_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
246
+ | Janet<br>`JANET` | Janet 1.41.3-dev / Emscripten 3.1.8 opaque vendored bundle | host-verifies the manifest, stored assets, logical hashes, and profile-bound one-shot runner before executing the Janet VM; supports `stdin` and `programArgs` | explicit `runtimeAssets.janet.baseUrl`/`workerUrl`/`manifestUrl` overrides require one complete profile-and-runner receipt bundle; URL-only `PUBLIC_WASM_JANET_*` overrides fail closed; `programArgs`, `activePath`, `workspaceFiles` |
247
+ | Julia<br>`JULIA` | @chriskoch/julia-wasm@1.0.4 | host-verifies the manifest, stored assets, logical hashes, and profile-bound one-shot runner before executing the legacy Julia VM; supports `stdin` and `activePath` | explicit `runtimeAssets.julia.baseUrl`/`workerUrl`/`manifestUrl` overrides require one complete profile-and-runner receipt bundle; URL-only `PUBLIC_WASM_JULIA_*` overrides fail closed; `activePath` |
248
+ | Nim<br>`NIM` | Nim 2.2.4 / benagastov Nim-WASM-Compiler with clang/lld WASM | host-verifies the manifest, eight stored assets, logical hashes, and profile-bound one-shot runner before compiling Nim to C and linking with clang/lld WASM in a disposable worker; supports `stdin`, `programArgs`, and `activePath` | explicit `runtimeAssets.nim.baseUrl`/`workerUrl`/`manifestUrl` overrides require one complete profile-and-runner receipt bundle; URL-only `PUBLIC_WASM_NIM_*` overrides fail closed; `programArgs`, `activePath` |
249
+ | Bash<br>`BASH` | @wasm-idle/runtime-bash@0.1.0 / GNU Bash WASIX + receipt-pinned @wasmer/sdk@0.9.0 profile | host-verifies one profile manifest, the stored SDK JavaScript, Wasmer Wasm, and WEBc before starting a fixed worker generation with no runtime-asset fetches; invokes `bash -c <code> <activePath> ...programArgs` and supports `stdin`, `programArgs`, `activePath`, and `workspaceFiles` | `rootUrl` mirrors reuse the bundled profile; explicit `runtimeAssets.bash.baseUrl`/`manifestUrl`/`moduleUrl`/`wasmerWasmUrl`/`webcUrl` overrides require one complete profile; `workerUrl` is rejected; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
250
+ | ClojureScript<br>`CLOJURESCRIPT` | @wasm-idle/runtime-clojurescript@0.1.0 / ClojureScript 1.12.134 | static worker compiles and evaluates with the official `cljs.js` self-hosted compiler; supports `stdin`, `programArgs`, `activePath`, and `workspaceFiles` | `runtimeAssets.clojurescript.baseUrl`/`runtimeAssets.clojurescript.workerUrl` or `PUBLIC_WASM_CLOJURESCRIPT_BASE_URL`/`PUBLIC_WASM_CLOJURESCRIPT_WORKER_URL`; `programArgs`, `activePath`, `workspaceFiles` |
251
+ | TinyGo<br>`TINYGO` | wasm-tinygo@0.0.0 / upstream TinyGo 0.40.1 browser toolchain | receipt-verifies and runs upstream `cmd/go` plus TinyGo in a disposable capped Worker; targets `wasip1`; supports `stdin`, `programArgs`, `workspaceFiles`, hosted C++ without exceptions/RTTI, and offline `vendor/modules.txt` | `runtimeAssets.tinygo.moduleUrl`/`assetLoader`; `PUBLIC_WASM_TINYGO_MODULE_URL`, execution/workspace resource limits, `programArgs` |
252
+ | OCaml<br>`OCAML` | wasm-of-js-of-ocaml@0.1.0 / js_of_ocaml + wasm_of_ocaml | default backend `wasm`; selectable `wasm`, `js`; `ocamlWasmBinaryenMode` `fast`, `full`; supports `stdin`; outer module and manifest are size/SHA-256 verified before use | `runtimeAssets.ocaml.moduleUrl`/`manifestUrl` plus `moduleReceipt`/`manifestReceipt` for a custom generation, or `PUBLIC_WASM_OCAML_*` for a mirror of the bundled generation; `ocamlBackend` |
253
+ | JavaScript<br>`JAVASCRIPT` | wasm-typescript@0.1.0 / @swc/wasm-typescript@1.15.33 | TypeScript service transpiles JS/TS and runs in browser sandbox; supports `stdin` and `programArgs` | `runtimeAssets.typescript.moduleUrl`/`libUrl` or `PUBLIC_WASM_TYPESCRIPT_MODULE_URL` |
254
+ | TypeScript<br>`TYPESCRIPT` | wasm-typescript@0.1.0 / @swc/wasm-typescript@1.15.33 | TypeScript service transpiles then runs in browser sandbox; supports `stdin` and `programArgs` | `runtimeAssets.typescript.moduleUrl`/`libUrl` or `PUBLIC_WASM_TYPESCRIPT_MODULE_URL` |
255
+ | AssemblyScript<br>`ASSEMBLYSCRIPT` | static ESM `static/wasm-assemblyscript/runtime.mjs` produced from assemblyscript@0.28.17 + @assemblyscript/loader@0.28.17 | `asc <activePath> --outFile module.wasm --runtime incremental --bindings raw --optimize --exportRuntime`; runs the emitted WASM through WASI/browser imports and supports `stdin` | `runtimeAssets.assemblyscript.moduleUrl` or `PUBLIC_WASM_ASSEMBLYSCRIPT_MODULE_URL` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles` |
256
+ | WAT<br>`WAT` | wasm-wat@0.1.0 / wabt@1.0.39 | WABT parses WAT to WASM then runs through WASI shim; supports `stdin` and `programArgs` | `runtimeAssets.wat.moduleUrl` or `PUBLIC_WASM_WAT_MODULE_URL`; `programArgs` |
257
+ | WASM<br>`WASM` | Browser WebAssembly + @bjorn3/browser_wasi_shim@0.4.2 | loads provided WASM bytes and executes with WASI preview1 imports; supports `stdin` and `programArgs` | `programArgs`, `stdin`, `activePath` |
258
+ | Lua<br>`LUA` | wasm-lua@0.1.0 / wasmoon@1.16.0 | Wasmoon Lua VM; supports `stdin` and `programArgs` | `runtimeAssets.lua.moduleUrl` or `PUBLIC_WASM_LUA_MODULE_URL`; `programArgs` |
259
+ | Zig<br>`ZIG` | static wasm-zig assets / `zig_small.wasm` + `std.tar.gz` | native gzip delivery for the tar standard library; default target `wasm64-wasi`; Zig compile args are appended; supports `stdin`, `compileArgs`, `programArgs` | `runtimeAssets.zig.compilerUrl`/`stdlibUrl` or `PUBLIC_WASM_ZIG_*`; `zigTargetTriple`, `activePath`, `workspaceFiles` |
260
+ | Scheme<br>`LISP` | wasm-lisp@0.1.0 / Puppy Scheme WASM component | receipt-verified Puppy Scheme compiler/runtime; supports `stdin` and `programArgs` | `runtimeAssets.lisp.{moduleUrl,manifestUrl,manifestFingerprint}` or `PUBLIC_WASM_LISP_{MODULE_URL,MANIFEST_URL,MANIFEST_FINGERPRINT}`; `programArgs` |
261
+ | Ruby<br>`RUBY` | receipt-pinned `static/wasm-ruby` profile produced from @ruby/3.4-wasm-wasi@2.9.3-2.9.4 + @ruby/wasm-wasi@2.9.3-2.9.4 | host-verifies the manifest, canonical stored module and gzip bytes, and logical WASM before transferring three owned buffers to a no-fetch CRuby 3.4 worker; supports `stdin`, `programArgs`, and workspace files | `rootUrl` mirrors reuse the bundled profile; explicit `runtimeAssets.ruby` overrides require one complete profile and same-origin canonical paths; URL-only `PUBLIC_WASM_RUBY_*` overrides fail closed; `stdin`, `programArgs`, `workspaceFiles` |
262
+ | Haskell<br>`HASKELL` | ghc-in-browser / GHC 9.14.0.20251031 WASI rootfs | loads `dyld.mjs`, `rootfs.tar.zst`, `bsdtar.wasm`; `compileArgs` become GHC args, otherwise legacy `args` become GHC args | `runtimeAssets.haskell.moduleUrl`/`rootfsUrl`/`bsdtarUrl`; `mainSoPath`, `searchDirs`, `activePath`, `workspaceFiles` |
263
+ | LFortran<br>`LFORTRAN` | receipt-pinned `wasm-llvm/producer/lfortran-browser` artifacts in `static/wasm-lfortran` | real LFortran 0.65.0-97-gab867a23 LLVM evaluator compiles and executes Emscripten side modules in a fresh Worker; shared-ring stdin supports delayed READ and EOF; experimental Fortran feature coverage | `runtimeAssets.lfortran.baseUrl` relocates the reviewed bundle; `stdin`, `activePath`, workspace data/include files, cancellation and execution limits; no program arguments or multi-file module build orchestration |
264
+ | Fortran<br>`FORTRAN` | Netlib f2c 2022-09-09 + `@cowasm/f2c 1.0.0` libf2c + @wasm-idle/llvm-core@1.0.0 | runs `f2c.wasm` in WASI, compiles generated C with the llvm-core Clang host, links `libf2c.a`, then executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.fortran.baseUrl`/`f2cWasmUrl`/`libf2cUrl`/`f2cHeaderUrl`/`analyzerUrl` or `PUBLIC_WASM_FORTRAN_*`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
265
+ | COBOL<br>`COBOL` | GnuCOBOL 3.2 + GMP 6.3.0 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.0 | native gzip delivery for the frontend Wasm and filesystem tar assets; translates free-format COBOL with the real GnuCOBOL `cobc` frontend, compiles the generated C with the llvm-core Clang host, links libcob/GMP, and executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.cobol.baseUrl` or `PUBLIC_WASM_COBOL_BASE_URL`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
266
+ | R<br>`R` | versioned static `static/webr/<hash>/webr.js` / webr@0.6.0 | loads the browser ESM entry `webr.js` and its WebR runtime files from the configured static asset tree on demand; supports `stdin`, `programArgs`, and workspace files | `runtimeAssets.r.baseUrl` or `PUBLIC_WASM_R_BASE_URL`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
267
+ | Octave<br>`OCTAVE` | Octave 10.3.0 (octave-10.3.0-pl5321h996e327_3.tar.bz2) | Octave CLI Emscripten worker; supports `stdin` and `programArgs` | `runtimeAssets.octave.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_OCTAVE_*` |
268
+ | DuckDB<br>`DUCKDB` | static ESM `static/wasm-duckdb/runtime.mjs` produced from @duckdb/duckdb-wasm@1.33.1-dev45.0 | selects the best DuckDB-Wasm MVP/EH bundle on demand and creates a fresh in-memory database per run; `stdin` is registered as `stdin.txt` and `/dev/stdin` rather than terminal stdin | `runtimeAssets.duckdb.moduleUrl` or `PUBLIC_WASM_DUCKDB_MODULE_URL` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles` |
269
+ | SQLite<br>`SQLITE` | static ESM `static/wasm-sqlite/runtime.mjs` produced from sql.js@1.14.1 | sql.js loads `sql-wasm.wasm` on demand and executes SQL in a fresh in-memory database; terminal stdin is not applicable | `runtimeAssets.sqlite.moduleUrl`/`wasmUrl` or `PUBLIC_WASM_SQLITE_MODULE_URL`/`PUBLIC_WASM_SQLITE_WASM_URL` or `rootUrl`; `workspaceFiles` |
270
+ | PHP<br>`PHP` | static ESM `static/wasm-php/runtime.mjs` prebuilt by the standalone `producers/wasm-php` producer from @php-wasm/web-8-4@3.1.34 + @php-wasm/universal@3.1.34 | fixed PHP `8.4` php-wasm runtime; injects `$argv`/`$argc` and runs the active workspace script with `php.run`; supports `stdin` and `programArgs`; there is no runtime version selector | `runtimeAssets.php.moduleUrl` or `PUBLIC_WASM_PHP_MODULE_URL` or `rootUrl`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
134
271
 
135
272
  ### Blocked candidates
136
273
 
@@ -138,11 +275,12 @@ These languages are intentionally not part of the execution support matrix yet.
138
275
  out of `supportedLanguages` until the blocker is resolved with a real browser runtime/compiler and
139
276
  stdin/stdout coverage.
140
277
 
141
- | Candidate | Candidate IDs | Current evidence | Blocker | Required follow-up |
142
- | -------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143
- | Modern Fortran | `F90`, `F95` | `FORTRAN` now runs through f2c/libf2c, while `static/wasm-fortran` still packages LFortran analyzer assets | LFortran WASM/WAT stdin codegen still aborts and the C backend reports `visit_FileRead() not implemented`; f2c covers Fortran 77-style code but is not a full modern Fortran compiler | Package a real browser modern Fortran compiler/runtime with stdin-capable codegen before advertising F90/F95 as first-class runtimes |
144
- | Crystal | `CRYSTAL` | No browser Crystal compiler/runtime assets are packaged in this repository | Crystal cannot be treated as syntax-only or as a wasm-idle-authored translator/subset | Find or build a browser-hosted real Crystal compiler/runtime path with stdin/stdout coverage before registering the language |
145
- | Swift | `SWIFT` | Swift.org documents Wasm support through a native Swift 6.x toolchain plus a Wasm SDK, and SwiftWasm Pad uses a backend compile service; no browser-hosted swiftc/SwiftPM runtime asset is packaged here | Swift cannot be implemented as a wasm-idle-authored parser/runtime subset or as a remote compile service; the playground needs a redistributable browser-hosted real Swift compiler path | Build or source a browser-hosted Swift compiler/SwiftPM runtime bundle, prove stdin/stdout execution for generated WASI modules, then register SWIFT as a first-class runtime |
278
+ | Candidate | Candidate IDs | Current evidence | Blocker | Required follow-up |
279
+ | -------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
280
+ | Odin | `ODIN` | [Pinned native WASI baseline](https://github.com/seo-rii/wasm-llvm/pull/2) compiles real multi-file Odin and passes stdin, EOF and nonzero-exit cases; the consumer target probe exercises the production WASM Worker | The compiler-host Emscripten probe fails in upstream gb.h on unsupported OS/CPU definitions and missing sys/sendfile.h; no browser-hosted Odin compiler exists in the bundle | [Complete the compiler host port and consumer acceptance](docs/language-ports/odin.md) before registering ODIN; native target execution does not enable source compilation |
281
+ | Modern Fortran | `F90`, `F95` | `FORTRAN` now runs through f2c/libf2c, while `static/wasm-fortran` still packages LFortran analyzer assets | LFortran WASM/WAT stdin codegen still aborts and the C backend reports `visit_FileRead() not implemented`; f2c covers Fortran 77-style code but is not a full modern Fortran compiler | Package a real browser modern Fortran compiler/runtime with stdin-capable codegen before advertising F90/F95 as first-class runtimes |
282
+ | Crystal | `CRYSTAL` | [Pinned Crystal 1.21.0 producer](https://github.com/seo-rii/wasm-llvm/pull/3) emits a real WASI object; the consumer probe links that target with verified WASI libc and exercises standard input and EOF in the production WASM Worker | Cross-compiling the compiler fails at Crystal::System::Process.prepare_args in the upstream WASI process implementation; no browser-hosted Crystal compiler bundle is available | [Implement the compiler host and consumer source-execution contract](docs/language-ports/crystal.md) before registering CRYSTAL; a native object or linked target does not establish browser compilation |
283
+ | Swift | `SWIFT` | Native Swift 6.3.3 and the full Wasm SDK produce a target that passes Chromium stdin/UTF-8/EOF checks through the production WASM worker with explicit and shared-buffer input; browser-hosted swiftc/SwiftPM assets remain unavailable | Target execution evidence does not supply a browser-hosted real Swift compiler or SwiftPM; SWIFT remains unregistered | Produce a browser-hosted Swift compiler/SwiftPM bundle and pass source compilation, diagnostics, arguments, and workspace contracts before registering SWIFT |
146
284
 
147
285
  ## Monorepo layout
148
286
 
@@ -158,7 +296,7 @@ toolchains can be consumed from pinned external runtime repositories:
158
296
  an explicit HTTP(S) URL.
159
297
  - `packages/lsp`: code-only browser language-server hosts. TypeScript libraries, SQL engines,
160
298
  clangd, and other language-tool assets are supplied through explicit runtime URLs.
161
- - `wasm-llvm`: external producer repository for compiler source pins, patches, reproducible builds,
299
+ - [`seo-rii/wasm-llvm`](https://github.com/seo-rii/wasm-llvm): external producer repository for compiler source pins, patches, reproducible builds,
162
300
  manifests, and asset verification. Its `producer/rust-browser` source build owns the current Rust
163
301
  1.99 compiler, matching LLVM 22 code generator, and in-process LLD; it is not consumed as an npm
164
302
  runtime package.
@@ -169,10 +307,13 @@ toolchains can be consumed from pinned external runtime repositories:
169
307
  - `packages/vue`: Vue composables around `@wasm-idle/core`.
170
308
  - `packages/node`: Node.js host helpers for Node-capable sandbox loaders.
171
309
  - `runtimes/*`: imported runtime/compiler packages such as `wasm-rust`,
172
- `wasm-of-js-of-ocaml`, `wasm-go`, `wasm-tinygo`, `wasm-dotnet`, `wasm-typescript`,
310
+ `wasm-of-js-of-ocaml`, `wasm-go`, `wasm-dotnet`, `wasm-typescript`,
173
311
  `wasm-wat`, `wasm-lua`, `wasm-lisp`, `wasm-elixir`, `wasm-tcl`, `wasm-awk`,
174
312
  `wasm-forth`, `wasm-j`, `wasm-bqn`, `wasm-janet`,
175
313
  `pyodide`, `teavm`, `assemblyscript`, `ruby`, `r`, and `js-sandbox`.
314
+ - `runtimes/wasm-tinygo`: the public `TINYGO` browser compiler consumer plus an explicitly labeled
315
+ legacy AST-to-C development harness. Static releases publish only the receipt-verified upstream
316
+ consumer and its source-pinned toolchain assets.
176
317
  - `producers/wasm-php`: standalone, locked producer for the checked-in PHP 8.4 page asset. It is
177
318
  outside the root workspace and is never published as an npm package.
178
319
  - `static/wasm-zig`, `static/wasm-haskell`, `static/wasm-julia`, and `static/wasm-nim`: bundled browser runtime and
@@ -215,8 +356,9 @@ pnpm run build:static-runtime-modules
215
356
 
216
357
  This producer step writes `runtime.mjs` trees under `static/wasm-assemblyscript/`,
217
358
  `static/wasm-duckdb/`, `static/wasm-ruby/`, and `static/wasm-sqlite/`. It also writes the Wasmer SDK
218
- module, worker, and WASM payload under `static/wasm-bash/sdk/`. The browser loads each module on
219
- demand when its language is selected; these files are deployed page assets, not npm package
359
+ compatibility files and the unified Bash runtime profile under `static/wasm-bash/` through the same
360
+ rollback-capable Bash producer used by `sync:wasm-bash`. The browser consumes only the profile's
361
+ opaque, receipt-pinned storage paths; these files are deployed page assets, not npm package
220
362
  contents.
221
363
 
222
364
  PHP is built independently under `producers/wasm-php`, with its own lockfile and exact
@@ -272,8 +414,10 @@ handwritten wasm-idle subset, but it inherits AtomVM/Popcorn runtime limits and
272
414
  Erlang/OTP ERTS coverage. Some OTP paths that rely on missing NIFs can fail in the current bundle,
273
415
  so the browser starter and stdin coverage use `io:get_line`/`io:format` only.
274
416
 
275
- Julia browser execution uses the `@chriskoch/julia-wasm` Julia 1.0.4 asset bundle under
276
- `static/wasm-julia/`. Refresh the vendored worker/runtime assets with:
417
+ Julia browser execution uses the `@chriskoch/julia-wasm@1.0.4` asset bundle under
418
+ `static/wasm-julia/`. Despite the package and bundled README version, the verified runtime reports
419
+ `VERSION == v"1.3.0-DEV.560"`; wasm-idle therefore labels it as a legacy development runtime.
420
+ Refresh the vendored worker/runtime assets with:
277
421
 
278
422
  ```bash
279
423
  cd wasm-idle
@@ -291,14 +435,28 @@ pnpm run sync:wasm-nim
291
435
 
292
436
  ## Rust browser integration
293
437
 
294
- The demo app bundles the workspace `wasm-rust` browser compiler under `static/wasm-rust/` and points
295
- the example `Terminal` at `/wasm-rust/index.js` by default. Refresh it with:
438
+ The demo app publishes the workspace `wasm-rust` compiler as a receipt-pinned executable graph
439
+ under `static/wasm-rust/`. The example `Terminal` uses `/wasm-rust/index.js` as the graph's logical
440
+ base URL; that logical JavaScript path is never fetched or imported. Verified module bytes are
441
+ served from inert `.js.bin`/`.js.gz.bin` storage and execute only through owned Blob URLs. Refresh
442
+ the receipts for the checked static publication with the command below. Publication removes raw or
443
+ precompressed JavaScript outside the verified graph; the separately scoped debug instrumenter is
444
+ the only explicit raw-JavaScript allowlist.
296
445
 
297
446
  ```bash
298
- pnpm --dir runtimes/wasm-rust build
299
447
  pnpm run sync:wasm-rust
300
448
  ```
301
449
 
450
+ Publishing a newly built producer dist is an explicit operation and succeeds only when both graph
451
+ authorities match `scripts/wasm-rust-assets.lock.json`. It replaces the complete published runtime
452
+ tree, including WASI sysroot/link packs, so first verify that the producer dist contains the exact
453
+ pack generation intended for publication:
454
+
455
+ ```bash
456
+ pnpm --dir runtimes/wasm-rust build
457
+ pnpm run sync:wasm-rust -- runtimes/wasm-rust/dist
458
+ ```
459
+
302
460
  The built-in Rust route supports `wasm32-wasip1`, `wasm32-wasip2`, and `wasm32-wasip3`. The page
303
461
  exposes a target selector when Rust is active, defaults to `wasm32-wasip1`, and persists that choice
304
462
  in local storage. The compiler module, rustc, sysroot, and component tooling remain unloaded until
@@ -306,25 +464,49 @@ Rust is selected; LSP assets remain unloaded until the LSP toggle is enabled.
306
464
 
307
465
  ## TinyGo browser integration
308
466
 
309
- The demo app can also vendor the workspace `wasm-tinygo` browser build under `static/wasm-tinygo/`
310
- and load its `runtime.js` entry directly inside the TinyGo playground sandbox. The example page
311
- uses the bundled browser runtime by default, including on `localhost` during `vite dev` /
312
- `vite preview`. Refresh the
313
- bundled runtime assets after rebuilding the workspace project with:
467
+ `TINYGO` is a public `wasip1` playground language backed by the independent `upstream.js`
468
+ consumer. It never falls back to wasm-idle's older Go AST-to-C porting harness: the static sync
469
+ allowlist excludes `runtime.js`, its runtime chunks, emception, and the legacy compiler payload.
470
+ The legacy code remains in `runtimes/wasm-tinygo` only for local compiler-port development and is
471
+ explicitly classified as `wasm-idle-go-ast-to-c-subset`.
472
+
473
+ The sibling `wasm-llvm/producer/tinygo-browser` producer pins upstream TinyGo 0.40.1, go-llvm,
474
+ TinyGo LLVM 20.1.1, Go 1.24.6, and WASI SDK 33. The public consumer hash-verifies both producer
475
+ receipts, the upstream compiler, reduced TinyGo/Go root, `cmd/go` WASI package-graph provider, and
476
+ raw LLD before compiling. It derives package JSON from the supplied module workspace, validates
477
+ every compiler/link-plan handoff, links with raw LLD, and finalizes with pinned Binaryen 129.
478
+
479
+ Compile protocol v6 covers generated `go:embed` objects, CGo C, hosted libc++/libc++abi C++17
480
+ without exceptions/RTTI/global constructors, preprocessed Clang assembly, exact allowed
481
+ `CXXFLAGS`, and restricted `#cgo LDFLAGS`. Offline external modules require a complete
482
+ `vendor/modules.txt` tree; there is no network module fallback. Package-graph and compile work run
483
+ inside disposable Workers with fail-closed phase deadlines and a capped WebAssembly memory
484
+ declaration. Separate producer and consumer fixtures cover maps, slices, structs, methods,
485
+ interfaces, generics, package initialization, goroutines, channels, stdin, CGo, C++, and assembly.
486
+ Go/Plan 9 assembly is still not loaded by upstream TinyGo 0.40.1 and is documented as an upstream
487
+ limitation rather than emulated by a browser-only subset.
488
+
489
+ Prepare a verified asset directory, build the runtime, and publish the upstream-only static tree
490
+ with:
314
491
 
315
492
  ```bash
316
- pnpm --dir runtimes/wasm-tinygo build
493
+ pnpm --dir runtimes/wasm-tinygo prepare:wasm-llvm-upstream -- \
494
+ --compiler /path/to/tinygo-compiler.wasm \
495
+ --root-archive /path/to/tinygoroot.tar.gz \
496
+ --producer-receipt /path/to/producer-receipt.json \
497
+ --package-graph /path/to/tinygo-package-graph.wasm \
498
+ --package-graph-receipt /path/to/package-graph-provider-receipt.json \
499
+ --lld /path/to/lld.wasm \
500
+ --output-dir public/tools/upstream
501
+ pnpm --dir runtimes/wasm-tinygo build:upstream
317
502
  pnpm run sync:wasm-tinygo
318
503
  ```
319
504
 
320
- TinyGo exposes `wasm`, `wasip1`, `wasip2`, and `wasip3` targets through the example page. The
321
- browser pipeline still lives inside `wasm-tinygo`; `wasm-idle` imports its reusable `runtime.js`
322
- library entry directly, forwards the selected target into the build request, then runs the emitted
323
- artifact with browser WASI so terminal stdin/EOF behavior stays consistent with the other runtimes.
324
- The default bundled browser path loads the vendored TinyGo runtime in `direct` mode, skips the old
325
- bootstrap-only compile step, and runs runnable WASI artifacts locally. The `wasip2` and `wasip3`
326
- entries use the preview target profiles shipped by the bundled `wasm-tinygo` runtime, so they may
327
- produce non-runnable preview artifacts until the matching execution path is available.
505
+ `PUBLIC_WASM_TINYGO_MODULE_URL` or `runtimeAssets.tinygo.moduleUrl` may point at a separately hosted
506
+ `upstream.js`; its sibling chunks and `tools/upstream/` assets must be served from the same relative
507
+ tree. `PUBLIC_WASM_TINYGO_APP_URL` remains a compatibility alias used only to derive that module
508
+ URL. Custom hosts may provide `runtimeAssets.tinygo.assetLoader`, while normal execution and
509
+ workspace limits continue to apply.
328
510
 
329
511
  ## C# / F# / VB.NET / .NET browser integration
330
512
 
@@ -353,35 +535,59 @@ browser UI thread.
353
535
 
354
536
  ## Browser regression commands
355
537
 
356
- Browser-level Rust and TinyGo checks are reproducible from this repo:
538
+ C3 local asset setup, byte I/O ABI, and its 1 GiB default memory budget are documented in
539
+ [C3 browser integration](docs/c3-browser.md).
540
+
541
+ Clean checkouts can prepare the ignored Clang, clangd, and OCaml browser payloads from one
542
+ receipt-verified manifest:
543
+
544
+ ```bash
545
+ pnpm run prepare:test-assets -- clangd
546
+ pnpm run prepare:test-assets -- clang ocaml
547
+ ```
548
+
549
+ `scripts/browser-test-assets.v1.json` pins one existing Git snapshot of the published asset graph
550
+ and every downloaded file's exact size and SHA-256 digest. CI downloads that immutable snapshot
551
+ from GitHub without WAF credentials. Update the snapshot URL and all changed receipts together;
552
+ do not replace a receipt with bytes from a mutable deployment URL. Receipt failures report both
553
+ expected and actual byte counts and SHA-256 digests.
554
+
555
+ OCaml preparation keeps these verified download inputs in a separate receipt-keyed cache,
556
+ compiles the tracked TypeScript browser adapter with the producer's locked compiler, and syncs
557
+ that adapter together with the verified native bundle. The sync derives the final
558
+ `wasmOcamlVersion.ts` profile; downloaded input receipts remain unchanged. This makes adapter
559
+ fixes reproducible in clean CI without rebuilding or publishing the native OCaml toolchain.
560
+ Gzip-only Binaryen inputs are checked against their expanded manifest receipts before sync.
561
+ At runtime, raw gzip packs retain compressed and expanded receipt checks; HTTP-decoded packs
562
+ are bounded and verified against the exact expanded size and SHA-256.
563
+
564
+ The preparer rejects source or target paths outside their configured roots, checks each redirect
565
+ before following it, writes atomically, and reuses only matching files. With no group argument,
566
+ it prepares both the Clang delivery bundle and the complete OCaml browser compiler graph.
567
+ `WASM_IDLE_TEST_ASSET_BASE_URL` can select a compatible mirror with the same receipt-verified bytes.
568
+ For protected local browser tests, provide `WASM_IDLE_TEST_BYPASS_COOKIE` through the environment
569
+ in `dev_bypass_waf=<value>` form; the browser cookie jar scopes it to the test origin. Asset
570
+ downloads forward this optional cookie only to the trusted `https://seorii.page` origin and never
571
+ to GitHub or another mirror. There is no built-in credential fallback.
572
+
573
+ Browser-level Rust checks are reproducible from this repo:
357
574
 
358
575
  ```bash
359
576
  cd wasm-idle
360
577
  pnpm run probe:rust-browser
361
578
  pnpm run test:browser:playwright
362
- pnpm run probe:tinygo-browser
363
- pnpm run test:browser:tinygo
364
579
 
365
580
  WASM_IDLE_BROWSER_URL='http://localhost:5173/absproxy/5173/' \
366
581
  WASM_IDLE_REUSE_LOCAL_PREVIEW=1 \
367
582
  pnpm run probe:rust-browser
368
583
 
369
- WASM_IDLE_BROWSER_URL='http://localhost:5173/absproxy/5173/' \
370
- WASM_IDLE_REUSE_LOCAL_PREVIEW=1 \
371
- pnpm run probe:tinygo-browser
372
-
373
584
  WASM_IDLE_RUN_REAL_BROWSER_RUST=1 \
374
585
  WASM_IDLE_BROWSER_URL='http://localhost:5173/absproxy/5173/' \
375
586
  WASM_IDLE_REUSE_LOCAL_PREVIEW=1 \
376
587
  pnpm exec vitest run src/lib/playground/rust.playwright.test.ts
377
-
378
- WASM_IDLE_RUN_REAL_BROWSER_TINYGO=1 \
379
- WASM_IDLE_BROWSER_URL='http://localhost:5173/absproxy/5173/' \
380
- WASM_IDLE_REUSE_LOCAL_PREVIEW=1 \
381
- pnpm exec vitest run src/lib/playground/tinygo.playwright.test.ts
382
588
  ```
383
589
 
384
- Both runtime probes exercise the real Chromium page path. The default Rust probe now feeds stdin with a
590
+ The runtime probe exercises the real Chromium page path. The default Rust probe now feeds stdin with a
385
591
  single line (`5\n`) and expects the page to finish without sending EOF, which keeps the regression
386
592
  aligned with the default Rust sample and proves that pressing Enter is enough for line-based stdin.
387
593
  Programs that intentionally read stdin until EOF can still be finished with `Ctrl+D` or the toolbar
@@ -389,9 +595,6 @@ Programs that intentionally read stdin until EOF can still be finished with `Ctr
389
595
  The browser helper writes stdin through the page-owned `window.__wasmIdleDebug.writeTerminalInput(...)`
390
596
  hook instead of trying to click xterm's hidden helper textarea, which proved too flaky for repeatable
391
597
  Playwright runs.
392
- The TinyGo probe follows the same pattern. The browser path should load the vendored runtime in
393
- `direct` mode and avoid the old bootstrap compile command altogether.
394
- The TinyGo browser commands currently default to `vite dev`.
395
598
  If Rust ever reports `invalid metadata files for crate core` or `Unsupported archive identifier`,
396
599
  the browser almost always fetched a stale or wrong `wasm-rust` sysroot asset. Hard refresh the page
397
600
  and rebuild then resync `static/wasm-rust/` from `runtimes/wasm-rust/dist/`.
@@ -409,6 +612,13 @@ session; the repo-owned regression target is the local preview path above.
409
612
 
410
613
  ## Runtime expectations
411
614
 
615
+ The BQN, Forth, and Tcl static Workers use a shared stdin ring. Its write counter and EOF/cancel
616
+ flags are separate atomic values: notifying a waiter does not change its expected write counter.
617
+ Their Worker-only waits therefore recheck these flags at least every 100 ms while scheduled, even
618
+ when an EOF/cancel notification arrives just before the wait starts. This is not an input deadline;
619
+ an open, empty stdin remains available for later input. `staticStdinRingWorker.test.ts` forces that
620
+ check-to-wait ordering for both EOF and cancellation without relying on scheduling luck.
621
+
412
622
  `@wasm-idle/terminal` is an optional browser UI package:
413
623
 
414
624
  ```bash
@@ -456,9 +666,11 @@ loaded for compatibility instead of participating in the default runtime path.
456
666
 
457
667
  `@wasm-idle/lsp` keeps its host and provider JS in the package. Heavy compiler/runtime modules are
458
668
  external static assets loaded only after LSP is enabled: Python uses `pyodide/pyodide.mjs`, R uses
459
- the versioned `webr/<hash>/webr.js`, and the AssemblyScript, DuckDB/SQLite SQL, and Ruby providers
460
- reuse their `static/wasm-*/runtime.mjs` trees. Other compiler-backed providers follow the same
461
- external URL model through their language-server asset configuration.
669
+ the versioned `webr/<hash>/webr.js`, and the AssemblyScript and DuckDB/SQLite SQL providers reuse
670
+ their `static/wasm-*/runtime.mjs` trees. Ruby instead requires a complete identity-and-receipt
671
+ profile; the page host verifies its manifest, module, and compressed Wasm before creating the LSP
672
+ worker. Other compiler-backed providers follow the same external URL model through their
673
+ language-server asset configuration.
462
674
 
463
675
  Pure-JavaScript provider engines for TypeScript, GraphQL, WAT, and document languages are optional
464
676
  peers of `@wasm-idle/lsp`, not mandatory production dependencies. The Pages application keeps
@@ -467,17 +679,16 @@ and its language is selected. Vite emits those providers into lazy worker chunks
467
679
  fetched before they are needed. Library consumers using one of those providers must install its
468
680
  optional peer set, while compiler and language-runtime payloads still come only from external URLs.
469
681
 
470
- Rust still supports an external browser compiler module for library consumers. Point
471
- `PUBLIC_WASM_RUST_COMPILER_URL` at a built `wasm-rust` ESM entry such as
472
- `.../wasm-rust/dist/index.js`, or pass `runtimeAssets.rust.compilerUrl` at runtime. Rust source
473
- instrumentation is emitted as the separate `debug-instrumenter.js` static asset and is imported
474
- only for debug executions. Override it with `runtimeAssets.rust.debugModuleUrl`; otherwise
475
- wasm-idle resolves it beside the configured compiler module and preserves the compiler URL version
476
- query.
477
- TinyGo expects a browser-loadable `wasm-tinygo` runtime module. Point
478
- `PUBLIC_WASM_TINYGO_MODULE_URL` at a built entry such as `.../wasm-tinygo/dist/runtime.js`, or
479
- pass `runtimeAssets.tinygo.moduleUrl` at runtime. The older `PUBLIC_WASM_TINYGO_APP_URL` /
480
- `runtimeAssets.tinygo.appUrl` document path is still accepted and normalized to `runtime.js`.
682
+ Rust supports an external mirror of the pinned compiler graph for library consumers. Set
683
+ `PUBLIC_WASM_RUST_COMPILER_URL` or `runtimeAssets.rust.compilerUrl` to the logical `index.js` URL
684
+ with the exact generated runtime-manifest query, and mirror every `.bin` delivery path and receipt
685
+ from `WASM_RUST_EXECUTABLE_GRAPH_PROFILE`. An arbitrary browser-loadable ESM entry or a raw
686
+ `dist/index.js` is rejected. Rust source instrumentation remains a separate static asset.
687
+ TinyGo uses the public receipt-verified `static/wasm-tinygo/upstream.js` compiler by default.
688
+ Override it with `PUBLIC_WASM_TINYGO_MODULE_URL` or `runtimeAssets.tinygo.moduleUrl`; a custom
689
+ `runtimeAssets.tinygo.assetLoader` can serve the module's verified sibling toolchain files. The
690
+ public route supports only `wasip1` and rejects unsupported targets instead of selecting the legacy
691
+ subset.
481
692
  WAT uses the bundled `static/wasm-wat/` WABT browser module by default. Override it with
482
693
  `PUBLIC_WASM_WAT_MODULE_URL`, or pass `runtimeAssets.wat.moduleUrl`.
483
694
  WASM executes binary WebAssembly modules directly through the browser WebAssembly API. The editor
@@ -499,9 +710,13 @@ environment-based version selector. Override only the module location with
499
710
  `PUBLIC_WASM_PHP_MODULE_URL` or `runtimeAssets.php.moduleUrl`. A custom host must serve the entry's
500
711
  sibling chunks and assets with compatible CORS and cross-origin isolation headers; a cross-origin
501
712
  host cannot use wasm-idle's same-origin gzip service worker.
502
- Bash dynamically imports the Wasmer SDK from `static/wasm-bash/sdk/index.mjs`, initializes its
503
- static worker, and then loads `bash.webc`. Override these three URLs with
504
- `runtimeAssets.bash.moduleUrl`, `workerUrl`, and `webcUrl`, or derive all of them from `rootUrl`.
713
+ Bash verifies one unified manifest plus the stored Wasmer SDK JavaScript, Wasmer Wasm, and WEBc
714
+ before it starts the outer worker. The worker imports only the verified SDK bytes and uses a fixed
715
+ application-owned nested bootstrap; SDK, worker, Wasm, WEBc, sentinel, and registry network
716
+ fallbacks are not part of the normal execution path. A `rootUrl` mirror reuses the bundled profile.
717
+ Explicit `runtimeAssets.bash.baseUrl`, `manifestUrl`, `moduleUrl`, `wasmerWasmUrl`, or `webcUrl`
718
+ overrides require a complete matching profile and receipts. Arbitrary `workerUrl` overrides are
719
+ rejected because executable nested-worker substitution is outside the trust contract.
505
720
  Lua uses the bundled `static/wasm-lua/` wasmoon browser module plus its local `glue.wasm`
506
721
  payload by default. Override it with `PUBLIC_WASM_LUA_MODULE_URL`, or pass
507
722
  `runtimeAssets.lua.moduleUrl`.
@@ -510,12 +725,30 @@ standard library by default. Override them with `PUBLIC_WASM_ZIG_COMPILER_URL` a
510
725
  `PUBLIC_WASM_ZIG_STDLIB_URL`, or pass `runtimeAssets.zig.compilerUrl` and
511
726
  `runtimeAssets.zig.stdlibUrl`. The compiler runs under browser WASI, emits a `wasm64-wasi`
512
727
  artifact with the self-hosted backend, and wasm-idle executes that artifact locally in the worker.
513
- Scheme uses the bundled `static/wasm-lisp/` Puppy Scheme compiler module by default. Override it
514
- with `PUBLIC_WASM_LISP_MODULE_URL`, or pass `runtimeAssets.lisp.moduleUrl`.
515
- Ruby dynamically imports `static/wasm-ruby/runtime.mjs`, which exposes CRuby 3.4 and its default
516
- `ruby+stdlib.wasm` URL. Override the module or WASM payload with
517
- `runtimeAssets.ruby.moduleUrl`/`wasmUrl` or `PUBLIC_WASM_RUBY_MODULE_URL`/
518
- `PUBLIC_WASM_RUBY_WASM_URL`.
728
+ Scheme uses the bundled `static/wasm-lisp/` Puppy Scheme compiler profile by default. The execution
729
+ and LSP workers verify its pinned manifest, stored bytes, decompressed size, and logical asset hashes
730
+ before importing code. A custom profile must provide `runtimeAssets.lisp.moduleUrl`, `manifestUrl`,
731
+ and `manifestFingerprint`, or the corresponding `PUBLIC_WASM_LISP_*` variables.
732
+ Tcl uses the bundled `static/wasm-tcl/` Wacl profile by default. The host verifies the manifest and
733
+ all transport receipts, manually decompresses the canonical `.gz.bin` assets with exact output
734
+ limits, and transfers only verified logical bytes to a runner that pins the same manifest
735
+ fingerprint and closes after one run. URL-only overrides may mirror the bundled bytes. Authorizing
736
+ different executable bytes requires all Tcl identity fields, manifest and asset receipts, plus the
737
+ matching `workerReceipt` in the same `runtimeAssets.tcl` object; omitted trust fields never fall back
738
+ to bundled values. The pinned Wacl/RequireJS payload remains trusted executable code: its verified
739
+ bootstrap needs no follow-up asset fetch, but the worker is not a general network sandbox. Hosts
740
+ must serve `.gz.bin` as opaque bytes without `Content-Encoding: gzip`; legacy `.gz` aliases are not
741
+ referenced by the current manifest.
742
+ Ruby uses the receipt-pinned `static/wasm-ruby/` CRuby 3.4 profile. Before creating a worker, the
743
+ page host verifies `runtime-manifest.v2.json`, canonical `runtime.mjs.bin` storage, compressed
744
+ `ruby_stdlib-*.wasm.gz.bin` storage, the decompressed WASM receipt, and the complete provenance
745
+ fingerprint. It then transfers exactly those three verified logical buffers to a persistent worker
746
+ that performs no runtime-asset fetches. A `rootUrl` mirror reuses the bundled profile. Any explicit
747
+ `runtimeAssets.ruby` override must provide one complete identity-and-receipt profile and use its
748
+ same-origin canonical paths with absent or exact receipt query pins. URL-only
749
+ `PUBLIC_WASM_RUBY_*` overrides intentionally fail closed. The producer receipt covers every
750
+ package-owned Vite file but excludes pnpm-generated nested `node_modules/.bin/` launch shims, whose
751
+ installation paths are not reproducible package content.
519
752
  AssemblyScript dynamically imports `static/wasm-assemblyscript/runtime.mjs`, produced from the
520
753
  pinned AssemblyScript compiler and loader. Override it with
521
754
  `PUBLIC_WASM_ASSEMBLYSCRIPT_MODULE_URL` or `runtimeAssets.assemblyscript.moduleUrl`. Compilation
@@ -537,7 +770,7 @@ the Rust worker:
537
770
  - `wasm32-wasip1` runs as preview1 core wasm through `@bjorn3/browser_wasi_shim`
538
771
  - `wasm32-wasip2` runs as a preview2 component through `preview2-shim` plus transpiled `jco` output
539
772
 
540
- The generic `src/lib/clang/app.ts` host remains in place for other runtimes, but Rust now delegates
773
+ C-family compilation remains hosted by `@wasm-idle/llvm-core`, while Rust delegates artifact
541
774
  execution to `wasm-rust` so the selected target and returned artifact format stay aligned.
542
775
 
543
776
  `Terminal` and `playground(...).load(...)` support either the legacy shared `path`/`rootUrl` or per-runtime asset config:
@@ -556,17 +789,9 @@ const runtimeAssets: PlaygroundRuntimeAssets = {
556
789
  php: {
557
790
  moduleUrl: 'https://cdn.example.com/repl/wasm-php/runtime.mjs'
558
791
  },
559
- ruby: {
560
- moduleUrl: 'https://cdn.example.com/repl/wasm-ruby/runtime.mjs'
561
- },
562
792
  sqlite: {
563
793
  moduleUrl: 'https://cdn.example.com/repl/wasm-sqlite/runtime.mjs'
564
794
  },
565
- bash: {
566
- moduleUrl: 'https://cdn.example.com/repl/wasm-bash/sdk/index.mjs',
567
- workerUrl: 'https://cdn.example.com/repl/wasm-bash/sdk/worker.mjs',
568
- webcUrl: 'https://cdn.example.com/repl/wasm-bash/bash.webc'
569
- },
570
795
  python: {
571
796
  loader: async ({ asset }) => ({ url: `https://cdn.example.com/repl/pyodide/${asset}` })
572
797
  },
@@ -583,14 +808,12 @@ const runtimeAssets: PlaygroundRuntimeAssets = {
583
808
  loader: async ({ asset }) => ({ url: `https://cdn.example.com/repl/clangd/${asset}` })
584
809
  },
585
810
  rust: {
586
- compilerUrl: 'https://cdn.example.com/wasm-rust/index.js'
811
+ compilerUrl:
812
+ 'https://cdn.example.com/wasm-rust/index.js?v=<runtime-manifest-sha256>&rustManifestBytes=<runtime-manifest-bytes>&rustManifestSha256=<runtime-manifest-sha256>'
587
813
  },
588
814
  dotnet: {
589
815
  moduleUrl: 'https://cdn.example.com/wasm-dotnet/index.js'
590
816
  },
591
- tinygo: {
592
- moduleUrl: 'https://cdn.example.com/wasm-tinygo/runtime.js'
593
- },
594
817
  wat: {
595
818
  moduleUrl: 'https://cdn.example.com/wasm-wat/index.js'
596
819
  },
@@ -609,14 +832,6 @@ const runtimeAssets: PlaygroundRuntimeAssets = {
609
832
  rootfsUrl: 'https://cdn.example.com/wasm-haskell/rootfs.tar.zst',
610
833
  bsdtarUrl: 'https://cdn.example.com/wasm-haskell/bsdtar.wasm'
611
834
  },
612
- janet: {
613
- baseUrl: 'https://cdn.example.com/wasm-janet/',
614
- workerUrl: 'https://cdn.example.com/wasm-janet/runner-worker.js'
615
- },
616
- julia: {
617
- baseUrl: 'https://cdn.example.com/wasm-julia/',
618
- workerUrl: 'https://cdn.example.com/wasm-julia/runner-worker.js'
619
- },
620
835
  nim: {
621
836
  baseUrl: 'https://cdn.example.com/wasm-nim/',
622
837
  workerUrl: 'https://cdn.example.com/wasm-nim/runner-worker.js'
@@ -629,7 +844,12 @@ file. Mirror its complete sibling asset tree at the same relative paths. Cross-o
629
844
  must provide compatible CORS and COEP/CORP headers and cannot rely on wasm-idle's same-origin gzip
630
845
  service worker.
631
846
 
632
- Python custom loaders receive file names under the Pyodide asset root and can serve both core assets and package files. TeaVM custom loaders receive file names under the TeaVM asset root. Clang custom loaders receive `bin/memfs.wasm.gz`, `bin/clang.wasm.gz`, `bin/lld.wasm.gz`, and `bin/sysroot.tar.gz`; COBOL loaders receive `cobc.wasm.gz`, `rootfs.tar.gz`, and `c-sysroot.tar.gz`. The shared loader pipes these gzip response bodies through native `DecompressionStream`. Legacy external manifests that still reference ZIP assets remain supported through the dynamically loaded `fflate` compatibility path. Zig custom loaders receive `zig_small.wasm` and `std.tar.gz`; an explicitly configured legacy `std.zip` URL remains compatible. Clangd custom loaders receive `clangd.js` and `clangd.wasm.gz`, with the worker decompressing the gzip payload before instantiation. Rust expects a browser-loadable compiler module URL; that module is responsible for serving its own nested runtime assets. C#, F#, and VB.NET expect a browser-loadable `wasm-dotnet` module with its language-specific static .NET `browser-wasm` runtime assets. TinyGo expects a browser-loadable runtime module. The browser runtime now ships a direct-mode execution path that can produce and run the bundled TinyGo WASI artifact locally, alongside `tools/go-probe.wasm` and vendored emception assets. TinyGo also accepts a runtime asset loader + pack bundle in `runtimeAssets.tinygo` when you need to serve runtime assets out of a single compressed archive. Compressed TeaVM runtime assets are no longer unpacked inside the library; provide the final file URL or handle decompression in your own loader.
847
+ Verified static runtimes such as Janet and Julia intentionally omit URL-only examples: a custom
848
+ `baseUrl`, `manifestUrl`, or `workerUrl` must be accompanied by every identity and asset-receipt
849
+ field declared by that runtime's asset config, including the matching `workerReceipt`. Partial
850
+ trust bundles fail closed instead of borrowing receipts from bundled executable bytes.
851
+
852
+ Python custom loaders receive file names under the Pyodide asset root and can serve both core assets and package files. TeaVM custom loaders receive file names under the TeaVM asset root. Clang custom loaders receive `bin/memfs.wasm.gz`, `bin/clang.wasm.gz`, `bin/lld.wasm.gz`, and `bin/sysroot.tar.gz`; COBOL loaders receive `cobc.wasm.gz`, `rootfs.tar.gz`, and `c-sysroot.tar.gz`. The shared loader pipes these gzip response bodies through native `DecompressionStream`. Legacy external manifests that still reference ZIP assets remain supported through the dynamically loaded `fflate` compatibility path. Zig custom loaders receive `zig_small.wasm` and `std.tar.gz`; an explicitly configured legacy `std.zip` URL remains compatible. Clangd custom loaders receive `clangd.js` and `clangd.wasm.gz`, with the worker decompressing the gzip payload before instantiation. Rust expects a logical, profile-pinned graph entry URL whose sibling inert storage exactly matches the generated receipts; it does not import that HTTP entry directly. C#, F#, and VB.NET expect a browser-loadable `wasm-dotnet` module with its language-specific static .NET `browser-wasm` runtime assets. Compressed TeaVM runtime assets are no longer unpacked inside the library; provide the final file URL or handle decompression in your own loader.
633
853
 
634
854
  To reuse the same runtime asset configuration for both `<Terminal>` and direct `playground(...)`
635
855
  access, bind it once:
@@ -641,21 +861,11 @@ import { createPlaygroundBinding } from 'wasm-idle';
641
861
  const wasmIdle = createPlaygroundBinding({
642
862
  rootUrl: 'https://cdn.example.com/repl',
643
863
  rust: {
644
- compilerUrl: 'https://cdn.example.com/wasm-rust/index.js'
864
+ compilerUrl:
865
+ 'https://cdn.example.com/wasm-rust/index.js?v=<runtime-manifest-sha256>&rustManifestBytes=<runtime-manifest-bytes>&rustManifestSha256=<runtime-manifest-sha256>'
645
866
  },
646
867
  dotnet: {
647
868
  moduleUrl: 'https://cdn.example.com/wasm-dotnet/index.js'
648
- },
649
- tinygo: {
650
- moduleUrl: 'https://cdn.example.com/wasm-tinygo/runtime.js',
651
- assetPacks: [
652
- {
653
- index: 'https://cdn.example.com/wasm-tinygo/runtime-pack/runtime-pack.index.json',
654
- asset: 'https://cdn.example.com/wasm-tinygo/runtime-pack/runtime-pack.bin',
655
- fileCount: 12,
656
- totalBytes: 123456
657
- }
658
- ]
659
869
  }
660
870
  });
661
871
 
@@ -669,5 +879,5 @@ await sandbox.load('print("hi")', false);
669
879
 
670
880
  Compiler assets produced by [`wasm-llvm`](https://github.com/seo-rii/wasm-llvm) are deployed to
671
881
  external static hosting and loaded by `@wasm-idle/llvm-core`. Also powered by Pyodide, TeaVM, `wasm-rust`,
672
- `wasm-tinygo`, `wasm-dotnet`, `wasm-of-js-of-ocaml`, `wasm-typescript`, `wasm-lisp`,
882
+ `wasm-dotnet`, `wasm-of-js-of-ocaml`, `wasm-typescript`, `wasm-lisp`,
673
883
  `wasm-wat`, `wasm-lua`, `wasm-zig`, CBQN, Janet, AtomVM/Popcorn, and `ghc-in-browser`.