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

thirdparty .wasm usage from C #616

Open
1 task done
aviplayer opened this issue Aug 7, 2024 · 5 comments
Open
1 task done

thirdparty .wasm usage from C #616

aviplayer opened this issue Aug 7, 2024 · 5 comments

Comments

@aviplayer
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Description

Are there any ability to use C compiled code?
I noticed nightly build provide an ability to compile/link C code
example: https://github.com/rafaelbeckel/test-c-rust-wasm
discussion: rustwasm/wasm-bindgen#2209
I tried to reuse solutions, but got an exceptions:

Added lib like this: rbg_calculator = { path = "../test-c-rust-wasm/crates/5_rust_bindgen" }

But CloudFlare worker fails:  service core:user:memgraph: Uncaught TypeError: WebAssembly.Instance(): Import #6 "env": module is not an object or function

Final goal is to add this one: https://github.com/memgraph/mgclient
It has an ability to be compiled in wasm:

Building WASM (Linux only)
Compiling mgclient for wasm requires the Emscripten sdk. This is automated in the following steps:
mkdir build && cd build
cmake .. -DWASM=ON

I also tried it, but the same error
Any suggestion on this?

@aviplayer
Copy link
Author

It fails directly there - var B = new WebAssembly.Instance(N, { "./index_bg.js": g });
What does it mean? What is index_bg? I tried to find any files but worker-build doesn't ptoduce any

@spigaz
Copy link
Contributor

spigaz commented Aug 7, 2024

My understanding is that workers-rs just compiles to wasm32-unknown-unknown and that poses some limitations.

But under the hood, the plain wasm file is loaded by the engine and you can use that, to access some additional support that might be present:
https://developers.cloudflare.com/workers/runtime-apis/webassembly/javascript/

And apparently there is a way to get emscripten to work (it seems required by your final goal in wasm)
https://github.com/cloudflare/worker-emscripten-template

@kflansburg
Copy link
Member

It fails directly there - var B = new WebAssembly.Instance(N, { "./index_bg.js": g }); What does it mean? What is index_bg? I tried to find any files but worker-build doesn't ptoduce any

These errors seem to be originating from the JavaScript shim that we auto-generate for you. Can you share a full reproduction repository?

@aviplayer
Copy link
Author

aviplayer commented Aug 9, 2024

Seems C static library was incorrect. Just bindings are not present. I asked on there repository, have no answer. One question: Can I use thirdparty .wasm from Rust on CF? Any suggestion to use from wasm?
I see it is possible to use memgraph from js: https://github.com/memgraph/jsmgclient/tree/main
But are there any standard/easy approach you can recommend? @kflansburg

Tried to load/embed using wasm_bingen, but got an error
``Errvalue: JsValue(CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder
cloudflare/cloudflare-docs#13469

Then if there any way to run thirdparty wasm?

@rafaelbeckel
Copy link

@aviplayer, sorry for my late answer; I was on vacation and didn't see your message.

This issue arises because C symbols are not exported to a dylib unless you wrap them explicitly in Rust. This thread can give you some context: rust-lang/rfcs#2771.

In the case of WASM, all missing symbols are expected to be provided from the env variable in the WASM imports table.

In my example, the memory.js file injects the missing symbols and provides a simple bump allocator from JS for malloc() and free() calls. Check out the build_with_wasm_pack.sh file in my example.

This was my first iteration for a POC and quite a hack-ish approach. In production, I'm using musl-libc (instead of the OpenBSD subset in the calculator) and have malloc() and free() implemented in Rust directly from the tinylibc crate, so we don't have to provide it from the imports table.

I will update the examples later on.

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

4 participants