mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-28 23:22:16 +00:00
* Shard the `convert.rs` module into sub-modules Hopefully this'll make the organization a little nicer over time! * Start adding support for optional types This commit starts adding support for optional types to wasm-bindgen as arguments/return values to functions. The strategy here is to add two new traits, `OptionIntoWasmAbi` and `OptionFromWasmAbi`. These two traits are used as a blanket impl to implement `IntoWasmAbi` and `FromWasmAbi` for `Option<T>`. Some consequences of this design: * It should be possible to ensure `Option<SomeForeignType>` implements to/from wasm traits. This is because the option-based traits can be implemented for foreign types. * A specialized implementation is possible for all types, so there's no need for `Option<T>` to introduce unnecessary overhead. * Two new traits is a bit unforutnate but I can't currently think of an alternative design that works for the above two constraints, although it doesn't mean one doesn't exist! * The error messages for "can't use this type here" is actually halfway decent because it says these new traits need to be implemented, which provides a good place to document and talk about what's going on here! * Nested references like `Option<&T>` can't implement `FromWasmAbi`. This means that you can't define a function in Rust which takes `Option<&str>`. It may be possible to do this one day but it'll likely require more trait trickery than I'm capable of right now. * Add support for optional slices This commit adds support for optional slice types, things like strings and arrays. The null representation of these has a pointer value of 0, which should never happen in normal Rust. Otherwise the various plumbing is done throughout the tooling to enable these types in all locations. * Fix `takeObject` on global sentinels These don't have a reference count as they're always expected to work, so avoid actually dropping a reference on them. * Remove some no longer needed bindings * Add support for optional anyref types This commit adds support for optional imported class types. Each type imported with `#[wasm_bindgen]` automatically implements the relevant traits and now supports `Option<Foo>` in various argument/return positions. * Fix building without the `std` feature * Actually fix the build... * Add support for optional types to WebIDL Closes #502
52 lines
2.6 KiB
Markdown
52 lines
2.6 KiB
Markdown
# Feature Reference
|
|
|
|
Here this section will attempt to be a reference for the various features
|
|
implemented in this project. This is likely not exhaustive but the [tests]
|
|
should also be a great place to look for examples.
|
|
|
|
[tests]: https://github.com/rustwasm/wasm-bindgen/tree/master/tests
|
|
|
|
The `#[wasm_bindgen]` attribute can be attached to functions, structs,
|
|
impls, and foreign modules. Impls can only contain functions, and the attribute
|
|
cannot be attached to functions in an impl block or functions in a foreign
|
|
module. No lifetime parameters or type parameters are allowed on any of these
|
|
types. Foreign modules must have the `"C"` abi (or none listed). Free functions
|
|
with `#[wasm_bindgen]` might not have the `"C"` abi or none listed, and it's also not
|
|
necessary to annotate with the `#[no_mangle]` attribute.
|
|
|
|
All structs referenced through arguments to functions should be defined in the
|
|
macro itself. Arguments allowed implement the `WasmBoundary` trait, and examples
|
|
are:
|
|
|
|
* Integers (u64/i64 require `BigInt` support)
|
|
* Floats
|
|
* Borrowed strings (`&str`)
|
|
* Owned strings (`String`)
|
|
* Exported structs (`Foo`, annotated with `#[wasm_bindgen]`)
|
|
* Exported C-like enums (`Foo`, annotated with `#[wasm_bindgen]`)
|
|
* Imported types in a foreign module annotated with `#[wasm_bindgen]`
|
|
* Borrowed exported structs (`&Foo` or `&mut Bar`)
|
|
* The `JsValue` type and `&JsValue` (not mutable references)
|
|
* Vectors and slices of supported integer types and of the `JsValue` type.
|
|
* Optional vectors/slices
|
|
|
|
All of the above can also be returned except borrowed references. Passing
|
|
`Vec<JsValue>` as an argument to a function is not currently supported. Strings are
|
|
implemented with shim functions to copy data in/out of the Rust heap. That is, a
|
|
string passed to Rust from JS is copied to the Rust heap (using a generated shim
|
|
to malloc some space) and then will be freed appropriately.
|
|
|
|
Owned values are implemented through boxes. When you return a `Foo` it's
|
|
actually turned into `Box<RefCell<Foo>>` under the hood and returned to JS as a
|
|
pointer. The pointer is to have a defined ABI, and the `RefCell` is to ensure
|
|
safety with reentrancy and aliasing in JS. In general you shouldn't see
|
|
`RefCell` panics with normal usage.
|
|
|
|
JS-values-in-Rust are implemented through indexes that index a table generated
|
|
as part of the JS bindings. This table is managed via the ownership specified in
|
|
Rust and through the bindings that we're returning. More information about this
|
|
can be found in the [design doc].
|
|
|
|
All of these constructs currently create relatively straightforward code on the
|
|
JS side of things, mostly having a 1:1 match in Rust with JS.
|