373 Commits

Author SHA1 Message Date
Alex Crichton
c4776becbb Touch up descriptions of has_type 2019-04-12 10:54:36 -07:00
Alex Crichton
657b97b6d8
Merge pull request #1405 from RReverser/instanceof
Add support for customising `instanceof` behaviour
2019-04-12 12:50:06 -05:00
Ingvar Stepanyan
c77b46af7d Add has_type and update is_instance_of docs 2019-04-12 17:41:51 +01:00
Ingvar Stepanyan
cb880bdbff Add customisable is_type_of 2019-04-12 17:23:42 +01:00
Alex Crichton
e39404e633 Add support for isize/usize arrays
Closes #1426
2019-04-12 08:56:36 -07:00
Alex Crichton
7e5e401076 Add an accessor for the function table
This commit adds an intrinsics to the `wasm_bindgen` crate which
accesses the `WebAssembly.Table` which is the function table of the
module. Eventually the thinking is that a module would import its own
function table via native wasm functionality (via `anyref` and such),
but until that's implemented let's add a binding for it ourselves!

Closes #1427
2019-04-08 10:40:46 -07:00
Alex Crichton
16745edf3f
Merge pull request #1416 from alexcrichton/js-string-valid-utf16
Add warnings about UTF-16 vs UTF-8 strings
2019-04-05 10:12:32 -05:00
Alex Crichton
44738e049a Add warnings about UTF-16 vs UTF-8 strings
This commit aims to address #1348 via a number of strategies:

* Documentation is updated to warn about UTF-16 vs UTF-8 problems
  between JS and Rust. Notably documenting that `as_string` and handling
  of arguments is lossy when there are lone surrogates.

* A `JsString::is_valid_utf16` method was added to test whether
  `as_string` is lossless or not.

The intention is that most default behavior of `wasm-bindgen` will
remain, but where necessary bindings will use `JsString` instead of
`str`/`String` and will manually check for `is_valid_utf16` as
necessary. It's also hypothesized that this is relatively rare and not
too performance critical, so an optimized intrinsic for `is_valid_utf16`
is not yet provided.

Closes #1348
2019-04-05 08:11:50 -07:00
Alex Crichton
d48f4995e5 Support 1-reference argument closures
This is work towards #1399, although it's just for one-argument closures
where the first argument is a reference. No other closures with
references in argument position are supported yet
2019-04-01 14:31:21 -07:00
Sam Day
1914bba0be Implement Debug on Closures
resolves #1387
2019-03-29 09:07:48 +01:00
Sam
ea01043e9a
Quick type fix in closure.rs 2019-03-27 13:03:50 +01:00
Alex Crichton
72672ff42a
Merge pull request #1397 from RReverser/option-char-abi
Simplify ABI for Option<char>
2019-03-26 13:50:59 -05:00
Ingvar Stepanyan
5f742ca4c4 Simplify ABI for Option<char>
Flatten None to a special u32 value instead of using an intermediate pointer.
2019-03-26 18:12:24 +00:00
Alex Crichton
a6fe0cefa8 Migrate all crates to the 2018 edition
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.
2019-03-26 08:10:53 -07:00
Alex Crichton
995be7c027 Replace target flags with --target
This commit deprecates the `--web`, `--no-modules`, and `--nodejs` flags
in favor of one `--target` flag. The motivation for this commit is to be
consistent between `wasm-bindgen` and `wasm-pack` so documentation for
one is applicable for the other (so we don't have to document everywhere
what the translation is between flags). Additionally this should make it
a bit easier to add new targets (if necessary) in the future as it won't
add to the proliferation of flags.

For now the old flags (like `--web`) continue to be accepted, but
they'll be removed during the next set of breaking changes for
`wasm-bindgen`.
2019-03-21 14:00:33 -07:00
Alex Crichton
c463cc96df Clean up the super long finalize function 2019-03-05 14:40:05 -08:00
Nick Fitzgerald
2ce57a7fa1 Add support for FnOnce to Closure 2019-03-01 13:18:48 -08:00
Alex Crichton
745b16e3d2 Add support for TextEncoder#encodeInto
This commit adds support for the recently implemented standard of
[`TextEncoder#encodeInto`][standard]. This new function is a "bring your
own buffer" style function where we can avoid an intermediate allocation
and copy by encoding strings directly into wasm's memory.

Currently we feature-detect whether `encodeInto` exists as it is only
implemented in recent browsers and not in all browsers. Additionally
this commit emits the binding using `encodeInto` by default, but this
requires `realloc` functionality to be exposed by the wasm module.
Measured locally an empty binary which takes `&str` previously took
7.6k, but after this commit takes 8.7k due to the extra code needed for
`realloc`.

[standard]: https://encoding.spec.whatwg.org/#dom-textencoder-encodeinto

Closes #1172
2019-02-26 10:29:39 -08:00
Alex Crichton
4181fb311a Add experimental support for the anyref type
This commit adds experimental support to `wasm-bindgen` to emit and
leverage the `anyref` native wasm type. This native type is still in a
proposal status (the reference-types proposal). The intention of
`anyref` is to be able to directly hold JS values in wasm and pass the
to imported functions, namely to empower eventual host bindings (now
renamed WebIDL bindings) integration where we can skip JS shims
altogether for many imports.

