Stream: git-wasmtime

Topic: wasmtime / issue #7349 Enable building the C API without ...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 24 2023 at 16:45):

alexcrichton opened issue #7349:

Currently Cranelift is a required feature of the C API due to the C API's usage of Func::new{,_unchecked} which require Cranelift to emit some trampolines. This means that in general only Rust gets to benefit from Cranelift-less builds which is not ideal since other embeddings may wish to exclude Cranelift for security or binary size reasons as well. We should figure out how to implement Func::new without requiring cranelift.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 24 2023 at 16:45):

alexcrichton added the wasmtime:c-api label to Issue #7349.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 24 2023 at 16:46):

github-actions[bot] commented on issue #7349:

Subscribe to Label Action

cc @peterhuene

<details>
This issue or pull request has been labeled: "wasmtime:c-api"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (Apr 04 2024 at 01:26):

Milek7 commented on issue #7349:

I have been thinking about this.
wasm->array trampolines could be stored in the compiled module. Currently there's an assumption that when wasm_call is null then the callee is always native. Some flag would need to be added to VMFuncRef to decide whether to pick wasm->native or wasm->array trampoline. Alternatively callee could stay as always native and instead native->array trampolines could be stored in the module, and then using Func::new would chain wasm->native and native->array together.
Though neither approach would solve TypedFunc::call calling into Func::new when no appropriate trampolines are available in the loaded modules. I see only two possible solutions for that, both not particularly desirable: either monomorphizing array call in TypedFunc::call for use when native callee is not available, or universal runtime native->array trampoline hand-written in assembly.

Maybe this case could be just ignored, because TypedFunc is not accessible from C anyway. Another option would be not providing Func::new in the C API when building without JIT and instead provide Func::wrap counterpart, but this has its own problems (currently wrap machinery relies on monomorphized shims, so that would again require hand-written assembly)

What's your opinion on this?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 04 2024 at 15:03):

alexcrichton commented on issue #7349:

Thanks for helping to think about this, it's much appreciated!

Though neither approach would solve TypedFunc::call calling into Func::new when no appropriate trampolines are available in the loaded modules

I agree that this is the main tricky bit. We've tried pretty hard to avoid handwritten assembly (removing it later whenever we've added it at some point) so if possible I'd prefer to avoid that route. When I was last thinking about it I was concluding what you're thinking here too which is to add an array call path to TypedFunc::call for when the native trampoline is null.

Maybe this case could be just ignored, because TypedFunc is not accessible from C anyway

While I think you might be right today this is also sort of tricky. Modules can reexport their imports so it's possible to get your hands on a function defined with TypedFunc::wrap, by, e.g. reexporting a WASI-defined import. It's still difficult to get to TypedFunc::call in the C API but I think it might not be as far away as we might otherwise think. Additionally if even just for the Rust API I think it'd be good to handle this case too.

instead provide Func::wrap counterpart

I'd agree this isn't feasible, I don't know how we'd actually do this in any way other than saying "these are the supported signatures" and you'd be out of luck if your signature wasn't there.


One thing I've wondered in the past as well is whether the dual of array/native calling conventions are actually buying us anything. While I don't think there's any doubt that an array calling convention is slower than native it might be the case that it's not slower enough to really make a difference. For example we could also solve some questions in this issue by posing the question: "what if we removed the native calling convention?". That would make most of these issues go away at the cost of performance at callsites. I'm not sure if the perf hit is really that noticeable, though, outside of microbenchmarks.

view this post on Zulip Wasmtime GitHub notifications bot (May 20 2024 at 19:14):

alexcrichton closed issue #7349:

Currently Cranelift is a required feature of the C API due to the C API's usage of Func::new{,_unchecked} which require Cranelift to emit some trampolines. This means that in general only Rust gets to benefit from Cranelift-less builds which is not ideal since other embeddings may wish to exclude Cranelift for security or binary size reasons as well. We should figure out how to implement Func::new without requiring cranelift.


Last updated: Nov 22 2024 at 17:03 UTC