Skip to content

Commit d7a4a77

Browse files
authored
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
1 parent 9469c16 commit d7a4a77

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1263
-357
lines changed

crates/anyref-xform/src/lib.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct Meta {
4848
pub table: TableId,
4949
pub alloc: Option<FunctionId>,
5050
pub drop_slice: Option<FunctionId>,
51+
pub live_count: Option<FunctionId>,
5152
}
5253

5354
struct Transform<'a> {
@@ -178,20 +179,27 @@ impl Context {
178179
let mut heap_alloc = None;
179180
let mut heap_dealloc = None;
180181
let mut drop_slice = None;
182+
let mut live_count = None;
181183

182184
// Find exports of some intrinsics which we only need for a runtime
183185
// implementation.
186+
let mut to_delete = Vec::new();
184187
for export in module.exports.iter() {
185188
let f = match export.item {
186189
walrus::ExportItem::Function(f) => f,
187190
_ => continue,
188191
};
189192
match export.name.as_str() {
190-
"__wbindgen_anyref_table_alloc" => heap_alloc = Some(f),
191-
"__wbindgen_anyref_table_dealloc" => heap_dealloc = Some(f),
192-
"__wbindgen_drop_anyref_slice" => drop_slice = Some(f),
193+
"__anyref_table_alloc" => heap_alloc = Some(f),
194+
"__anyref_table_dealloc" => heap_dealloc = Some(f),
195+
"__anyref_drop_slice" => drop_slice = Some(f),
196+
"__anyref_heap_live_count" => live_count = Some(f),
193197
_ => continue,
194198
}
199+
to_delete.push(export.id());
200+
}
201+
for id in to_delete {
202+
module.exports.delete(id);
195203
}
196204
let mut clone_ref = None;
197205
if let Some(heap_alloc) = heap_alloc {
@@ -240,6 +248,7 @@ impl Context {
240248
table,
241249
alloc: heap_alloc,
242250
drop_slice,
251+
live_count,
243252
})
244253
}
245254
}

crates/anyref-xform/tests/anyref-param-owned.wat

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
(module
44
(func $foo (export "foo") (param i32))
5-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
5+
(func $alloc (export "__anyref_table_alloc") (result i32)
66
i32.const 0)
7-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
7+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
88
)
99

1010
(; CHECK-ALL:
@@ -23,9 +23,6 @@
2323
(func $alloc (type 0) (result i32)
2424
i32.const 0)
2525
(func $foo (type 1) (param i32))
26-
(func $dealloc (type 1) (param i32))
2726
(table (;0;) 32 anyref)
28-
(export "foo" (func $foo anyref shim))
29-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
30-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
27+
(export "foo" (func $foo anyref shim)))
3128
;)

crates/anyref-xform/tests/anyref-param.wat

+7-13
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
(module
44
(func $foo (export "foo") (param i32))
5-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
5+
(func $alloc (export "__anyref_table_alloc") (result i32)
66
i32.const 0)
7-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
7+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
88
)
99

1010
(; CHECK-ALL:
1111
(module
12-
(type (;0;) (func (result i32)))
13-
(type (;1;) (func (param i32)))
14-
(type (;2;) (func (param anyref)))
15-
(func $foo anyref shim (type 2) (param anyref)
12+
(type (;0;) (func (param i32)))
13+
(type (;1;) (func (param anyref)))
14+
(func $foo anyref shim (type 1) (param anyref)
1615
(local i32)
1716
global.get 0
1817
i32.const 1
@@ -31,13 +30,8 @@
3130
i32.const 1
3231
i32.add
3332
global.set 0)
34-
(func $alloc (type 0) (result i32)
35-
i32.const 0)
36-
(func $foo (type 1) (param i32))
37-
(func $dealloc (type 1) (param i32))
33+
(func $foo (type 0) (param i32))
3834
(table (;0;) 32 anyref)
3935
(global (;0;) (mut i32) (i32.const 32))
40-
(export "foo" (func $foo anyref shim))
41-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
42-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
36+
(export "foo" (func $foo anyref shim)))
4337
;)

crates/anyref-xform/tests/clone-ref-intrinsic.wat

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
(func $foo (export "foo") (param i32) (result i32)
77
local.get 0
88
call $clone)
9-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
9+
(func $alloc (export "__anyref_table_alloc") (result i32)
1010
i32.const 0)
11-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
11+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1212
)
1313

1414
(; CHECK-ALL:
@@ -44,7 +44,5 @@
4444
i32.const 0)
4545
(func $dealloc (type 1) (param i32))
4646
(table (;0;) 32 anyref)
47-
(export "foo" (func $foo anyref shim))
48-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
49-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
47+
(export "foo" (func $foo anyref shim)))
5048
;)

