The `JsValue` type wraps a slab/heap of js objects which is managed by
the wasm-bindgen shim, and everything here is not actually able to cross
any thread boundaries. When wasm actually has threads, for example, each
thread will have to have its own slab of objects generated by
wasm-bindgen, and indices in one slab aren't valid in any other slabs.
This is technically a breaking change because `JsValue` was previously
`Send` and `Sync`, but I'm hoping that in practice this isn't actually a
breaking change because nothing in wasm can be using threads which in
theory shouldn't activate the `Send` and/or `Sync` bounds.
Adding `#[inline]` will typically improve codegen for optimized builds
without LTO (so far the majority in practice) by allowing functions that
otherwise couldn't be inlined across codegen units to get inlined
across codegen units.
Right now `wasm-bindgen` has a lot of functions that are very small and
delegate to other functions, but aren't otherwise candidates for
inlining because they're concrete.
I was poking around in release-mode wasm recently and noticed an
alarming number of functions for tiny pieces of functionality, which
motivates this patch!
This commit improves the codegen for `Closure<T>`, primarily for ZST
where the closure doesn't actually capture anything. Previously
`wasm-bindgen` would unconditionally allocate an `Rc` for a fat pointer,
meaning that it would always hit the allocator even when the `Box<T>`
didn't actually contain an allocation. Now the reference count for the
closure is stored on the JS object rather than in Rust.
Some more advanced tests were added along the way to ensure that
functionality didn't regress, and otherwise the calling convention for
`Closure` changed a good deal but should still be the same user-facing.
The primary change was that the reference count reaching zero may cause
JS to need to run the destructor. It simply returns this information in
`Drop for Closure` and otherwise when calling it now also retains a
function pointer that runs the destructor.
Closes#874
Previously the `link_mem_intrinsics` hack actually had a runtime
overhead by storing a value into a global location, but it turns out we
can actually use a non-inlined function call as part of the *descriptor*
which requires this to be in the final binary, but we'll end up snip'ing
the value at the end.
All in all this should mean that it's not a zero-overhead solution for
linking these intrinsics! The `#[wasm_bindgen]` attribute already has
other problems if the descriptors don't show up, so that's the least of
our issues!
This commit implements support for binding APIs that take
`Uint8ClampedArray` in JS. This is pretty rare but comes up in a
`web-sys` binding or two, and we're now able to bind these APIs instead
of having to omit the bindings.
The `Uint8ClampedArray` type is bound by using the `Clamped` marker
struct in Rust. For example this is declaring a JS API that takes
`Uint8ClampedArray`:
use wasm_bindgen::Clamped;
#[wasm_bindgen]
extern {
fn takes_clamped(a: Clamped<&[u8]>);
}
The `Clamped` type currently only works when wrapping the `&[u8]`, `&mut
[u8]`, and `Vec<u8>` types. Everything else will produce an error at
`wasm-bindgen` time.
Closes#421
This commit adds support for exporting a function defined in Rust that returns a
`Result`, translating the `Ok` variant to the actual return value and the `Err`
variant to an exception that's thrown in JS.
The support for return types and descriptors was rejiggered a bit to be a bit
more abstract and more well suited for this purpose. We no longer distinguish
between functions with a return value and those without a return value.
Additionally a new trait, `ReturnWasmAbi`, is used for converting return values.
This trait is an internal implementation detail, however, and shouldn't surface
itself to users much (if at all).
Closes#841
This commit adds support for the WebIDL `Callback` type by translating all
callbacks to the `js_sys::Function` type. This will enable passing raw JS values
into callbacks as well as Rust valus using the `Closure` type.
This commit doesn't currently implement "callback interfaces" in WebIDL, that's
left for a follow-up commit.
This commit adds an implementation of `AsRef<JsValue>` for the `Closure<T>`
type. Previously this was not possible because the `JsValue` didn't actually
exist until the closure was passed to JS, but the implementation has been
changed to ... something a bit more unconventional. The end result, however, is
that `Closure<T>` now always contains a `JsValue`.
The end result of this work is intended to be a precursor to binding callbacks
in `web-sys` as `JsValue` everywhere but still allowing usage with `Closure<T>`.
In addition to closing #495 this'll be useful eventually when instantiating
multiple wasm modules from Rust as you'd now be able to acquire a reference to
the current module in Rust itself.
I discussed this with @fitzgen awhile back and this sort of casting seems
especially problematic when you have code along the lines of:
let mut x: HtmlElement = ...;
{
let y: &mut JsValue = x.as_ref();
*y = 3.into();
}
x.some_html_element_method();
as that will immediately throw! We didn't have a use case for mutable casting
other than consistency, so this commit removes it for now. We can possibly add
it back in later if motivated, but for now it seems reasonable to try to avoid
these sorts of pitfalls!
This is a pretty heavyweight dependency which accounts for a surprising amount
of runtime for larger modules in `wasm-bindgen`. We don't need 90% of the crate
and so this commit bundles a small interpreter for instructions we know are only
going to appear in describe-related functions.
This commit adds support for generating bindings for dictionaries defined in
WebIDL. Dictionaries are associative arrays which are simply objects in JS with
named keys and some values. In Rust given a dictionary like:
dictionary Foo {
long field;
};
we'll generate a struct like:
pub struct Foo {
obj: js_sys::Object,
}
impl Foo {
pub fn new() -> Foo { /* make a blank object */ }
pub fn field(&mut self, val: i32) -> &mut Self {
// set the field using `js_sys::Reflect`
}
}
// plus a bunch of AsRef, From, and wasm abi impls
At the same time this adds support for partial dictionaries and dictionary
inheritance. All dictionary fields are optional by default and hence only have
builder-style setters, but dictionaries can also have required fields. Required
fields are exposed as arguments to the `new` constructor.
Closes#241
* Tweak the implementation of heap closures
This commit updates the implementation of the `Closure` type to internally store
an `Rc` and be suitable for dropping a `Closure` during the execution of the
closure. This is currently needed for promises but may be generally useful as
well!
* Support asynchronous tests
This commit adds support for executing tests asynchronously. This is modeled
by tests returning a `Future` instead of simply executing inline, and is
signified with `#[wasm_bindgen_test(async)]`.
Support for this is added through a new `wasm-bindgen-futures` crate which is a
binding between the `futures` crate and JS `Promise` objects.
Lots more details can be found in the details of the commit, but one of the end
results is that the `web-sys` tests are now entirely contained in the same test
suite and don't need `npm install` to be run to execute them!
* Review tweaks
* Add some bindings for `Function.call` to `js_sys`
Name them `call0`, `call1`, `call2`, ... for the number of arguments being
passed.
* Use oneshots channels with `JsFuture`
It did indeed clean up the implementation!
* Bump to 0.2.12
* Update all version numbers and deps
* Update all listed authors to `["The wasm-bindgen Developers"]`
* Update `repository` links to specific paths for each crate
* Update `homepage` links to the online book
* Update all links away from `alexcrichton/wasm-bindgen`
* Add `#[doc]` directives for HTML URLs
* Update more version requirements
* Fill out CHANGELOG
* 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
* Move the `js` module to a `js_sys` crate
* Update js-sys tests to pass again
* Update binding_to_unimplemented_apis_doesnt_break_everything
Remove its dependency on the `js` module
* Update metadata for js-sys
* Fix the `closures` example