Commit Graph

6 Commits

Author SHA1 Message Date
Pauan
7bc9147258
Improving the code generation for catch (#2098)
* Improving the code generation for catch

* Fixing newlines

* Running rustfmt

* Updating unit tests

* Fixing build error
2020-04-22 09:14:00 -05:00
Alex Crichton
ceac51f260 Fix a test for upstream changes 2020-03-17 07:02:50 -07:00
Timothy McCallum
0f3c53b5a5
Create JavaScript array without using new keyword. (#1987)
* Create JavaScript array without using `new` keyword.

At present [this line of code](https://github.com/rustwasm/wasm-bindgen/blob/master/crates/cli-support/src/js/mod.rs#L747) creates the heap using JavaScript's new keyword.
```
//Line 747
self.global(&format!("const heap = new Array({});", INITIAL_HEAP_OFFSET));
self.global("heap.fill(undefined);");
```
Assuming that the `INITIAL_HEAP_OFFSET` is always 32 (because it is set as a constant in the Rust code), below is the equivalent of what this code will produce; an Array Object with 32 items which are all undefined.
```
const heap = new Array(32);
//(32) [empty × 32]
//Where
var zero_element = heap[0];
//undefined
var one_element = heap[1];
//undefined
```
I believe that this is the desired outcome for the program. All good.

### Suggestion to consider

I am always reminded **not** to use the `new` keyword. Mainly by reading or listening to JavaScript ["The Good Parts"](https://youtu.be/XFTOG895C7c?t=1654). 

For example if the `INITIAL_HEAP_OFFSET` was ever anything but one number, the heap would be created in a different way. For example if two numbers are passed in, then an array of size 2 would be created; where both items in the array are individual numbers.
```
const heap = new Array(32, 32);
var zero_element = heap[0];
var one_element = heap[1];
//32
//32
```
I know that this is highly unlikely, due to the fact that the `INITIAL_HEAP_OFFSET` is set as a `const` in the Rust. But thought that I would put out the following suggestion for consideration anyway. This comes from a place of just wanting to contribute in a way that could make this already awesome program a little better. :)

### Suggested update
The heap array could be created using the following code
```
const heap = [];
heap.length = INITIAL_HEAP_OFFSET;
heap[0]
heap[1]
//undefined
//undefined
```
This would create a JavaScript Array of length `INITIAL_HEAP_OFFSET`, where are items are `undefined`

The new code generates (in raw JavaScript)
```
const heap = [];
heap.length = 32;
```
Which produces
```
(32) [empty × 32]
```
In the same way that the original code does.

* Add closing parenthesis to close out self.global

* Adding files which were altered by the BLESS=1 system variable. Essentially updating generated files that are used for testing.

* Adding code generated wat file, by way of running tests using BLESS=1

* Adding table.wat that was generated by running the  tests with BLESS=1 set

* Update code that creates heap array line 747 mod.rs

* Updating files that are automatically generated when using BLESS=1
2020-02-06 19:00:15 -06:00
Alex Crichton
c564eb72b1
Use *.wat instead of *.wit for text files (#1901)
The `*.wit` extension is actually intended to mean "WebAssembly Instance
Type", not "WebAssembly Interface Types". The `*.wat` text format
already will have support for annotations, and wasm interface types are
just an extension of that!
2019-12-11 16:22:35 -08:00
Alex Crichton
203d86f343
Add tests for the interface types output of wasm-bindgen (#1898)
* Add tests for the interface types output of wasm-bindgen

This commit expands the test suite with assertions about the output of
the interface types pass in wasm-bindgen. The goal here is to actually
assert that we produce the right output and have a suite of reference
files to show how the interface types output is changing over time.

The `reference` test suite added in the previous PR has been updated to
work for interface types as well, generating `*.wit` file assertions
which are printed via the `wit-printer` crate on crates.io.

Along the way a number of bugs were fixed with the interface types
output, such as:

* Non-determinism in output caused by iteration of a `HashMap`

* Avoiding JS generation entirely in interface types mode, ensuring that
  we don't export extraneous intrinsics that aren't otherwise needed.

* Fixing location of the stack pointer for modules where it's GC'd out.
  It's now rooted in the aux section of wasm-bindgen so it's available
  to later passes, like the multi-value pass.

* Interface types emission now works in debug mode, meaning the
  `--release` flag is no longer required. This previously did not work
  because the `__wbindgen_throw` intrinsic was required in debug mode.
  This comes about because of the `malloc_failure` and `internal_error`
  functions in the anyref pass. The purpose of these functions is to
  signal fatal runtime errors, if any, in a way that's usable to the
  user. For wasm interface types though we can replace calls to these
  functions with `unreachable` to avoid needing to import the
  intrinsic. This has the accidental side effect of making
  `wasm_bindgen::throw_str` "just work" with wasm interface types by
  aborting the program, but that's not actually entirely intended. It's
  hoped that a split of a `wasm-bindgen-core` crate would solve this
  issue for the future.

* Run the wasm interface types validator in tests

* Add more gc roots for adapter gc

* Improve stack pointer detection

The stack pointer is never initialized to zero, but some other mutable
globals are (TLS, thread ID, etc), so let's filter those out.
2019-12-04 15:19:48 -06:00
Alex Crichton
d7a4a772cf
Add reference output tests for JS operations (#1894)
* Add reference output tests for JS operations

This commit starts adding a test suite which checks in, to the
repository, test assertions for both the JS and wasm file outputs of a
Rust crate compiled with `#[wasm_bindgen]`. These aren't intended to be
exhaustive or large scale tests, but rather micro-tests to help observe
the changes in `wasm-bindgen`'s output over time.

The motivation for this commit is basically overhauling how all the GC
passes work in `wasm-bindgen` today. The reorganization is also included
in this commit as well.

Previously `wasm-bindgen` would, in an ad-hoc fashion, run the GC passes
of `walrus` in a bunch of places to ensure that less "garbage" was seen
by future passes. This not only was a source of slowdown but it also was
pretty brittle since `wasm-bindgen` kept breaking if extra iteams leaked
through.

The strategy taken in this commit is to have one precise location for a
GC pass, and everything goes through there. This is achieved by:

* All internal exports are removed immediately when generating the
  nonstandard wasm interface types section. Internal exports,
  intrinsics, and runtime support are all referenced by the various
  instructions and/or sections that use them. This means that we now
  have precise tracking of what an adapter uses.

* This in turn enables us to implement the `add_gc_roots` function for
  `walrus` custom sections, which in turn allows walrus GC passes to do
  what `unexport_unused_intrinsics` did before. That function is now no
  longer necessary, but effectively works the same way. All intrinsics
  are unexported at the beginning and then they're selectively
  re-imported and re-exported through the JS glue generation pass as
  necessary and defined by the bindings.

* Passes like the `anyref` pass are now much more precise about the
  intrinsics that they work with. The `anyref` pass also deletes any
  internal intrinsics found and also does some rewriting of the adapters
  aftewards now to hook up calls to the heap count import to the heap
  count intrinsic in the wasm module.

* Fix handling of __wbindgen_realloc

The final user of the `require_internal_export` function was
`__wbindgen_realloc`. This usage has now been removed by updating how we
handle usage of the `realloc` function.

The wasm interface types standard doesn't have a `realloc` function
slot, nor do I think it ever will. This means that as a polyfill for
wasm interface types we'll always have to support the lack of `realloc`.
For direct Rust to JS, however, we can still optionally handle
`realloc`. This is all handled with a few internal changes.

* Custom `StringToMemory` instructions now exist. These have an extra
  `realloc` slot to store an intrinsic, if found.
* Our custom instructions are lowered to the standard instructions when
  generating an interface types section.
* The `realloc` function, if present, is passed as an argument like the
  malloc function when passing strings to wasm. If it's not present we
  use a slower fallback, but if it's present we use the faster
  implementation.

This should mean that there's little-to-no impact on existing users of
`wasm-bindgen`, but this should continue to still work for wasm
interface types polyfills and such. Additionally the GC passes now work
in that they don't delete `__wbindgen_realloc` which we later try to
reference.

* Add an empty test for the anyref pass

* Precisely track I32FromOptionAnyref's dependencies

This depends on the anyref table and a function to allocate an index if
the anyref pass is running, so be sure to track that in the instruction
itself for GC rooting.

* Trim extraneous exports from nop anyref module

Or if you're otherwise not using anyref slices, don't force some
intrinsics to exist.

* Remove globals from reference tests

Looks like these values adjust in slight but insignificant ways over
time

* Update the anyref xform tests
2019-12-04 12:01:39 -06:00