crates/anyref-xform/tests/drop-ref-intrinsic.wat

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
(func $foo (export "foo") (param i32)
77
local.get 0
88
call $drop)
9-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
9+
(func $alloc (export "__anyref_table_alloc") (result i32)
1010
i32.const 0)
11-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
11+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1212
)
1313

1414
(; CHECK-ALL:
@@ -31,7 +31,5 @@
3131
i32.const 0)
3232
(func $dealloc (type 1) (param i32))
3333
(table (;0;) 32 anyref)
34-
(export "foo" (func $foo anyref shim))
35-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
36-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
34+
(export "foo" (func $foo anyref shim)))
3735
;)

crates/anyref-xform/tests/import-anyref-owned.wat

+8-13
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,18 @@
55
(func (export "foo")
66
i32.const 0
77
call $a)
8-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
8+
(func $alloc (export "__anyref_table_alloc") (result i32)
99
i32.const 0)
10-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
10+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1111
)
1212

1313
(; CHECK-ALL:
1414
(module
1515
(type (;0;) (func))
16-
(type (;1;) (func (result i32)))
17-
(type (;2;) (func (param i32)))
18-
(type (;3;) (func (param anyref)))
19-
(import "" "a" (func $a (type 3)))
20-
(func $a anyref shim (type 2) (param i32)
16+
(type (;1;) (func (param i32)))
17+
(type (;2;) (func (param anyref)))
18+
(import "" "a" (func $a (type 2)))
19+
(func $a anyref shim (type 1) (param i32)
2120
local.get 0
2221
table.get 0
2322
local.get 0
@@ -26,11 +25,7 @@
2625
(func (;2;) (type 0)
2726
i32.const 0
2827
call $a anyref shim)
29-
(func $alloc (type 1) (result i32)
30-
i32.const 0)
31-
(func $dealloc (type 2) (param i32))
28+
(func $dealloc (type 1) (param i32))
3229
(table (;0;) 32 anyref)
33-
(export "foo" (func 2))
34-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
35-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
30+
(export "foo" (func 2)))
3631
;)

crates/anyref-xform/tests/import-anyref-ret.wat

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44
(import "" "a" (func $a (result i32)))
55
(func (export "foo") (result i32)
66
call $a)
7-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
7+
(func $alloc (export "__anyref_table_alloc") (result i32)
88
i32.const 0)
9-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
9+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1010
)
1111

1212
(; CHECK-ALL:
1313
(module
1414
(type (;0;) (func (result i32)))
1515
(type (;1;) (func (result anyref)))
16-
(type (;2;) (func (param i32)))
1716
(import "" "a" (func $a (type 1)))
1817
(func $a anyref shim (type 0) (result i32)
1918
(local i32 anyref)
@@ -28,9 +27,6 @@
2827
call $a anyref shim)
2928
(func $alloc (type 0) (result i32)
3029
i32.const 0)
31-
(func $dealloc (type 2) (param i32))
3230
(table (;0;) 32 anyref)
33-
(export "foo" (func 2))
34-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
35-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
31+
(export "foo" (func 2)))
3632
;)

crates/anyref-xform/tests/import-anyref.wat

+7-13
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,24 @@
55
(func (export "foo")
66
i32.const 0
77
call $a)
8-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
8+
(func $alloc (export "__anyref_table_alloc") (result i32)
99
i32.const 0)
10-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
10+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1111
)
1212

