-
Notifications
You must be signed in to change notification settings - Fork 57
Why are the core module exports completely inaccessible? #75
Comments
if a module uses interface types, the api it wants to expose is not the core exports, so we shouldn't automatically expose them. |
I understand that, and I think that's why the adapted functions are exactly right in |
They're already explicitly marked with |
We explicitly want to avoid exporting things the module author doesn't want public. The use case for the core/interface export distinction is because many adapter functions will want to interact with a module's memory, but a module may not want to allow arbitrary reads+writes to its memory. If we require memory to be exported, that makes it impossible to truly share nothing when linking, because an external module could always do totally unmodeled things to one's state. It should be possible to re-export a core export as a no-op, but only if the module author does so. In my polyfill I model this as forwarding a core export. The reason this is backwards-compatible is because of modeling the core module as wrapped by an external module. In any polyfill, we create a new JS object around the exports that the wasm module generates, and that doesn't need to forward every export. We then don't expose any reference to the original exports object, and it essentially becomes a (older JS style) private variable. Which is exactly what we want for our encapsulation purposes. And it's semantically incorrect to call an interface-having wasm module without either codegen support in the engine, or a polyfill. Calling |
Hm, I do understand the notion behind this. I guess I find it a bit strange that a browser without support for Interface Types (ITs) gets access to something that a browser with support for ITs cannot access. For ITs, I predict a pattern like this will get used: let {instance} = await WebAssembly.instantiate(/*...*/);
if(!hasSupportForInterfaceTypes) {
const {wrap} = await import("./glue.js");
instance = wrap(instance);
}
instance.export.highLevelFunction(); This is something that I think a developer should be able to develop and test without having to download and old version of a browser. WDYT? (Alternatively: What about giving |
I was predicting a pattern more like const { wrapIfNeedBe } = await import("./glue.js");
const { instance } = await wrapIfNeedBe(WebAssembly.instantiate(/*...*/));
instance.export.highLevelFunction(); but it's likely that we'll see both in the wild. Your version defers the glue import, which is beneficial if the browser supports it, so is probably more production-ready and will be more common. I think having an option to pass a flag to |
I am wondering why the explainer currently says that the core module exports are completely inaccessible unless the host doesn't have support for interface types or exports are explicitely re-exported. I can't follow why this restrictive approach is desirable. Can someone fill me in on the reasoning?
I admit that I don't have strong use-cases right now, but I feel like there might be situations where skipping the adapter code could be desirable for performance or monkey-patching purposes.
I'd love to somehow allow developers to access the core module exports if necessary, maybe via something like
instance.coreExports
or similar.(cc @RReverser)
The text was updated successfully, but these errors were encountered: