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

WASI Library support in wasmer-js 1.0 #284

Closed
h1romas4 opened this issue Dec 13, 2021 · 5 comments
Closed

WASI Library support in wasmer-js 1.0 #284

h1romas4 opened this issue Dec 13, 2021 · 5 comments

Comments

@h1romas4
Copy link

Hello.

In wasmer-js 0.12.0, I was able to use the WASI module as a library (and get an export) in the following process, is there any plan to support it in the 1.0 series?

https://github.com/h1romas4/libymfm.wasm/blob/v0.9.0/examples/web/src/js/wasi_wasmer.js#L41-L73

export async function initWasi() {
    // ...snip...

    // create WASI instance
    wasi = new WASI({
        args: [""],
        env: {},
        bindings: {
            ...WASI.defaultBindings,
            fs: memFs
        }
    });
    // fetch wasm module
    const response = await fetch(new URL('../wasm/libymfm_bg.wasm', import.meta.url));
    const responseArrayBuffer = new Uint8Array(await response.arrayBuffer());
    // compile wasm
    const wasm_bytes = new Uint8Array(responseArrayBuffer).buffer;
    const lowered_wasm = await lowerI64Imports(wasm_bytes);
    let module = await WebAssembly.compile(lowered_wasm);
    // get WASI imports
    let imposts = wasi.getImports(module);
    // merge wasm imports
    //   (import "wasi_snapshot_preview1" "fd_seek" (func $__wasi_fd_seek (type $t25)))
    //   (import "./libymfm_bg.js" "__wbg_new_59cb74e423758ede"...)
    imposts['./libymfm_bg.js'] = await import('../wasm/libymfm_bg');
    const instance = await WebAssembly.instantiate(module, {
        ...imposts
    });
    // start wasi
    wasi.start(instance);
    // init wasi (Isn't this necessary?)
    instance.exports._initialize();

    // return wasm exports(for call setWasmExport())
    return instance.exports;
}

Best regards.

@syrusakbary
Copy link
Member

Hi @h1romas4, what APIs would be useful for your use case? Just being able to access the instance and it's exports?

@h1romas4
Copy link
Author

h1romas4 commented Dec 13, 2021

@syrusakbary Thank you for your responce.

Yes, I would like to have access to the instance and exports.

In my use case, main(_start) is not the only entry point, there are many export functions generated by wasm-bindgen and extern "C".

Within the exported function, there are calls to the WASI API such as println!(Rust) and fopen(C++), and I want to call these functions from JavaScript in my Web Browser.

The specific exports looks like this. (/libymfm_bg.js was generated by wasm-bindgen)

  (import "wasi_snapshot_preview1" "environ_get" (func $__imported_wasi_snapshot_preview1_environ_get (type $t8)))
  (import "wasi_snapshot_preview1" "environ_sizes_get" (func $__imported_wasi_snapshot_preview1_environ_sizes_get (type $t8)))
  (import "wasi_snapshot_preview1" "fd_close" (func $__imported_wasi_snapshot_preview1_fd_close (type $t4)))
  (import "wasi_snapshot_preview1" "fd_fdstat_get" (func $__imported_wasi_snapshot_preview1_fd_fdstat_get (type $t8)))
  (import "wasi_snapshot_preview1" "fd_fdstat_set_flags" (func $__imported_wasi_snapshot_preview1_fd_fdstat_set_flags 
  ...snip...
  (import "./libymfm_bg.js" "__wbg_new_59cb74e423758ede" (func $console_error_panic_hook::Error::new::__wbg_new_59cb74e423758ede::h5e712c4974ccece4 (type $t1)))
  (import "./libymfm_bg.js" "__wbg_stack_558ba5917b466edd" (func $console_error_panic_hook::Error::stack::__wbg_stack_558ba5917b466edd::hb1a9c3d223c10378 (type $t7)))
  (import "./libymfm_bg.js" "__wbg_error_4bb6c2a97407129a" (func $console_error_panic_hook::error::__wbg_error_4bb6c2a97407129a::h3f15166c4de92044 (type $t3)))
  (import "./libymfm_bg.js" "__wbindgen_object_drop_ref" (func $wasm_bindgen::__wbindgen_object_drop_ref::hda0f57decd45dfa0 (type $t3)))
  (import "./libymfm_bg.js" "__wbindgen_throw" (func $wasm_bindgen::__wbindgen_throw::he7308114fccb2084 (type $t7)))
  (import "wasi_snapshot_preview1" "random_get" (func $wasi::lib_generated::wasi_snapshot_preview1::random_get::he91525f4791886e0 (type $t8)))

The actual source code for wasmer-python and wasmer-js examples can be found under the examples directory in the repository below. (A synthesizer made with WebAssembly)

https://github.com/h1romas4/libymfm.wasm

Thank you!

syrusakbary added a commit that referenced this issue Dec 14, 2021
Return the raw instance when instantiating. Fix #284
@syrusakbary
Copy link
Member

This issue should be now solved.
The new version v1.0.2 is now published into NPM and Deno.

@syrusakbary
Copy link
Member

Basically, calling wasi.instantiate(...) will return the inner WebAssembly.Instance, so you can use it as needed

@h1romas4
Copy link
Author

Thank you for your quick response!
I would like to work on migrating to 1.0.

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

No branches or pull requests

2 participants