1313
(; CHECK-ALL:
1414
(module
1515
(type (;0;) (func))
16-
(type (;1;) (func (result i32)))
17-
(type (;2;) (func (param i32)))
18-
(type (;3;) (func (param anyref)))
19-
(import "" "a" (func $a (type 3)))
20-
(func $a anyref shim (type 2) (param i32)
16+
(type (;1;) (func (param i32)))
17+
(type (;2;) (func (param anyref)))
18+
(import "" "a" (func $a (type 2)))
19+
(func $a anyref shim (type 1) (param i32)
2120
local.get 0
2221
table.get 0
2322
call $a)
2423
(func (;2;) (type 0)
2524
i32.const 0
2625
call $a anyref shim)
27-
(func $alloc (type 1) (result i32)
28-
i32.const 0)
29-
(func $dealloc (type 2) (param i32))
3026
(table (;0;) 32 anyref)
31-
(export "foo" (func 2))
32-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
33-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
27+
(export "foo" (func 2)))
3428
;)

crates/anyref-xform/tests/mixed-export.wat

+7-11
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
(module
44
(func $a (export "a") (param f32 i32 i64 i32 i32))
5-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
5+
(func $alloc (export "__anyref_table_alloc") (result i32)
66
i32.const 0)
7-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
7+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
88
)
99

1010
(; CHECK-ALL:
1111
(module
1212
(type (;0;) (func (result i32)))
13-
(type (;1;) (func (param i32)))
14-
(type (;2;) (func (param f32 i32 i64 i32 i32)))
15-
(type (;3;) (func (param f32 anyref i64 anyref i32)))
16-
(func $a anyref shim (type 3) (param f32 anyref i64 anyref i32)
13+
(type (;1;) (func (param f32 i32 i64 i32 i32)))
14+
(type (;2;) (func (param f32 anyref i64 anyref i32)))
15+
(func $a anyref shim (type 2) (param f32 anyref i64 anyref i32)
1716
(local i32 i32)
1817
global.get 0
1918
i32.const 1
@@ -42,11 +41,8 @@
4241
global.set 0)
4342
(func $alloc (type 0) (result i32)
4443
i32.const 0)
45-
(func $a (type 2) (param f32 i32 i64 i32 i32))
46-
(func $dealloc (type 1) (param i32))
44+
(func $a (type 1) (param f32 i32 i64 i32 i32))
4745
(table (;0;) 32 anyref)
4846
(global (;0;) (mut i32) (i32.const 32))
49-
(export "a" (func $a anyref shim))
50-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
51-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
47+
(export "a" (func $a anyref shim)))
5248
;)

crates/anyref-xform/tests/mixed.wat

+9-14
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,19 @@
99
i32.const 4
1010
i32.const 5
1111
call $a)
12-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
12+
(func $alloc (export "__anyref_table_alloc") (result i32)
1313
i32.const 0)
14-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
14+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1515
)
1616

1717
(; CHECK-ALL:
1818
(module
1919
(type (;0;) (func))
20-
(type (;1;) (func (result i32)))
21-
(type (;2;) (func (param i32)))
22-
(type (;3;) (func (param f32 i32 i64 i32 i32)))
23-
(type (;4;) (func (param f32 anyref i64 anyref i32)))
24-
(import "" "a" (func $a (type 4)))
25-
(func $a anyref shim (type 3) (param f32 i32 i64 i32 i32)
20+
(type (;1;) (func (param i32)))
21+
(type (;2;) (func (param f32 i32 i64 i32 i32)))
22+
(type (;3;) (func (param f32 anyref i64 anyref i32)))
23+
(import "" "a" (func $a (type 3)))
24+
(func $a anyref shim (type 2) (param f32 i32 i64 i32 i32)
2625
local.get 0
2726
local.get 1
2827
table.get 0
@@ -40,11 +39,7 @@
4039
i32.const 4
4140
i32.const 5
4241
call $a anyref shim)
43-
(func $alloc (type 1) (result i32)
44-
i32.const 0)
45-
(func $dealloc (type 2) (param i32))
42+
(func $dealloc (type 1) (param i32))
4643
(table (;0;) 32 anyref)
47-
(export "foo" (func 2))
48-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
49-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
44+
(export "foo" (func 2)))
5045
;)

crates/anyref-xform/tests/ret-anyref.wat

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
(func $foo (export "foo") (result i32)
55
i32.const 0)
66

7-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
7+
(func $alloc (export "__anyref_table_alloc") (result i32)
88
i32.const 0)
9-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
9+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1010
)
1111

1212
(; CHECK-ALL:
@@ -23,11 +23,7 @@
2323
call $dealloc)
2424
(func $foo (type 0) (result i32)
2525
i32.const 0)
26-
(func $alloc (type 0) (result i32)
27-
i32.const 0)
2826
(func $dealloc (type 2) (param i32))
2927
(table (;0;) 32 anyref)
30-
(export "foo" (func $foo anyref shim))
31-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
32-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
28+
(export "foo" (func $foo anyref shim)))
3329
;)

crates/anyref-xform/tests/table-grow-intrinsic.wat

+3-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
i32.const 0
88
call $grow
99
drop)
10-
(func $alloc (export "__wbindgen_anyref_table_alloc") (result i32)
10+
(func $alloc (export "__anyref_table_alloc") (result i32)
1111
i32.const 0)
12-
(func $dealloc (export "__wbindgen_anyref_table_dealloc") (param i32))
12+
(func $dealloc (export "__anyref_table_dealloc") (param i32))
1313
)
1414

1515
(; CHECK-ALL:
@@ -32,9 +32,6 @@
3232
drop)
3333
(func $alloc (type 0) (result i32)
3434
i32.const 0)
35-
(func $dealloc (type 1) (param i32))
3635
(table (;0;) 32 anyref)
37-
(export "foo" (func $foo anyref shim))
38-
(export "__wbindgen_anyref_table_alloc" (func $alloc))
39-
(export "__wbindgen_anyref_table_dealloc" (func $dealloc)))
36+
(export "foo" (func $foo anyref shim)))
4037
;)

0 commit comments

Comments
 (0)