Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split crate into "standalone" and "JS" components #1841

Open
alexcrichton opened this issue Oct 29, 2019 · 2 comments
Open

Split crate into "standalone" and "JS" components #1841

alexcrichton opened this issue Oct 29, 2019 · 2 comments

Comments

@alexcrichton
Copy link
Contributor

Over time wasm-bindgen has picked up more features to follow the WebAssembly proposals, namely the interface types proposal. Additionally wasm-bindgen has been used for new embeddings such as WASI! One of the major goals of interface types is to also help bring wasm code to many more places outside of the web browser.

Currently for this "outside the web browser" use case wasm-bindgen is acting as Rust's implementation of interface types (to follow the standard), and I think that's likely to continue being the case into the future. Unfortunately though this causes a bit of an impedance mismatch!

  • From the start wasm-bindgen was built for the web and assumes JS. Lots of functionality isn't available in standalone webassembly (almost none of the APIs on JsValue, classes, etc)
  • Currently debug builds, by default, fail for the interface types target because they don't optimize out calls to __wbindgen_throw. There are no intrinsics with a standalone wasm file!
  • Restrictions on the web are not actually restrictions everywhere else. We support u64/i64 on the web by passing two i32 components, but Support for i64/u64 in interface types #1837 points out this is natively supported by all other runtimes.

Overall I think that to continue to faithfully pursue the standalone outside-the-web browser use case we'll want to do something about the current organization. I don't think this should be isolated to just the wasm32-wasi target, but it should include it!

I would expect an organization where you still use #[wasm_bindgen]-the-macro but if you're in a standalone environment you'd have a type like Anyref instead of JsValue. Additionally you would have no access to intrinsics in a standalone environment, unlike the JS environment. I think we'll want to tweak the features available in #[wasm_bindgen] as well, where if you're in a standalone environment we require a module for all imports and don't support any features like js_namespace and such.

I sort of envision this happening by doing something like the following:

  • Spilt out a wasm-bindgen-core crate. This crate defines the Anyref type, uses zero intrinsics, and defines all the basic conversion traits.
  • Add a dependency from wasm-bindgen-core to wasm-bindgen-macro, and reexport it
  • The current wasm-bindgen crate would then depend on wasm-bindgen-core, reexporting most of its functionality and layering JsValue on top of Anyref.
  • Update wasm-bindgen-macro with an off-by-default js feature (or something like that). When enabled this enables all the support for things like js_namespace and such. The wasm-bindgen-core crate would not turn this feature on, but wasm-bindgen would
  • If necessary add a js feature to wasm-bindgen-core which wasm-bindgen would activate, which would tweak impls like the ABI of i64/u64.

The general user experience would then be that if you're using wasm-bindgen today, nothing changes. For standalone use-cases though that do not intend on targeting the web specifically, you'd use the wasm-bindgen-core crate. The wasm-bindgen-core crate would statically ensure that you stay within what interface types are supported. This means no support for fancy types like closures (until they're added to the standard eventually). The hope here is that you can get errors in crate compilation long before you actually run the wasm-bindgen CLI tool.

In any case I'm curious what others think of this strategy? Is wasm-bindgen still an appropriate place for all this? Do others think that this should all be split out somehow? Should we send a PR tomorrow? (etc, etc)

@fitzgen
Copy link
Member

fitzgen commented Oct 29, 2019

Yeah, we've talked about this general kind of thing before in wg meetings and I'm still in favor of it 👍

@Pauan
Copy link
Contributor

Pauan commented Oct 29, 2019

I completely agree, this sounds like a good plan.

I'm okay with reusing wasm-bindgen for this, because the name "wasm bindgen" just means "a tool that generates bindings for wasm", ala the bindgen crate.

I do think it's a little confusing to use the same wasm_bindgen macro for both wasm and JS bindings, but I think it's okay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants