This PR contains a few major improvements:
* Code duplication has been removed.
* Everything has been refactored so that the implementation is much easier to understand.
* `future_to_promise` is now implemented with `spawn_local` rather than the other way around (this means `spawn_local` is faster since it doesn't need to create an unneeded `Promise`).
* Both the single threaded and multi threaded executors have been rewritten from scratch:
* They only create 1-2 allocations in Rust per Task, and all of the allocations happen when the Task is created.
* The singlethreaded executor creates 1 Promise per tick, rather than 1 Promise per tick per Task.
* Both executors do *not* create `Closure`s during polling, instead all needed `Closure`s are created ahead of time.
* Both executors now have correct behavior with regard to spurious wakeups and waking up during the call to `poll`.
* Both executors cache the `Waker` so it doesn't need to be recreated all the time.
I believe both executors are now optimal in terms of both Rust and JS performance.
This commit adds support to attach `#[wasm_bindgen]` on an `async fn`
which will change the return value into a `Promise` in JS. This in
theory has the exact same semantics as an `async` function in JS where
you call it with all the arguments, nothing happens and you get a
promise back, and then later the promise actually resolves.
This commit also adds a helper trait, `IntoJsResult`, to allow `async`
functions with multiple kinds of return values instead of requiring
everything to be `Result<JsValue, JsValue>`.
This commit tweaks the codegen for imported functions and such (anything
that relies on some imported intrinsic or function filled in by the CLI)
to share as much code as possible on non-wasm32 platforms. This should
help us catch more errors before compiling to wasm and also just make it
easier to write UI tests!
For example a UI test previously couldn't be written for #1528 but now
it can be, and one is include (although the error message is quite bad).
Most of the CLI crates were already in the 2018 edition, and it turns
out that one of the macro crates was already in the 2018 edition so we
may as well move everything to the 2018 edition!
Always nice to remove those `extern crate` statements nowadays!
This commit also does a `cargo fmt --all` to make sure we're conforming
with style again.
This commit is an implementation of [RFC 6] which enables crates to
inline local JS snippets into the final output artifact of
`wasm-bindgen`. This is accompanied with a few minor breaking changes
which are intended to be relatively minor in practice:
* The `module` attribute disallows paths starting with `./` and `../`.
It requires paths starting with `/` to actually exist on the filesystem.
* The `--browser` flag no longer emits bundler-compatible code, but
rather emits an ES module that can be natively loaded into a browser.
Otherwise be sure to check out [the RFC][RFC 6] for more details, and
otherwise this should implement at least the MVP version of the RFC!
Notably at this time JS snippets with `--nodejs` or `--no-modules` are
not supported and will unconditionally generate an error.
[RFC 6]: https://github.com/rustwasm/rfcs/pull/6Closes#1311
Reported in #1191 the fix requires us to get a bit creative I think. The
general gist is that a block like this:
#[wasm_bindgen]
impl Foo {
pub fn foo() {}
}
was previously expanded all in one go. Now, however, it's expanded into:
impl Foo {
#[__wasm_bindgen_class_marker(Foo = "Foo")]
pub fn foo() {}
}
// goop generated by orginal #[wasm_bindgen]
This method of expansion takes advantage of rustc's recursive expansion
feature. It also allows us to expand `impl` blocks and allow inner items
to not be fully expanded yet, such as still having `#[cfg]` attributes
(like in the original bug report).
We use theinternal `__wasm_bindgen_class_marker` to indicate that we're
parsing an `ImplItemMethod` unconditionally, and then generation
proceeds as usual. The only final catch is that when we're expanding in
an `impl` block we have to generate tokens for the `Program`
(wasm-bindgen injected goop like the custom section) inside the body
of the function itself instead of next to it. Otherwise we'd get syntax
errors inside of impl blocks!
Closes#1191