This commit doesn't actually affect wasm-bindgen's behavior at all
as-is, but rather this support requires an opt-in env var to be
configured. Once the support is stable in browsers it's intended that
this will add a CLI switch for turning on this support, eventually
defaulting it to `true` in the far future.

The basic strategy here is to take the `stack` and `slab` globals in the
generated JS glue and move them into wasm using a table. This new table
in wasm is managed at the fringes via injected shims. At
`wasm-bindgen`-time the CLI will rewrite exports and imports with shims
that actually use `anyref` if needed, performing loads/stores inside the
wasm module instead of externally in the wasm module.

This should provide a boost over what we have today, but it's not a
fantastic strategy long term. We have a more grand vision for `anyref`
being a first-class type in the language, but that's on a much longer
horizon and this is currently thought to be the best we can do in terms
of integration in the near future.

The stack/heap JS tables are combined into one wasm table. The stack
starts at the end of the table and grows down with a stack pointer (also
injected). The heap starts at the end and grows up (state managed in
linear memory). The anyref transformation here will hook up various
intrinsics in wasm-bindgen to the runtime functionality if the anyref
supoprt is enabled.

The main tricky treatment here was applied to closures, where we need JS
to use a different function pointer than the one Rust gives it to use a
JS function pointer empowered with anyref. This works by switching up a
bit how descriptors work, embedding the shims to call inside descriptors
rather than communicated at runtime. This means that we're accessing
constant values in the generated JS and we can just update the constant
value accessed.
2019-02-20 07:28:54 -08:00
Nick Fitzgerald
0e11e4a3bd Add the UnwrapThrowExt<T> trait
An extension trait for `Option<T>` and `Result<T, E>` for unwraping the `T`
value, or throwing a JS error if it is not available.

These methods should have a smaller code size footprint than the normal
`Option::unwrap` and `Option::expect` methods, but they are specific to
working with wasm and JS.

On non-wasm32 targets, defaults to the normal unwrap/expect calls.
2019-01-31 13:26:21 -08:00
Alex Crichton
c35d6f4b0a Fix conditional #[wasm_bindgen] in impls
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
2019-01-28 12:29:01 -08:00
Richard Dodd (dodj)
f8680a0c10
remove is array function 2019-01-17 21:08:32 +00:00
Richard Dodd
f3dd38690a Remove Array.isArray test. 2019-01-16 10:16:29 +00:00
Richard Dodd
fab9d1dff6 Resolve what to do with no_std. 2019-01-16 10:16:29 +00:00
Richard Dodd
72765757ef Fix tests again. 2019-01-16 10:16:29 +00:00
Richard Dodd
36cb50445f Make clear it's a JsValue. 2019-01-16 10:16:29 +00:00
Richard Dodd
126efd5a95 Redo as js function + fix tests 2019-01-16 10:16:29 +00:00
Richard Dodd
5b51d279b4 Use toString where JSON.stringify didn't work 2019-01-16 10:16:29 +00:00
Richard Dodd
34bab511e5 Use JSON serialization to get better debug printouts. 2019-01-16 10:16:29 +00:00
Tom Houlé
1f2adb7422
Fix tiny comment formatting issue in docs 2018-12-30 10:14:07 +01:00
daxpedda
4105f7988b
Fix typo in "wasm_bindgen::JsCast" trait docs
This method will return `Err(self)` **is** `self.is_instance_of::<T>()` returns `false`
should be
This method will return `Err(self)` **if** `self.is_instance_of::<T>()` returns `false`
2018-12-01 12:22:39 +01:00
Alex Crichton
29531c0abf Run rustfmt 2018-11-30 13:04:27 -08:00
Alex Crichton
49d835a7bc Switch from heap/stack to just a heap
This commit switches strategies for storing `JsValue` from a heap/stack
to just one heap. This mirrors the new strategy for `JsValue` storage
in #1002 and should make multiplexing those strategies at
`wasm-bindgen`-time much easier.

Instead of having one array which acts as a stack for borrowed values
and one array for a heap of borrowed values, only one JS array is used
for storage of JS values now. This makes `getObject` far simpler by
simply being an array access, but it means that cloning an object now
reserves a new slot instead of reference counting it. If the old
reference counting behavior is needed it's thought that `Rc<JsValue>`
can be used in Rust.

The new "heap" has an initial stack pointer which grows downwards, and a
heap which grows upwards. The heap is a singly-linked-list which is
allocated/deallocated from. The stack grows downwards to zero and
presumably starts generating errors once it underflows. An initial stack
size of 32 is chosen as that should encompass all use cases today, but
we can eventually probably add configuration for this!

Note that the heap is initialized to all `null` for the stack and then
the initial JS values (`undefined`, `null`, `true`, `false`) are pushed
onto the heap in reserved locations.
2018-11-30 12:07:16 -08:00
Alex Crichton
42053ddd4e Move closure shims into the descriptor
Currently closure shims are communicated to JS at runtime, although at
runtime the same constant value is always passed to JS! More pressing,
however, work in #1002 requires knowledge of closure descriptor indices
at `wasm-bindgen` time which is not currently known.

