This commit implements the `extends` attribute for `#[wasm_bindgen]` to
statically draw the inheritance hierarchy in the generated bindings, generating
appropriate `AsRef`, `AsMut`, and `From` implementations.
This commit implements the `JsCast` trait automatically for all imported types
in `#[wasm_bindgen] extern { ... }` blocks. The main change here was to generate
an `instanceof` shim for all imported types in case it's needed.
All imported types now also implement `AsRef<JsValue>` and `AsMut<JsValue>`
First added in #161 this never ended up panning out, so let's remove the
experimental suport which isn't actually used by anything today and hold off on
any other changes until an RFC happens.
* Make ConvertToAst trait fallible
It's got some panics, and we'll be switching those to errors!
* First example of a diagnostic-driven error
Add a diagnostic-driven error `#[wasm_bindgen]` being attached to public
functions, and add some macros to boot to make it easier to generate errors!
* Result-ify `src/parser.rs`
This commit converts all of `src/parser.rs` away from panics to using
`Diagnostic` instead. Along the way this adds a test case per changed `panic!`,
ensuring that we don't regress in these areas!
This commit starts to add infrastructure for targeted diagnostics in the
`#[wasm_bindgen]` attribute, intended eventually at providing much better errors
as they'll be pointing to exactly the code in question rather than always to a
`#[wasm_bindgen]` attribute.
The general changes are are:
* A new `Diagnostic` error type is added to the backend. A `Diagnostic` is
created with a textual error or with a span, and it can also be created from a
list of diagnostics. A `Diagnostic` implements `ToTokens` which emits a bunch
of invocations of `compile_error!` that will cause rustc to later generate
errors.
* Fallible implementations of `ToTokens` have switched to using a new trait,
`TryToTokens`, which returns a `Result` to use `?` with.
* The `MacroParse` trait has changed to returning a `Result` to propagate errors
upwards.
* A new `ui-tests` crate was added which uses `compiletest_rs` to add UI tests.
These UI tests will verify that our output improves over time and does not
regress. This test suite is added to CI as a new builder as well.
* No `Diagnostic` instances are created just yet, everything continues to panic
and return `Ok`, with the one exception of the top-level invocations of
`syn::parse` which now create a `Diagnostic` and pass it along.
This commit does not immediately improve diagnostics but the intention is that
it is laying the groundwork for improving diagnostics over time. It should
ideally be much easier to contribute improved diagnostics after this commit!
cc #601
* Fix importing the same identifier from two modules
This needed a fix in two locations:
* First the generated descriptor function needed its hash to include the module
that the import came from in order to generate unique descriptor functions.
* Second the generation of the JS shim needed to handle duplicate identifiers in
a more uniform fashion, ensuring that imported names didn't clash.
* Fix importing the same name in two modules
Previously two descriptor functions with duplicate symbols were emitted, and now
only one function is emitted by using a global table to keep track of state
across macro invocations.
* Try to enable all webidls
* Separate out unavailable webidl files by reason.
* Create record of fully tested WebIDL files
* Update notes to reflect new situation with web-idl
* Make a blank ident fail, disable the necessary widls.
It turns out that all the blank idents came from blank enum variants,
which is allowed in webidl apparently.
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!
* 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
Not a lot of attention has been paid to dealing with conflicts of symbols
between crates and different `#[wasm_bindgen]` blocks. This commit starts to fix
this issue by unblocking #486 which first ran into this. Currently there's a bug
where if two independent crates bind the same JS API they'll generate the same
symbol which causes conflicts for things like LTO or linking in general.
This commit starts to add a "salt" to all symbols generated by `wasm-bindgen`
(these are all transparent to the user) to ensure that each crate's invocations
are kept apart from one another and using the correct bindings.
* clippy: it is more idiomatic to loop over references to containers instead of using explicit iteration methods
* clippy: useless use of `format!`
* clippy: if/else is an expression
* clippy: use of followed by a function call
* clippy: large size difference between variants
* clippy: redundant closure
* Revert "clippy: large size difference between variants"
This reverts commit 7e2e660dd4.
* Revert "clippy: it is more idiomatic to loop over references to containers instead of using explicit iteration methods"
This reverts commit 5c4804f790.
I've started noticing this in non-LTO builds and initially tried to remove it. I
was unsuccessful but decided to better document my adventures to hopefully
improve future onlookers!
This sets the `catch` flag on the emitted AST when an operation/attribute has
the `[Throws]` extended attribute on it.
Additionally, constructors aren't annotated with `[Throws]` but can still throw
exceptions, so we must conservatively assume *every* constructor can throw an
error.
* 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.
This is similar to `js_namespace` but translates into a static method on `Class`
rather than a free function. This allows us to have bindings to things like
`Object.keys` as `Object::keys`.
* 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
Currently `#[wasm_bindgen]` generates a bunch of references to symbols that
don't actually exist on non-wasm targets, making it more difficult to get a
crate working across multiple platforms. This commit updates the symbol
references to be dummy ones that panic on non-wasm targets to allow simple
testing/benchmarking to work on native targets.
While this isn't a perfect solution for #114 it's probably as good as we can do
for now pending upstream Cargo features, so I'm gonna say that it...
Closes#114
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
Using `proc-macro2`'s `nightly` feature is a good default for most use cases.
However, it causes a build error if used together with crates such as
`cssparser` that also use `proc-macro2` from a build script.
This change adds a default enabled feature `spans` that users can disable if
they need to work around this conflict.
Fixes#160.
The previous codegen wasn't enough to convince LLVM that the function pointer
was a constant value and could be aggressively inlined, so this updates the
`JsStatic` internals slightly to guarantee to LLVM that the function pointer is
constant and no dynamic dispatch is needed after all
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
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 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.
This commit adds support for passing `&mut FnMut(..)` to JS via imports. These
closures cannot be invoked recursively in JS (they invalidate themselves while
they're being invoked) and otherwise work the same as `&Fn(..)` closures.
Closes#123
This commit is a complete overhaul of how the `#[wasm_bindgen]` macro
communicates type information to the CLI tool, and it's done in a somewhat...
unconventional fashion.
Today we've got a problem where the generated JS needs to understand the types
of each function exported or imported. This understanding is what enables it to
generate the appropriate JS wrappers and such. We want to, however, be quite
flexible and extensible in types that are supported across the boundary, which
means that internally we rely on the trait system to resolve what's what.
Communicating the type information historically was done by creating a four byte
"descriptor" and using associated type projections to communicate that to the
CLI tool. Unfortunately four bytes isn't a lot of space to cram information like
arguments to a generic function, tuple types, etc. In general this just wasn't
flexible enough and the way custom references were treated was also already a
bit of a hack.
This commit takes a radical step of creating a **descriptor function** for each
function imported/exported. The really crazy part is that the `wasm-bindgen` CLI
tool now embeds a wasm interpreter and executes these functions when the CLI
tool is invoked. By allowing arbitrary functions to get executed it's now *much*
easier to inform `wasm-bindgen` about complicated structures of types. Rest
assured though that all these descriptor functions are automatically unexported
and gc'd away, so this should not have any impact on binary sizes
A new internal trait, `WasmDescribe`, is added to represent a description of all
types, sort of like a serialization of the structure of a type that
`wasm-bindgen` can understand. This works by calling a special exported function
with a `u32` value a bunch of times. This means that when we run a descriptor we
effectively get a `Vec<u32>` in the `wasm-bindgen` CLI tool. This list of
integers can then be parsed into a rich `enum` for the JS generation to work
with.
This commit currently only retains feature parity with the previous
implementation. I hope to soon solve issues like #123, #104, and #111 with this
support.
This commit starts wasm-bindgen down the path of supporting closures. We
discussed this at the recent Rust All-Hands but I ended up needing to pretty
significantly scale back the ambitions of what closures are supported. This
commit is just the initial support and provides only a small amount of support
but will hopefully provide a good basis for future implementations.
Specifically this commit adds support for passing `&Fn(...)` to an *imported
function*, but nothing elese. The `&Fn` type can have any lifetime and the JS
object is invalidated as soon as the import returns. The arguments and return
value of `Fn` must currently implement the `WasmAbi` trait, aka they can't
require any conversions like strings/types/etc.
I'd like to soon expand this to `&mut FnMut` as well as `'static` closures that
can be passed around for a long time in JS, but for now I'm putting that off
until later. I'm not currently sure how to implement richer argument types, but
hopefully that can be figured out at some point!
This commit starts wasm-bindgen down a path of removing the special
casing it currently has around vectors, slices, and strings. This has
long been a thorn in wasm-bindgen's side as it doesn't handle other
kinds of vectors and otherwise is very inflexible with future additions.
Additionally it leads to a lot of duplicated-ish code throughout various
portions of codegen.
The fundamental reason for this was that two arguments were required to
be passed back to wasm, and I couldn't figure out a way to shove both
those arguments into a function argument. The new strategy here is that
there is one global stack well known to both JS and Rust which arguments
*may* also be transferred between.
By default all ABI arguments pass as literal function arguments, but if
two or more arguments need to be passed then the extra ones are all
passed through this global stack. The stack is effectively temporary
scratch space when crossing the JS/Rust boundary (both ways). No long
term storage is intended here.
The `simple` test is passing as a result of this commit, using strings
internally. The `Vector` type in the AST has been removed (yay!) and the
bulk of the implementation of slices and vectors now resides in the
`wasm-bindgen` crate itself, defining how to pass all these arguments
around. The JS generator, however, still needs to know about all the
sorts of vectors so it can generate appropriate code for JS.
Future commits will continue cleanup and get the rest of the tests
working.