Stream: git-wasmtime

Topic: wasmtime / issue #9600 Allowing reentrance of wasm compon...


view this post on Zulip Wasmtime GitHub notifications bot (Nov 12 2024 at 20:50):

Nimaoth opened issue #9600:

Hi, I'm currently experimenting with wasm components for a plugin system, and one use case I have is being able to do callbacks between components.

So say we have two components A and B, where B imports an exported interface from A, with a function add-callback(...) which is called from component B, and component B exports a function handle-callback(...) which will be call by component A . A doesn't know about the existence of B at compile time (they are dynamically linked).
It would work fine for callbacks which are call later (e.g. by an event in the host).
The problem now is that since reentrant calls aren't allowed, I can't do this for callbacks which are called immediately (like a predicate function for a filter, so e.g. B calls filter in A with a function in B as the predicate, and then A calls the predicate immediately, because the stack trace would contain B->A->B and would reenter B).

So I just tried disabling the reentrance checks in runtime/component/func.rs and it seems to work fine for my tests. The question here is are there any technical reasons for why the reentrance is dissallowed (e.g. memory saftety violation, deadlocks, race conditions), or is it only because the component model defines this?
If there is no hard requirement for it would it then be possible add a feature to allow reentrance for certain components?

view this post on Zulip Wasmtime GitHub notifications bot (Nov 12 2024 at 21:15):

bjorn3 commented on issue #9600:

cc https://github.com/WebAssembly/component-model/issues/234

Reentrance is not allowed by Wasmtime because the spec says so. As for why this is the case, see https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md:

Components prevent unexpected reentrance by setting the "lockdown" state (in the previous bullet) whenever calling out through an import, clearing the lockdown state on return, thereby preventing reentrant export calls in the interim. This establishes a clear contract between separate components that both prevents obscure composition-time bugs and also enables more-efficient non-reentrant runtime glue code (particularly in the middle of the Canonical ABI).

view this post on Zulip Wasmtime GitHub notifications bot (Nov 17 2024 at 06:28):

BERADQ commented on issue #9600:

any progress?

view this post on Zulip Wasmtime GitHub notifications bot (Nov 18 2024 at 17:55):

alexcrichton commented on issue #9600:

@Nimaoth @BERADQ here @bjorn3 is correct in that Wasmtime's current behavior is an implementation of the current component model specification. For changing the behavior here I think it would be best to raise this issue on the component-model repository itself to gather interest among stakeholders there. Wasmtime is unlikely to change behavior in this regard unless there's interest in the specification itself for changing, so inevitably the first step will be to kick off the discussion there.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 22:28):

fitzgen closed issue #9600:

Hi, I'm currently experimenting with wasm components for a plugin system, and one use case I have is being able to do callbacks between components.

So say we have two components A and B, where B imports an exported interface from A, with a function add-callback(...) which is called from component B, and component B exports a function handle-callback(...) which will be call by component A . A doesn't know about the existence of B at compile time (they are dynamically linked).
It would work fine for callbacks which are call later (e.g. by an event in the host).
The problem now is that since reentrant calls aren't allowed, I can't do this for callbacks which are called immediately (like a predicate function for a filter, so e.g. B calls filter in A with a function in B as the predicate, and then A calls the predicate immediately, because the stack trace would contain B->A->B and would reenter B).

So I just tried disabling the reentrance checks in runtime/component/func.rs and it seems to work fine for my tests. The question here is are there any technical reasons for why the reentrance is dissallowed (e.g. memory saftety violation, deadlocks, race conditions), or is it only because the component model defines this?
If there is no hard requirement for it would it then be possible add a feature to allow reentrance for certain components?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 22:28):

fitzgen commented on issue #9600:

Cosing this issue as this is an upstream spec matter. If the spec changes, then we can reopen this issue accordingly.


Last updated: Dec 23 2024 at 12:05 UTC