Since the closure descriptor shims and such are already constant values,
this commit moves the descriptor function indices into the *descriptor*
for a closure/function pointer. This way we can learn about these values
at `wasm-bindgen` time instead of only knowing them at runtime.

This should have no semantic change on users of `wasm-bindgen`, although
some closure invocations may be slightly speedier because there's less
arguments being transferred over the boundary. Overall though this will
help #1002 as the closure shims that the Rust compiler generates may not
be the exact ones we hand out to JS, but rather wrappers around them
which do `anyref` business things.
2018-11-29 12:42:44 -08:00
Alex Crichton
151ed58b69 Consistently use extern "C"
This is what rustfmt favors, so let's favor it too!

Closes #1042
2018-11-27 12:27:00 -08:00
Alex Crichton
48f4adfa8c Run rustfmt over everything 2018-11-27 12:07:59 -08:00
Alex Crichton
2e82fdbe16 Don't worry about descriptive strings for malloc errors
This commit updates the `__wbindgen_malloc` shim to avoid throwing a
descriptive error in release mode. This is primarily done for two
reasons:

* If the function is gc'd out in release mode the `"invalid malloc
  request"` string is part of data and can't be gc'd automatically.

* In some esoteric JS environments `TextDecoder` isn't always available,
  and this relatively core function is very quick to bring in that
  requirement early on. For example some recent experimentation with
  WebAudio worklets shows that they currently don't have the
  `TextDecoder` type available!
2018-11-09 12:19:48 -08:00
Roberto Vidal
2faf44250d Fix reference to unexisting method 2018-11-09 13:14:16 +01:00
Alex Crichton
9ebbcd3827
Merge pull request #992 from alexcrichton/inline-trivial
Flag a trivial `JsValue` constructor as `#[inline]`
2018-10-28 14:57:53 -07:00
Alex Crichton
f3d9851c2d Flag a trivial JsValue constructor as #[inline]
No reason this shouldn't be inlined in optimized builds!
2018-10-28 13:16:10 -07:00
Alex Crichton
78f425744f Don't pass 0-length mallocs to system allocator
Part of the unsafe contract!
2018-10-28 10:09:57 -07:00
Alex Crichton
d70257af6c Tweak some logic in JsValue::drop
While technically correct the current implementation sort of made it
only roundaboutedly so. Tweak the logic a bit and the associated comment
to ensure that stack values are never dropped and the global constants
are all skipped.
2018-10-24 23:33:01 -07:00
Alex Crichton
25b26f41e7 Implement support for WebAssembly threads
... and add a parallel raytracing demo!

This commit adds enough support to `wasm-bindgen` to produce a workable
wasm binary *today* with the experimental WebAssembly threads support
implemented in Firefox Nightly. I've tried to comment what's going on in
the commits and such, but at a high level the changes made here are:

* A new transformation, living in a new `wasm-bindgen-threads-xform`
  crate, prepares a wasm module for parallel execution. This performs a
  number of mundane tasks which I hope to detail in a blog post later on.
* The `--no-modules` output is enhanced with more support for when
  shared memory is enabled, allowing passing in the module/memory to
  initialize the wasm instance on multiple threads (sharing both module
  and memory).
* The `wasm-bindgen` crate now offers the ability, in `--no-modules`
  mode, to get a handle on the `WebAssembly.Module` instance.
* The example itself requires Xargo to recompile the standard library
  with atomics and an experimental feature enabled. Afterwards it
  experimentally also enables threading support in wasm-bindgen.

I've also added hopefully enough CI support to compile this example in a
builder so we can upload it and poke around live online. I hope to
detail more about the technical details here in a blog post soon as
well!
2018-10-23 01:20:18 -07:00
Alex Crichton
e46537e6c2 Ensure that JsValue isn't considered Send
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.
2018-10-10 15:47:07 -07:00
Nick Fitzgerald
3ceb0441d3 Use the global allocator, not the system allocator
This was previously causing us to accidentally always pull in the system
allocator, even if users were trying to just use a custom global allocator.
2018-10-09 18:08:46 -07:00
Nick Fitzgerald
7ec1511d3d
Merge pull request #915 from alexcrichton/add-inline
Add a number of `#[inline]` annotation through crates
2018-10-02 16:46:32 -07:00
Alex Crichton
727e0a7154 Fix Closure::forget
It forgot to actually forget the contents!
2018-10-01 15:37:15 -07:00
Alex Crichton
332beecabe Add a number of #[inline] annotation through crates
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!
2018-10-01 15:31:09 -07:00
Alex Crichton
8ba41cce6e Improve codegen for Closure<T>
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
2018-09-29 07:00:53 -07:00
Alex Crichton
5a0ac2d37c Add #[inline] for IntoWasmAbi for ()
No need for it to not be inlined, it literally compiles to nothing!
2018-09-27 12:22:05 -07:00