Skip to content

feat(stdlib): wasmCall extern for invoking WebAssembly exports by name#440

Merged
hyperpolymath merged 2 commits into
mainfrom
feat/wasm-call-extern
May 28, 2026
Merged

feat(stdlib): wasmCall extern for invoking WebAssembly exports by name#440
hyperpolymath merged 2 commits into
mainfrom
feat/wasm-call-extern

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Adds the generic Option A surface from bindings #5: a single extern that lowers to exports[name](...args) on the --deno-esm backend, with Number coercion so i32/i64/f32/f64 returns all coerce to Float at the AffineScript boundary.

This is the smallest-scope / highest-leverage Tier-1 binding item — it unblocks idaptik vm/wasm (740 LoC) and every future WASM-host integration. Typed per-Zig-fn shims can layer on top per-consumer where typing discipline outweighs the generic surface's flexibility.

Surface:

pub extern fn wasmCall(
  exports: WasmExports,
  name: String,
  args: [Float]
) -> Float;

Lowering (lib/codegen_deno.ml):

__as_wasmCall(exports, name, args)
  = Number(exports[name](...(args || [])))

Test fixture tests/codegen-deno/wasm_call.{affine,harness.mjs} exercises the round-trip with a 41-byte hand-built wasm module exporting add(i32, i32) -> i32; all 7 codegen-deno harnesses pass.

Closes #414. Updates docs/bindings-roadmap.adoc row #5 status ◐ → ● and points the rationale at this PR.

Adds the generic Option A surface from bindings #5: a single extern
that lowers to `exports[name](...args)` on the --deno-esm backend,
with Number coercion so i32/i64/f32/f64 returns all coerce to Float
at the AffineScript boundary.

This is the smallest-scope / highest-leverage Tier-1 binding item —
it unblocks idaptik vm/wasm (740 LoC) and every future WASM-host
integration. Typed per-Zig-fn shims can layer on top per-consumer
where typing discipline outweighs the generic surface's flexibility.

Surface:

    pub extern fn wasmCall(
      exports: WasmExports,
      name: String,
      args: [Float]
    ) -> Float;

Lowering (lib/codegen_deno.ml):

    __as_wasmCall(exports, name, args)
      = Number(exports[name](...(args || [])))

Test fixture tests/codegen-deno/wasm_call.{affine,harness.mjs}
exercises the round-trip with a 41-byte hand-built wasm module
exporting add(i32, i32) -> i32; all 7 codegen-deno harnesses pass.

Closes #414. Updates docs/bindings-roadmap.adoc row #5
status ◐ → ● and points the rationale at this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath hyperpolymath marked this pull request as ready for review May 28, 2026 20:39
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 28, 2026 20:45
@hyperpolymath hyperpolymath disabled auto-merge May 28, 2026 20:45
@hyperpolymath hyperpolymath merged commit c8f43c1 into main May 28, 2026
24 of 25 checks passed
@hyperpolymath hyperpolymath deleted the feat/wasm-call-extern branch May 28, 2026 20:45
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 82 issues detected

Severity Count
🔴 Critical 4
🟠 High 10
🟡 Medium 68

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action ons/checkout@v6\n    needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action land/setup-deno@v2\n    needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in affine-vscode-publish.yml",
    "type": "unknown",
    "file": "affine-vscode-publish.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "unknown",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "unknown",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "unknown",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "unknown",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "unknown",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "unknown",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath restored the feat/wasm-call-extern branch May 28, 2026 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bindings #5: WASM-exports calling pattern

1 participant