In addition to being more ergonomic these are much more efficient at reading
large files as they preallocate internally. This provides a nice speed boost
locally, reducing the overhead of `wasm-bindgen-test-runner` from 0.23s to
0.19s, yay!
This commit updates the test runner to only deserialize a `Module` once and then
directly pass it to the `wasm-bindgen` config, avoiding pulling in a public
dependency with the same strategy as the `wasm-gc-api` crate for now.
This reduces the runtime of this step for `wasm-bindgen-test-runner` from ~0.23s
to ~0.19s on my machine.
Since `wasmi` already has a public dependency on `parity_wasm` let's just use
it! A `clone` is much faster than a serialize + parse, reducing a `wasm-bindgen`
invocation on my machine from 0.2s to 0.18s.
Currently the `wasm-gc-api` crate doesn't expose `parity_wasm::Module` as a
public dependency which means that whenever we want to run a GC (which is twice
per `wasm-bindgen` invocation) we have to serialize and reparse the module a
lot! The `wasm-bindgen` has to serialize, `wasm-gc` then parses, `wasm-gc` then
serializes, and `wasm-bindgen` then parses.
This commit sidesteps all of these operations by ensuring that we always use the
same `parity_wasm::Module` instance, even when multiple versions of the
`parity_wasm` crate are in use. We'll get a speed boost when they happen to
align (which they always should for `wasm-bindgen`), but it'll work even if they
aren't aligned (by going through serialization).
Concretely on my machine this takes a `wasm-bindgen` invocation from 0.5s to
0.2s, a nice win!
This is a bit of a refinement of the solution from #548 to make sure that these
statics are only present on the `wasm32-*` targets, as otherwise these
descriptors are completely inert on other platforms!
* Add a test harness to directly execute wasm tests
This commits adds a few new crates and infrastructure to enable comands like:
cargo test --target wasm32-unknown-unknown
The intention here is to make it as low-friction as possible to write wasm tests
and also have them execute in a reasonable amount of time. Eventually this is
also hopefully enough support to do things like headless testing!
For now though this is defintely MVP status rather than fully fleshed out.
There's some more information at `crates/test/README.md` about how it works and
how to use it, but for now this is mainly intended to play around with locally
in this repository for our own tests.
* Port a numbe of `js-sys` tests to the new test framework
This commit ports a number of existing tests for the `js-sys` crate over to the
new test framework created in the previous commit, showing off how they can be
executed as well as drastictlly simplifying the tests themselves! This is
intended to be a proof of concept for now which we can refine over time. This
should also show off that it's possible to incrementally move over to the new
test framework.
* 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
This commit adds a hack to the `wasm-bindgen` CLI tool to work around #483 which
is present on nightly Rust with the recent LLVM upgrade. Hopefully this'll carry
us forward until the [upstream bug][1] is fixed.
Closes#483
[1]: https://bugs.llvm.org/show_bug.cgi?id=38184
The changes on master Rust insert debug sections now (yay!) but this means that
wasm binaries by default pick up debug sections from the standard library, so
let's remove them by default in wasm-bindgen unless `--debug` is passed
* Create a new `web-sys` crate
This will eventually contain all the WebIDL-generated bindings to Web APIs.
* ci: Test the new `web-sys` crate in CI
* web-sys: Add a small README
* web-sys: Vendor all the WebIDL files from mozilla-central
* backend: Add a pass to remove AST items that use undefined imports
This is necessary for the WebIDL frontend, which can't translate many WebIDL
constructs into equivalent wasm-bindgen AST things yet. It lets us make
incremental progress: we can generate bindings to methods we can support right
now even though there might be methods on the same interface that we can't
support yet.
* webidl: Add a bunch of missing semicolons
* webidl: Make parsing private
It was only `pub` so that we could test it, but we ended up moving towards
integration tests rather than unit tests that assert particular ASTs are parsed
from WebIDL files.
* webidl: Remove uses of undefined import types
* test-project-builder: Build projects in "very verbose" mode
This helps for debugging failing WebIDL-related tests.
* test-project-builder: Add more profiling timers
* test-project-builder: Detect when webpack-dev-server fails
Instead of going into an infinite loop, detect when webpack-dev-server fails to
start up and early exit the test.
* webidl: Specify version for dev-dependency on wasm-bindgen-backend
Instead of only a relative path.
* guide: Add section about contributing to `web-sys`
* WIP enable Event.webidl
Still need to fix and finish the test.
* Update expected webidl output
* Start out a test's status as incomplete
That way if we don't fill it in the error message doesn't look quite so bizarre
* Fix onerror function in headless mode
Otherwise we don't see any output!
* Fix package.json/node_modules handling in project generation
Make sure these are looked up in the git project root rather than the crate root
* Avoid logging body text
This was meant for debugging and is otherwise pretty noisy
* Fix a relative path
* More expected test fixes
* Fix a typo
* test-project-builder: Allow asynchronous tests
* webidl: Convert [Unforgeable] attributes into `#[wasm_bindgen(structural)]`
Fixes#432
* test-project-builder: Print generated WebIDL bindings for debugging purposes
Helps debug bad WebIDL bindings generation inside tests.
* When we can't find a descriptor, say which one can't be found
This helps when debugging things that need to become structural.
* web-sys: Test bindings for Event
* ci: Use `--manifest-path dir` instead of `cd dir && ...`
* web-sys: Just move .webidl files isntead of symlinking to enable them
* tests: Polyfill Array.prototype.values for older browsers in CI
* test-project-builder: Don't panic on poisoned headless test mutex
We only use it to serialize headless tests so that we don't try to bind the port
concurrently. Its OK to run another headless test if an earlier one panicked.
* JsValue: Add {is,as}_{object,function} methods
Allows dynamically casting values to `js::Object` and `js::Function`.
* tidy: Fix whitespace and missing semicolons
* Allow for dynamic feature detection of methods
If we create bindings to a method that doesn't exist in this implementation,
then it shouldn't fail until if/when we actually try and invoke that missing
method.
* tests: Do feature detection in Array.prototype.values test
* Add JsValue::{is_string, as_js_string} methods
And document all the cast/convert/check methods for js value.
* eslint: allow backtick string literals
* Only generate a fallback import function for non-structural imports
* remove BindgenAttrs from other backend::ast structs
This is primarily a tool for use with the macro crate. Most of
these attributes were ignored in the actual codegen, but a few
were still being used. This is confusing when trying to add
other sources for codegen (such as webidl and typescript).
* move parsing logic to macro crate
This makes the backend crate solely concerned with having an ast
for which we can generate code.
* Reorganize Travis configuration
* Add a `JOB` env var descriptor to all matrix entries. Not used anywhere but is
useful when viewing the whole build on Travis's web interface.
* Reorganize where builds are located, moving slow builds first and fast ones
last.
* Change checking the CLI builds from `cargo build` to `cargo check`
* Use YAML references to reduce some duplication
* Print some more timing statistics for each test
* Extract `Project` helper in tests to a module
This'll help make it a bit more extensible over time. At the same time the
methods are also slightly reorganized to read more clearly from top to bottom.
* Migrate all tests away from Webpack
Wepback can take a significant amount of time to execute and when it's
multiplied by hundreds of tests that adds up really quickly! After investigating
Node's `--experimental-modules` option it looks like it's suitable for our use
so this switches all tests to using JS files (moving away from TypeScript as
well) with `--experimental-modules` with Node.
Tests will be selectively re-enabled with webpack and node.js specific output
(that doesn't require `--experimental-modules`), coming in later commits.
* Restore the node test for node.js output
Ensures it's workable as-is
* Only generate typescript with webpack
* Only read wasm files for webpack
* Skip package.json/node_modules for now
* Only generate webpack config if needed
* Start a dedicated test module for typescript
Will hopefully verify the generated Typescript compiles OK.
* Remove unneeded `node` method
* Fixup some rebase conflicts
* Don't run asmjs example on travis
* Fixup generator tests
* Attempt to fix windows
* Comment windows fix
* More test fixes
* More exclusions
* More test fixes
* Relax eslint regex
Catch mjs modules as well
* Fix eslint
* Speed up travis on examples slightly
Travis tests show hundreds of warning for `'y' is defined but never used` and
when investigating it looks like a mistake was introduced in 0938858aa
during #272, so hopefully this'll be an easy fix!
If a JS import's shim isn't actually imported that means that somewhere along
the way it was optimized out or it was never used in the first place! In that
case we can skip generation of the JS bindings for it as it's not needed.
This can happen when a nested dependency crate exports things but the root crate
doesn't use them. In these cases, it is fine to ignore the missing descriptor,
because the thing it describes was removed as dead code.
* backend comments complete
* better matching
* gen comments
* Add example
* Move test bindings gen to own fn
* move build step into build fn
* add fn to read js, refactor gen_bindings/test to allow for this
* Add comments test
* Update readmes
* add comments to travis
* fix broken tests
* +x on build.sh
* fix wbg cmd in build.sh
* Address fitzgen's comments
This commit optimizes constructing an instance of `JsValue` which is one of
`null`, `undefined`, `true`, or `false`. These are commonly created on the Rust
side of things and since there's only a limited set of values we can easily
prepopulate the global slab with a few entries and use hardcoded indices to
refer to these constants. This should avoid the need to travel into JS to insert
a `null` or and `undefined` into the global slab.
Awhile back slices switched to being raw views into wasm memory, but this
doens't work if we free the underlying memory unconditionally! Moving around a
`Vec` is already moving a lot of data, so let's copy it onto the JS heap instead
of leaving it in the wasm heap.
This commit is an implementation of mapping u64/i64 to `BigInt` in JS through
the unstable BigInt APIs. The BigInt type will ship soon in Chrome and so this
commit builds out the necessary support for wasm-bindgen to use it!
When adding support for mutable slices I was under the impression that if the
wasm memory was reallocated while we were using it then we'd have to commit the
changes from the original buffer back to the new buffer. What I didn't know,
however, is that once the wasm memory is reallocated then all views into it are
supposed to be defunkt.
It looks like node 9 didn't have this implementation quite right and it appears
fixed in node 10, causing the deleted test here to fail. While this commit does
raise the question of whether this is the right approach to interact with slices
in JS I think the answer is still "yes". The user can always initiate the copy
if need be and that seems strictly better than copying 100% of the time.
This commit updates the `Abi` associated type for all slice types to a
`WasmSlice` type, an aggregate of two `u32` integers. This translates to an ABI
where when passed as a function argument it expands to two integer arguments,
and when passed as a return value it passes a return pointer as the first
argument to get filled in.
This is hopefully more forwards-compatible with the host bindings proposal which
uses this strategy for passing string arguments at least. It's a little sketchy
what we're doing as there's not really a stable ABI yet, but hopefully this'll
all be relatively stable for awhile!
This commit adds support for mutable slices to pass the boundary between JS and
Rust. While mutable slices cannot be used as return values they can be listed as
arguments to both exported functions as well as imported functions.
When passing a mutable slice into a Rust function (aka having it as an argument
to an exported Rust function) then like before with a normal slice it's copied
into the wasm memory. Afterwards, however, the updates in the wasm memory will
be reflected back into the original slice. This does require a lot of copying
and probably isn't the most efficient, but it should at least work for the time
being.
The real nifty part happens when Rust passes a mutable slice out to JS. When
doing this it's a very cheap operation that just gets a subarray of the main
wasm memory. Now the wasm memory's buffer can change over time which can produce
surprising results where memory is modified in JS but it may not be reflected
back into Rust. To accomodate this when a JS imported function returns any
updates to the buffer are copied back to Rust if Rust's memory buffer has
changed in the meantime.
Along the way this fixes usage of `slice` to instead use `subarray` as that's
what we really want, no copying. All methods have been updated to use `subarray`
accessors instead of `slice` or constructing new arrays.
Closes#53
This commit adds an example of executing the `wasm2asm` tool to generate asm.js
output instead of WebAssembly. This is often useful when supporting older
browsers, such as IE 11, that doesn't have native support for WebAssembly.
These functions are activated with the `serde-serialization` feature of the
`wasm-bindgen` crate. When activated they will allow passing any arbitrary value
into JS that implements the `Serialize` trait and receiving any value from JS
using the `Deserialize` trait. The interchange between JS and Rust is JSON.
Closes#96
This commit adds a `#[wasm_bindgen(version = "...")]` attribute support. This
information is eventually written into a `__wasm_pack_unstable` section.
Currently this is a strawman for the proposal in ashleygwilliams/wasm-pack#101
Turns out there was a bug when passing a vector of `JsValue` instances back to
JS all objects were leaked rather than correctly removed from the global slab.
This commit fixes how the `getArrayJsValueFromWasm` function is defined to
correctly iterate over the slice by looking at the values rather than the
indices.
Closes#169
Currently errors are reported via Rust panics but there's lots more errors being
added over time so this commit starts the movement towards the `failure` crate
to more idiomatically report errors as well as provide better error messages
over time.
Add support for `#[wasm_bindgen(readonly)]` which indicates that an exported
struct field is readonly and attempting to set it in JS will throw an exception.
Closes#151
Automatically infer public struct fields as "JS wants to access this" and
generate appropriate getters/setters for the field. At this time the field is
required to implement `Copy`, but we will probably want to relax that in the
future to at least encompass `JsValue` and maybe other `Clone` values as well.
Closes#121
Currently the entire `Program` is deserialized to match schema versions but this
is likely to fail when the schema changes. Instead just deserialize the
schema/version fields, compare those, and if successful go ahead and deserialize
everything.
This commit adds support for both `#![no_std]` in the wasm-bindgen runtime
support (disabled by default with an on-by-default `std` feature). This also
adds support to work and compile in the context of `#![no_std]` crates.
Closes#146
This commit adds support for closures with arguments like strings and such. In
other words, closures passed to JS can now have the same suite of arguments as
all functions that can be exported from Rust, as one might expect!
At this time due to the way trait objects work closures still cannot use types
with references like `&str`, but bare values like `String` or `ImportedType`
should work just fine.
Closes#104
This commit overhauls the conversion traits used for types crossing the Rust/JS
boundary. Previously there were a few ad-hoc traits but now there've been
slightly reduced and decoupled.
Conversion from Rust values to JS values is now exclusively done through
`IntoWasmAbi` with no special treatment for references. Conversion from JS to
Rust is a bit trickier as we want to create references in Rust which have
implications in terms of safety. As a result there are now three traits for
this, `FromWasmAbi`, `RefFromWasmAbi`, and `RefMutFromWasmAbi`. These three
traits are implemented for various types and specially dispatched to depending
on the type of argument in the code generator.
The goal of this commit is to lay the groundwork for using these traits in
closures with straightforward-ish definitions.