9 Commits

Author SHA1 Message Date
Alex Crichton
68c5233f80 First refactor for WebIDL bindings
This commit starts the `wasm-bindgen` CLI tool down the road to being a
true polyfill for WebIDL bindings. This refactor is probably the first
of a few, but is hopefully the largest and most sprawling and everything
will be a bit more targeted from here on out.

The goal of this refactoring is to separate out the massive
`crates/cli-support/src/js/mod.rs` into a number of separate pieces of
functionality. It currently takes care of basically everything
including:

* Binding intrinsics
* Handling anyref transformations
* Generating all JS for imports/exports
* All the logic for how to import and how to name imports
* Execution and management of wasm-bindgen closures

Many of these are separable concerns and most overlap with WebIDL
bindings. The internal refactoring here is intended to make it more
clear who's responsible for what as well as making some existing
operations much more straightforward. At a high-level, the following
changes are done:

1. A `src/webidl.rs` module is introduced. The purpose of this module is
   to take all of the raw wasm-bindgen custom sections from the module
   and transform them into a WebIDL bindings section.

  This module has a placeholder `WebidlCustomSection` which is nowhere
  near the actual custom section but if you squint is in theory very
  similar. It's hoped that this will eventually become the true WebIDL
  custom section, currently being developed in an external crate.

  Currently, however, the WebIDL bindings custom section only covers a
  subset of the functionality we export to wasm-bindgen users. To avoid
  leaving them high and dry this module also contains an auxiliary
  custom section named `WasmBindgenAux`. This custom section isn't
  intended to have a binary format, but is intended to represent a
  theoretical custom section necessary to couple with WebIDL bindings to
  achieve all our desired functionality in `wasm-bindgen`. It'll never
  be standardized, but it'll also never be serialized :)

2. The `src/webidl.rs` module now takes over quite a bit of
   functionality from `src/js/mod.rs`. Namely it handles synthesis of an
   `export_map` and an `import_map` mapping export/import IDs to exactly
   what's expected to be hooked up there. This does not include type
   information (as that's in the bindings section) but rather includes
   things like "this is the method of class A" or "this import is from
   module `foo`" and things like that. These could arguably be subsumed
   by future JS features as well, but that's for another time!

3. All handling of wasm-bindgen "descriptor functions" now happens in a
   dedicated `src/descriptors.rs` module. The output of this module is
   its own custom section (intended to be immediately consumed by the
   WebIDL module) which is in theory what we want to ourselves emit one
   day but rustc isn't capable of doing so right now.

4. Invocations and generations of imports are completely overhauled.
   Using the `import_map` generated in the WebIDL step all imports are
   now handled much more precisely in one location rather than
   haphazardly throughout the module. This means we have precise
   information about each import of the module and we only modify
   exactly what we're looking at. This also vastly simplifies intrinsic
   generation since it's all simply a codegen part of the `rust2js.rs`
   module now.

5. Handling of direct imports which don't have a JS shim generated is
   slightly different from before and is intended to be
   future-compatible with WebIDL bindings in its full glory, but we'll
   need to update it to handle cases for constructors and method calls
   eventually as well.

6. Intrinsic definitions now live in their own file (`src/intrinsic.rs`)
   and have a separated definition for their symbol name and signature.
   The actual implementation of each intrinsic lives in `rust2js.rs`

There's a number of TODO items to finish before this merges. This
includes reimplementing the anyref pass and actually implementing import
maps for other targets. Those will come soon in follow-up commits, but
the entire `tests/wasm/main.rs` suite is currently passing and this
seems like a good checkpoint.
2019-06-05 07:52:14 -07:00
Alex Crichton
c876bd6268
Merge pull request #1570 from DiamondLovesYou/master
Support 8 argument closures.
2019-06-03 09:36:41 -05:00
Richard Diamond
03218d9d3c Support 8 argument closures. 2019-06-01 04:19:26 -05:00
Alex Crichton
542076d658 Protect against segfaults calling destroyed closures
This commit updates the drop glue generated for closures to simply
ignore null pointers. The drop glue can be called in erroneous
situations such as when a closure is invoked after it's been destroyed.
In these cases we don't want to segfault and/or corrupt memory but
instead let the normal error message from the invoke glue continue to
get propagated.

Closes #1526
2019-05-13 07:22:33 -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
Nick Fitzgerald
2ce57a7fa1 Add support for FnOnce to Closure 2019-03-01 13:18:48 -08:00
Alex Crichton
20e871f676 Fix an issue where closure rewriting required class internals
Surfaced through previous sanity-checking commits, this reorders some
internal operations to...

Closes #1174
2019-01-14 15:53:29 -08: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
Anton Danilkin
654bb9b683 Port tests that use only basic features 2018-08-04 22:25:29 -05:00