Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS glue: Please provide a way to initialize with an already loaded WebAssembly.Module #2972

Closed
johnspurlock opened this issue Jun 30, 2022 · 7 comments

Comments

@johnspurlock
Copy link

Motivation

Cloudflare Workers has a wacky way of importing wasm modules.

import module from "./hello.wasm";

...is the only allowed way to bring in wasm (in module-based workers). module is then a WebAssembly.Module, not its exports like the upcoming standard proposal.

Currently this means any wasm-bindgen generated JS cannot be initialized properly out of the box. They need to be manually edited with something like a setModule function, which is then picked up and used in instantiateModule.

Once this is done, the wasm lib usually works fine on Cloudflare (modulo some other intentionally missing classes that need to be stubbed like FinalizationRegistry)

Proposed Solution

It would be great if a future version of the JS glue code could accept an WebAssembly.Module already in hand, for environments like this.

Alternatives

Tweaking wasm-bindgen generated JS by hand

Thanks!
- John

@allsey87
Copy link
Contributor

allsey87 commented Jul 1, 2022

Cloudflare Workers has a wacky way of importing wasm modules.

I completely agree that it would be nicer if this just worked out the box, but it sounds like this is more of an issue with Cloudflare rather than wasm-bindgen, right?

@johnspurlock
Copy link
Author

It's a constrained and security-focused runtime, so I suppose it's reasonable for them to prevent fetching wasm and instantiating modules on the fly. Instead, they are essentially uploaded (and checked) at deploy time.

They are, however, provided at runtime as a web-standard WebAssembly.Module, and it would be great if the bindgen script supported using it (in instantiateModule) instead of assuming fetch

@lukaslihotzki
Copy link
Contributor

The glue depends on the target. Which target do you use? With --target web, init with WebAssembly.Module does work fine. If you know how to tweak the output file, just tweak the template code in this repo instead and create a PR, like #3016.

@jkomyno
Copy link

jkomyno commented Jul 6, 2023

Hi @johnspurlock, I believe I have a fix for you in #3510.

@johnspurlock
Copy link
Author

Thanks! As long as I can hand in my WebAssembly.Module to init, that'll be great

@jkomyno
Copy link

jkomyno commented Jul 6, 2023

@johnspurlock With my PR, you'd only need to:

  • run wasm-bindgen --target bundler --workerd
  • import your Wasm bindings in a Cloudflare Worker, like so:
    import { yourFunction } from './wasm/your_crate.js'
    
    // call yourFunction()

@daxpedda
Copy link
Collaborator

daxpedda commented Jul 7, 2023

As pointed out before in #2972 (comment), the web target already supports importing a module without fetching:

if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {{
input = fetch(input);
}}

I've been extensively using Cloudflare Workers lately with the Web target, this has worked well for me:

#[wasm_bindgen]
pub fn fetch() -> Result<Response, JsValue> {
    Response::new_with_opt_str(Some("Hello, World!"))
}
import wasm from './test_bg.wasm'
import init, * as exports from './test.js';

await init(wasm);

export default exports;

So I believe this has already been solved by #1384.
Please leave a comment if I'm wrong about this!

@daxpedda daxpedda closed this as completed Jul 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants