If we pass rayon 0 workers it still spawns 1, so both 1 and 2 threads
were actually spawning one thread each. Let's remove the off-by-one so
1 and 2 cores should show a significant difference.
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 came up during #1760 where `Promise.resolve` must be invoked with
`this` as the `Promise` object, but we were erroneously importing it in
such a way that it didn't have a shim and `this` was `undefined`.
This commit switches away from `xargo` to using `-Zbuild-std` to
building the standard library for the raytrace-parallel example (which
needs to rebuild std with new target features).
The threads transform is implicitly enabled nowadays when the memory
looks like it's shared, so ensure that's taken into account in the
`is_enabled` check.
Turns out that `JSON.stringify(undefined)` doesn't actually return a
string, it returns `undefined`! If we're requested to serialize
`undefined` into JSON instead just interpret it as `null` which should
have the expected semantics of serving as a placeholder for `None`.
Closes#1778
To benefit users in debug mode we log any unexpected exceptions to help
diagnose any issues that might arise. It turns out, though, we log this
for *every* exception happening for *every* import, including imports
like `__wbindgen_throw` which are explicitly intended to throw an
exception. This can cause distracting debug logs to get emitted to the
console, so let's squelch the debug logging for known imports that we
shouldn't log for, such as intrinsics.
Closes#1785
This hasn't ever actually worked in `wasm-bindgen` but there's been
enough refactorings since the initial implementation that it's actually
quite trivial to implement now!
Closes#1777
This tiny crate provides utilities for working with Wasm codegen
conventions (typically established by LLVM or lld) such as getting the shadow
stack pointer.
It also de-duplicates all the places in the codebase where we were implementing
these conventions in one-off ways.
This crate provides a transformation to turn exported functions that use a
return pointer into exported functions that use multi-value.
Consider the following function:
```rust
pub extern "C" fn pair(a: u32, b: u32) -> [u32; 2] {
[a, b]
}
```
LLVM will by default compile this down into the following Wasm:
```wasm
(func $pair (param i32 i32 i32)
local.get 0
local.get 2
i32.store offset=4
local.get 0
local.get 1
i32.store)
```
What's happening here is that the function is not directly returning the
pair at all, but instead the first `i32` parameter is a pointer to some
scratch space, and the return value is written into the scratch space. LLVM
does this because it doesn't yet have support for multi-value Wasm, and so
it only knows how to return a single value at a time.
Ideally, with multi-value, what we would like instead is this:
```wasm
(func $pair (param i32 i32) (result i32 i32)
local.get 0
local.get 1)
```
However, that's not what this transformation does at the moment. This
transformation is a little simpler than mutating existing functions to
produce a multi-value result, instead it introduces new functions that wrap
the original function and translate the return pointer to multi-value
results in this wrapper function.
With our running example, we end up with this:
```wasm
;; The original function.
(func $pair (param i32 i32 i32)
local.get 0
local.get 2
i32.store offset=4
local.get 0
local.get 1
i32.store)
(func $pairWrapper (param i32 i32) (result i32 i32)
;; Our return pointer that points to the scratch space we are allocating
;; on the shadow stack for calling `$pair`.
(local i32)
;; Allocate space on the shadow stack for the result.
global.get $shadowStackPointer
i32.const 8
i32.sub
local.tee 2
global.set $shadowStackPointer
;; Call `$pair` with our allocated shadow stack space for its results.
local.get 2
local.get 0
local.get 1
call $pair
;; Copy the return values from the shadow stack to the wasm stack.
local.get 2
i32.load
local.get 2 offset=4
i32.load
;; Finally, restore the shadow stack pointer.
local.get 2
i32.const 8
i32.add
global.set $shadowStackPointer)
```
This `$pairWrapper` function is what we actually end up exporting instead of
`$pair`.
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 defaults all crates in-tree to use `std::future` by default
and none of them support the crates.io `futures` 0.1 crate any more.
This is a breaking change for `wasm-bindgen-futures` and
`wasm-bindgen-test` so they've both received a major version bump to
reflect the new defaults. Historical versions of these crates should
continue to work if necessary, but they won't receive any more
maintenance after this is merged.
The movement here liberally uses `async`/`await` to remove the need for
using any combinators on the `Future` trait. As a result many of the
crates now rely on a much more recent version of the compiler,
especially to run tests.
The `wasm-bindgen-futures` crate was updated to remove all of its
futures-related dependencies and purely use `std::future`, hopefully
improving its compatibility by not having any version compat
considerations over time. The implementations of the executors here are
relatively simple and only delve slightly into the `RawWaker` business
since there are no other stable APIs in `std::task` for wrapping these.
This commit also adds support for:
#[wasm_bindgen_test]
async fn foo() {
// ...
}
where previously you needed to pass `(async)` now that's inferred
because it's an `async fn`.
Closes#1558Closes#1695
This needed and update now that we're explicitly importing `*.wasm` to
import `*.js` instead. Additionally this was moved over to the `web`
target to avoid needing Webpack
Closes#1743