Skip to content

AOT: instantiate .wasm ES module imports (import * as wasm from './x.wasm') and expose its exports #5234

Closed

Description

@proggeramlug

Context: real apps import compiled WebAssembly as ESM modules (wasm-bindgen "bundler"/"web" target). e.g. opencode pulls @silvia-odwyer/photon-node, whose photon_rs_bg.js does import * as wasm from "./photon_rs_bg.wasm" and calls wasm.someExport(...). The import is expected to yield the instantiated module's named exports.

Goal

Support import * as wasm from "./x.wasm" (and named/default forms) by instantiating the WebAssembly module at module-init and exposing its exports as the module's named exports, wired to the importing JS glue's imports object (wasm-bindgen creates a circular glue↔wasm import relationship). perry already has a runtime WASM host — crates/perry-runtime/src/webassembly.rs (WebAssembly.instantiate(bytes) works via perry_wasm_host_*) — to build on.

Self-contained repro

Minimal module exporting add(i32,i32)->i32. Create add.wasm from this base64, then main.ts:

echo 'AGFzbQEAAAABBwFgAn9/AX8DAgEABwcBA2FkZAAACgkBBwAgACABags=' | base64 -d > add.wasm
// main.ts
import * as wasm from "./add.wasm";
console.log(wasm.add(2, 3));   // expected: 5

Node (with a wasm-ESM loader) and bundlers print 5. perry today fails earlier — see # (it currently can't even read the .wasm); after deferral it would throw-on-use. This issue is the real integration that makes wasm.add(2,3) return 5.

Scope notes

  • Instantiation at module-init; named exports surfaced (functions, and memory/global/table as appropriate).
  • The wasm imports object: for a bare .wasm with no imports (like the repro) it's empty; for wasm-bindgen, the glue provides imports — handle the circular case (glue imports wasm exports; wasm imports glue functions).
  • Companion to the cheaper deferral (#), which keeps the build moving until this lands.

Activity

  1. proggeramlug commented on Aug 17, 2026

    @proggeramlug
    ContributorAuthor

    I verified this still reproduces on current main and found no assignee, active branch/worktree, or PR implementing it. I am working on a fix now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew capability or improvement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions