summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/gc/init-expr.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/gc/init-expr.js')
-rw-r--r--js/src/jit-test/tests/wasm/gc/init-expr.js281
1 files changed, 281 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/gc/init-expr.js b/js/src/jit-test/tests/wasm/gc/init-expr.js
new file mode 100644
index 0000000000..dff4b5c028
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/gc/init-expr.js
@@ -0,0 +1,281 @@
+// |jit-test| skip-if: !wasmGcEnabled()
+
+// Test wasm::InitExpr GC specific constant expressions
+
+// struct.new and struct.new_default
+
+const { structNew, structNewDefault, structLarge } = wasmEvalText(`(module
+ (type $r (struct (field i32) (field f32)))
+ (type $xxl (struct
+ (field i64) (field f64) (field i64) (field f64)
+ (field i64) (field f64) (field i64) (field f64)
+ (field i64) (field f64) (field i64) (field f64)
+ (field i64) (field f64) (field i64) (field f64)
+ (field i64) (field f64) (field i64) (field f64)))
+
+ (global $g1 (ref null $r) (struct.new_default $r))
+
+ (global $g2 (ref null $r) (struct.new $r
+ (i32.const 2)
+ (f32.const 3.14)))
+
+ (global $gx (ref null $xxl) (struct.new $xxl
+ (i64.const 1) (f64.const 2.) (i64.const 3) (f64.const 4.)
+ (i64.const 5) (f64.const 2.) (i64.const 3) (f64.const 4.)
+ (i64.const 1) (f64.const 8.) (i64.const 9) (f64.const 4.)
+ (i64.const 1) (f64.const 2.) (i64.const 12) (f64.const 3.14)
+ (i64.const 16) (f64.const 17.) (i64.const 18) (f64.const 19.)))
+
+ (func (export "structNewDefault") (result eqref) global.get $g1)
+ (func (export "structNew") (result eqref) global.get $g2)
+ (func (export "structLarge") (result eqref) global.get $gx)
+ )`).exports;
+
+let result;
+result = structNew();
+assertEq(wasmGcReadField(result, 0), 2);
+assertEq(wasmGcReadField(result, 1), new Float32Array([3.140000104904175])[0]);
+result = structNewDefault();
+assertEq(wasmGcReadField(result, 0), 0);
+assertEq(wasmGcReadField(result, 1), 0);
+result = structLarge();
+assertEq(wasmGcReadField(result, 2), 3n);
+assertEq(wasmGcReadField(result, 19), 19);
+
+// array.new, array.new_default, array.new_fixed, and array.new_elem
+
+const { arrayNew, arrayNewDefault, arrayNewFixed, arrayNewElem } = wasmEvalText(`(module
+ (type $r (struct (field i32) (field f32)))
+ (type $a1 (array f64))
+ (type $a2 (array i32))
+ (type $a3 (array (ref null $r)))
+
+ (global $g1 (ref null $a1) (array.new $a1 (f64.const 3.14) (i32.const 3)))
+ (global $g2 (ref null $a2) (array.new_default $a2 (i32.const 2)))
+ (global $g3 (ref null $a3) (array.new_fixed $a3 2
+ (struct.new $r (i32.const 10) (f32.const 16.0))
+ (ref.null $r)))
+
+ (elem $a3e (ref null $r)
+ (item (struct.new $r (i32.const 1) (f32.const 2.0)))
+ (item (struct.new $r (i32.const 3) (f32.const 4.0)))
+ (item (struct.new $r (i32.const 5) (f32.const 6.0)))
+ )
+
+ (func (export "arrayNew") (result eqref) global.get $g1)
+ (func (export "arrayNewDefault") (result eqref) global.get $g2)
+ (func (export "arrayNewFixed") (result eqref) global.get $g3)
+ (func (export "arrayNewElem") (result eqref)
+ (array.new_elem $a3 $a3e (i32.const 0) (i32.const 3))
+ )
+ )`).exports;
+
+result = arrayNew();
+assertEq(wasmGcArrayLength(result), 3);
+assertEq(wasmGcReadField(result, 0), 3.14);
+assertEq(wasmGcReadField(result, 2), 3.14);
+
+result = arrayNewDefault();
+assertEq(wasmGcArrayLength(result), 2);
+assertEq(wasmGcReadField(result, 1), 0);
+
+result = arrayNewFixed();
+assertEq(wasmGcArrayLength(result), 2);
+assertEq(wasmGcReadField(wasmGcReadField(result, 0), 0), 10);
+assertEq(wasmGcReadField(wasmGcReadField(result, 0), 1), 16);
+assertEq(wasmGcReadField(result, 1), null);
+
+result = arrayNewElem();
+assertEq(wasmGcArrayLength(result), 3);
+assertEq(wasmGcReadField(wasmGcReadField(result, 0), 0), 1);
+assertEq(wasmGcReadField(wasmGcReadField(result, 0), 1), 2);
+assertEq(wasmGcReadField(wasmGcReadField(result, 1), 0), 3);
+assertEq(wasmGcReadField(wasmGcReadField(result, 1), 1), 4);
+assertEq(wasmGcReadField(wasmGcReadField(result, 2), 0), 5);
+assertEq(wasmGcReadField(wasmGcReadField(result, 2), 1), 6);
+
+// any.convert_extern and extern.convert_any
+
+let {testString, testArray} = wasmEvalText(`(module
+ (type $array (array i32))
+ (import "env" "s" (global $s (ref extern)))
+ (global $s' (ref extern) (extern.convert_any (any.convert_extern (global.get $s))))
+ (func (export "testString") (result (ref extern))
+ (global.get $s'))
+ (global $a (ref $array) (array.new_fixed $array 1 (i32.const 0)))
+ (global $a' (ref any) (any.convert_extern (extern.convert_any (global.get $a))))
+ (func (export "testArray") (result i32)
+ (ref.eq (global.get $a) (ref.cast (ref eq) (global.get $a'))))
+)`, {env:{s:"abc"}}).exports;
+
+assertEq(testString(), 'abc');
+assertEq(testArray(), 1);
+
+wasmFailValidateText(`(module
+ (global $g (ref extern) (extern.convert_any (any.convert_extern (ref.null extern))))
+)`, /expected/);
+wasmFailValidateText(`(module
+ (global $g (ref extern) (any.convert_extern (extern.convert_any (ref.null any))))
+)`, /expected/);
+
+// Simple table initialization
+{
+ const { t1, t2, t1init } = wasmEvalText(`(module
+ (type $s (struct (field i32)))
+ (type $a1 (array f64))
+ (type $a2 (array (ref null $s)))
+
+ ;; passive segment
+ (elem $e1 anyref
+ (item (struct.new $s (i32.const 123)))
+ (item (array.new $a1 (f64.const 234) (i32.const 3)))
+ (item (array.new_default $a2 (i32.const 3)))
+ (item (ref.i31 (i32.const 345)))
+ )
+ (table $t1 (export "t1") 4 4 anyref)
+
+ ;; active segment
+ (table $t2 (export "t2") anyref (elem
+ (item (struct.new $s (i32.const 321)))
+ (item (array.new $a1 (f64.const 432) (i32.const 3)))
+ (item (array.new_default $a2 (i32.const 3)))
+ (item (ref.i31 (i32.const 543)))
+ ))
+
+ (func (export "t1init") (table.init $t1 $e1 (i32.const 0) (i32.const 0) (i32.const 4)))
+ )`).exports;
+
+ assertEq(t1.get(0), null);
+ assertEq(t1.get(1), null);
+ assertEq(t1.get(2), null);
+ assertEq(t1.get(3), null);
+
+ assertEq(wasmGcReadField(t2.get(0), 0), 321);
+ assertEq(wasmGcReadField(t2.get(1), 0), 432);
+ assertEq(wasmGcReadField(t2.get(1), 1), 432);
+ assertEq(wasmGcReadField(t2.get(1), 2), 432);
+ assertEq(wasmGcReadField(t2.get(2), 0), null);
+ assertEq(wasmGcReadField(t2.get(2), 1), null);
+ assertEq(wasmGcReadField(t2.get(2), 2), null);
+ assertEq(t2.get(3), 543);
+
+ t1init();
+ assertEq(wasmGcReadField(t1.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1.get(1), 0), 234);
+ assertEq(wasmGcReadField(t1.get(1), 1), 234);
+ assertEq(wasmGcReadField(t1.get(1), 2), 234);
+ assertEq(wasmGcReadField(t1.get(2), 0), null);
+ assertEq(wasmGcReadField(t1.get(2), 1), null);
+ assertEq(wasmGcReadField(t1.get(2), 2), null);
+ assertEq(t1.get(3), 345);
+}
+
+// The contents of passive segments are unique per instance and evaluated at
+// instantiation time.
+{
+ const mod = new WebAssembly.Module(wasmTextToBinary(`(module
+ (type $s (struct (field (mut i32))))
+ (type $a (array (mut f64)))
+
+ (elem $e anyref
+ (item (struct.new $s (i32.const 123)))
+ (item (array.new $a (f64.const 234) (i32.const 1)))
+ )
+
+ (table $t1 (export "t1") 2 2 anyref)
+ (table $t2 (export "t2") 2 2 anyref)
+
+ (start $init1)
+
+ (func $init1
+ (table.init $t1 $e (i32.const 0) (i32.const 0) (i32.const 2))
+ )
+ (func (export "init2")
+ (table.init $t2 $e (i32.const 0) (i32.const 0) (i32.const 2))
+ )
+ (func (export "update1")
+ (ref.cast (ref $s) (table.get $t1 (i32.const 0)))
+ (struct.set $s 0 (i32.const 321))
+ (ref.cast (ref $a) (table.get $t1 (i32.const 1)))
+ (array.set $a (i32.const 0) (f64.const 432))
+ )
+ (func (export "update2")
+ (ref.cast (ref $s) (table.get $t1 (i32.const 0)))
+ (struct.set $s 0 (i32.const -321))
+ (ref.cast (ref $a) (table.get $t1 (i32.const 1)))
+ (array.set $a (i32.const 0) (f64.const -432))
+ )
+ )`));
+
+ const { t1: t1_1, t2: t2_1, init2: init2_1, update1: update1_1, update2: update2_1 } = new WebAssembly.Instance(mod, {}).exports;
+ const { t1: t1_2, t2: t2_2, init2: init2_2, update1: update1_2, update2: update2_2 } = new WebAssembly.Instance(mod, {}).exports;
+
+ assertEq(wasmGcReadField(t1_1.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), 234);
+ assertEq(t2_1.get(0), null);
+ assertEq(t2_1.get(1), null);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 234);
+ assertEq(t2_2.get(0), null);
+ assertEq(t2_2.get(1), null);
+
+ update1_1();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), 321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), 432);
+ assertEq(t2_1.get(0), null);
+ assertEq(t2_1.get(1), null);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 234);
+ assertEq(t2_2.get(0), null);
+ assertEq(t2_2.get(1), null);
+
+ init2_1();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), 321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), 432);
+ assertEq(wasmGcReadField(t2_1.get(0), 0), 321);
+ assertEq(wasmGcReadField(t2_1.get(1), 0), 432);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 234);
+ assertEq(t2_2.get(0), null);
+ assertEq(t2_2.get(1), null);
+
+ init2_2();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), 321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), 432);
+ assertEq(wasmGcReadField(t2_1.get(0), 0), 321);
+ assertEq(wasmGcReadField(t2_1.get(1), 0), 432);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 234);
+ assertEq(wasmGcReadField(t2_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t2_2.get(1), 0), 234);
+
+ update2_1();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t2_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t2_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 234);
+ assertEq(wasmGcReadField(t2_2.get(0), 0), 123);
+ assertEq(wasmGcReadField(t2_2.get(1), 0), 234);
+
+ update1_2();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t2_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t2_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), 321);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), 432);
+ assertEq(wasmGcReadField(t2_2.get(0), 0), 321);
+ assertEq(wasmGcReadField(t2_2.get(1), 0), 432);
+
+ update2_2();
+ assertEq(wasmGcReadField(t1_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t1_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t2_1.get(0), 0), -321);
+ assertEq(wasmGcReadField(t2_1.get(1), 0), -432);
+ assertEq(wasmGcReadField(t1_2.get(0), 0), -321);
+ assertEq(wasmGcReadField(t1_2.get(1), 0), -432);
+ assertEq(wasmGcReadField(t2_2.get(0), 0), -321);
+ assertEq(wasmGcReadField(t2_2.get(1), 0), -432);
+}