-
Notifications
You must be signed in to change notification settings - Fork 59
Description
I hope this is the right place for this discussion; I tried finding a forum that would reach the right target audience and this seemed like the best place.
I've been working with Rust/wasm for quite a while. For that I've been using wasm-bindgen
quite heavily (for a not-yet-released project) using a Webpack loader I've authored: https://github.com/dflemstr/rust-native-wasm-loader
One thing I have noticed is that there doesn't seem to be a clear direction regarding how code modules are to be treated between Rust and foreign modules (such as ES6 modules or other wasm modules) on the source level.
Incidentally, it seems to be working similar to C but not consistently. This behavior is quite confusing when interfacing between two languages that both support modules/namespacing (Rust+JS)
Remember, this is the perhaps naive impression of somebody using Rust together with wasm. I'm aware of how the current wasm FFI is closely modeled after the C FFI.
Imagine the following tree
(with the module hierarchy like you would expect):
.
└── src
├── lib.rs
├── reducer
│ └── editor.js
└── util
├── leftpad.js
└── leftpad.rs
What should the semantics be around visibility and scope for these files? This is what my intuition would tell me:
editor.js
should importleftpad.rs
as../util/leftpad.rs
, or import somemyrustlib.wasm
module where the symbol is available asutil::leftpad::xyz
in some fashion.leftpad.rs
should importeditor.js
as../reducer/editor.js
.- (Stretch:) There should be a separate notion of "exported in my Rust crate" and "available to Javascript"
- (Stretch:) It should be possible to mark a symbol as being available only in the
util
module, so thateditor.js
would not see such a symbol defined inleftpad.rs
, butleftpad.js
would be able to.
With that said, here is what current tools are doing:
- Raw
rustc
symbols that areexport "C"
'd are exported in a global shared namespace. wasm-bindgen
will export everything marked with#[wasm_bindgen]
also in a global shared namespace (including more advanced things such as structs/classes etc).wasm-bindgen
will resolve all imports (#[wasm_bindgen(module = "...")]
) relative to the location of the final generated module artifact, wherever that may be.wasm-bindgen
only supports symbols that are both crate-public and exported.- All imports/exports have no notion of encapsulation.
- (Feel free to suggest other items if we want to make a complete list; I just highlighted some examples)
I find this behavior surprising and feel like one could do either of these things:
- Prohibit imports/exports except on the crate top level (
lib.rs
/main.rs
) and resolve them relative to that location. - Properly namespace imports/exports such that they behave as I described above, or in some other intuitive fashion.
Does this sound reasonable? What are everybody's thoughts on this?