Commit 03e0d29
feat(stdlib): WasmValue + wasm_export_call typed wasm-exports binding (closes #455)
Tier 1 #5 of the AS bindings top-50 roadmap (#446). Owner's #455-decided
Option B: generic `wasm_export_call(exports, name, args: [WasmValue]) ->
WasmValue` with WasmValue as a tagged scalar carrier covering all four
wasm numeric kinds (i32, i64, f32, f64).
Future-proof: covers any wasm signature including i64, multi-typed args,
future spec additions. No binding change required as wasm evolves. Tiny
addition vs Option A's ~30 per-signature variants. Typed wrappers can
be layered on top of this generic as ergonomic helpers in a follow-up
sub-issue.
## Encoding decision
WasmValue lands as an OPAQUE `pub extern type` rather than a true AS sum
type. Rationale: the JS interop boundary needs a hand-written marshaller
that pairs `wv_i32(42) -> { kind: "i32", v: 42 }` with the export-call
dispatch `__as_wasm_export_call(exports, name, args)`. Mirrors the
existing `WasmExports` opaque pattern in stdlib/Deno.affine. A true
sum-type variant on top of this opaque base ships in a follow-up once
json.affine-style tagged-variant codegen lands for the Deno-ESM backend.
## What this PR ships
- `stdlib/Deno.affine`: +87 lines
* `pub extern type WasmValue`
* `wv_i32` / `wv_i64` / `wv_f32` / `wv_f64` constructors
* `wv_as_int` / `wv_as_float` / `wv_kind` accessors
* `wasm_export_call(exports, name, args: [WasmValue]) -> WasmValue`
* Worked example: `addI32ViaWasm(bytes, a, b)` in the docstring
- `lib/codegen_deno.ml`: +47 lines
* JS prelude: 8 `__as_wv_*` / `__as_wasm_export_call` helpers
* `deno_builtins` dispatch table: 8 entries
* BigInt for i64 (preserves precision beyond 2^53); `Math.fround` for f32
* Return wraps as f64 by default (lossless for any numeric); i64 returns
detected via `typeof result === "bigint"` and wrapped as i64
## What's deferred (per owner's #455 implementation-scope breakdown)
- Zig FFI implementation for the native backend — separate PR
- Idris2 ABI pattern doc (Zig=APIs/FFIs, Idris2=ABIs convention) — separate PR
- `examples/wasm-exports-demo.affine` end-to-end demo — separate PR
- Smoke-test through the Zig FFI — separate PR
Each of these is independently shippable now that the Deno.affine surface
is in place. Will file follow-up tracking issues after this lands.
## Owner-directive compliance
- Adds 8 externs in the WebAssembly section adjacent to existing `wasmCall`.
- Adds 8 codegen dispatch entries in the existing `let () = ...` block.
- Pure additive change; no existing surface modified.
- Owner Option B confirmed in #455 comment 2026-05-30 13:18Z.
## Refs
- closes #455 (Tier 1 #5, scope: Deno.affine + JS codegen)
- #446 — AS bindings top-50 umbrella
- `project_affinescript_bindings_top50_roadmap.md` — memory tracker
- `stdlib/Deno.affine:155-176` — existing `wasmCall` / `wasmInstance`
surface for context
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 4f0f3ca commit 03e0d29
2 files changed
Lines changed: 134 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
174 | 212 | | |
175 | 213 | | |
176 | 214 | | |
| |||
431 | 469 | | |
432 | 470 | | |
433 | 471 | | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
434 | 481 | | |
435 | 482 | | |
436 | 483 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
178 | 265 | | |
179 | 266 | | |
180 | 267 | | |
| |||
0 commit comments