Open yamt opened 11 months ago
Yes, at least by default.. In the future, we could add a way to opt-in in the component-type level (e.g., you imagine some sort of foo: reentrant func(...)
) that turns off the reentrancy check. But, from experience, this type of coarse-grained reentrance tends to complicate a codebase (see for example: nested event loops in browsers) and often isn't supported anyways, so it seems like a good idea to make this an explicit part of the interface so that the contract is clear to both parties about what to allow/expect.
i'm not sure if a component is an appropriate unit for that kind of checks. does it mean that, combining two components into a single component can trigger the check, right? but i got the intention. thank you.
btw,
Components define a "lockdown" state that prevents continued execution after a trap. This both prevents continued execution with corrupt state and also allows more-aggressive compiler optimizations (e.g., store reordering). This was considered early in Core WebAssembly standardization but rejected due to the lack of clear trapping boundary.
i'm interested in this discussion in Core WebAssembly standardization. can you give me a pointer if it was public? trapping boundary, is it about threads?
does it mean that, combining two components into a single component can trigger the check, right?
Each component's "can be entered" state is tracked independently (as part of the component instance state), so if you link two together, they should basically preserve their independent behavior. If one component simply imports the other, it's not even be possible to cause reentrance; it's only possible when one component instantiates another (via instance
definition) that the parent can be called from a child's import and then attempt to call the child's export (using a function table and call_indirect
to close the loop).
i'm interested in this discussion in Core WebAssembly standardization. can you give me a pointer if it was public? trapping boundary, is it about threads?
This was in some of the very earliest wasm CG discussions, so I'm not sure where it showed up in minutes/issues; I wasn't able to find anything on GitHub from a quick search, but I might've missed it. The basic reasons not to have lockdown semantics at the core wasm level are:
does it mean that, combining two components into a single component can trigger the check, right?
Each component's "can be entered" state is tracked independently (as part of the component instance state), so if you link two together, they should basically preserve their independent behavior. If one component simply imports the other, it's not even be possible to cause reentrance; it's only possible when one component instantiates another (via
instance
definition) that the parent can be called from a child's import and then attempt to call the child's export (using a function table andcall_indirect
to close the loop).
i meant that, if you have a call graph like A->B->C, and you happened to merge A and C into A', it might break.
i'm interested in this discussion in Core WebAssembly standardization. can you give me a pointer if it was public? trapping boundary, is it about threads?
This was in some of the very earliest wasm CG discussions, so I'm not sure where it showed up in minutes/issues; I wasn't able to find anything on GitHub from a quick search, but I might've missed it. The basic reasons not to have lockdown semantics at the core wasm level are:
1. If you trap in module A, what all do you lockdown? the current A instance? what if it imports a memory imported by another instance, should that lockdown too? what if that other instance imports a second memory, should that get locked down too? It's hard to answer these questions b/c the primitives are so low-level. 2. In some hypothetical scenarios, maybe the JS code embedding the core wasm _does_ want to observe the state after the trap (say, to capture a crash-dump). (In the case of the C-M, such a feature would be implemented by the runtime/tooling a "layer down".)
why hasn't it been implemented a "layer down" for core wasm? just for historical reasons?
i meant that, if you have a call graph like A->B->C, and you happened to merge A and C into A', it might break.
Ah, I see thanks. The case of parent-->child-->parent reentrance is explicitly allowed (see uses of "calling_enter" below here).
why hasn't it been implemented a "layer down" for core wasm? just for historical reasons?
Depending on the context, wasm may be the lowest layer (consider an OS where was is the ISA for all guest code). It's hard to rule things out at the core wasm layer.
the explainer says:
does it mean to prevent callback-style api as well?