summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/gc/signal-null-check.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/gc/signal-null-check.js')
-rw-r--r--js/src/jit-test/tests/wasm/gc/signal-null-check.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/gc/signal-null-check.js b/js/src/jit-test/tests/wasm/gc/signal-null-check.js
new file mode 100644
index 0000000000..a56526031d
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/gc/signal-null-check.js
@@ -0,0 +1,148 @@
+// |jit-test| skip-if: !wasmGcEnabled()
+//
+// Checks if null dereference works.
+
+for (let [fieldType, signedness, defaultValue] of [
+ ['i8', '_u', 'i32.const 42'],
+ ['i8', '_s', 'i32.const -42'],
+ ['i16', '_u', 'i32.const 1'],
+ ['i16', '_s', 'i32.const -1'],
+ ['i32', '', 'i32.const 3'],
+ ['i64', '', 'i64.const -77777777777'],
+ ['f32', '', 'f32.const 1.4'],
+ ['f64', '', 'f64.const 3.14'],
+ ['externref', '', 'ref.null extern'],
+].concat(
+ wasmSimdEnabled() ? [['v128', '', 'v128.const i32x4 1 2 -3 4']] : []
+)) {
+ // Check struct.get from null struct of a field of fieldType works
+ // Check struct.set similarly
+ testStructGetSet(fieldType, signedness, defaultValue, 4);
+ // - Also when the field is in the outline_ data area?
+ testStructGetSet(fieldType, signedness, defaultValue, 1000);
+ // Check array.get similarly
+ // Check array.set from null array with element of type fieldType
+ testArrayGetSet(fieldType, signedness, defaultValue, 100);
+}
+
+function testStructGetSet(fieldType, signedness, defaultValue, numFields) {
+ const ins = wasmEvalText(`
+(module
+ (type $t (struct ${
+ Array(numFields).fill("(field (mut " + fieldType + "))").join(' ')
+ }))
+ (global $g (mut (ref null $t)) (ref.null $t))
+ (func (export "init-null")
+ ref.null $t
+ global.set $g
+ )
+ (func (export "init-non-null")
+ ${ Array(numFields).fill(defaultValue).join('\n ') }
+ struct.new $t
+ global.set $g
+ )
+ (func (export "test_get_first")
+ global.get $g
+ struct.get${signedness} $t 0
+ drop
+ )
+ (func (export "test_set_first")
+ global.get $g
+ ${defaultValue}
+ struct.set $t 0
+ )
+ (func (export "test_get_mid")
+ global.get $g
+ struct.get${signedness} $t ${numFields >> 1}
+ drop
+ )
+ (func (export "test_set_mid")
+ global.get $g
+ ${defaultValue}
+ struct.set $t ${numFields >> 1}
+ )
+ (func (export "test_get_last")
+ global.get $g
+ struct.get${signedness} $t ${numFields - 1}
+ drop
+ )
+ (func (export "test_set_last")
+ global.get $g
+ ${defaultValue}
+ struct.set $t ${numFields - 1}
+ )
+)`);
+ ins.exports["init-non-null"]();
+ ins.exports["test_get_first"]();
+ ins.exports["test_get_mid"]();
+ ins.exports["test_get_last"]();
+ ins.exports["test_set_first"]();
+ ins.exports["test_set_mid"]();
+ ins.exports["test_set_last"]();
+
+ ins.exports["init-null"]();
+ assertDerefenceNull(() => ins.exports["test_get_first"]());
+ assertDerefenceNull(() => ins.exports["test_get_mid"]());
+ assertDerefenceNull(() => ins.exports["test_get_last"]());
+ assertDerefenceNull(() => ins.exports["test_set_first"]());
+ assertDerefenceNull(() => ins.exports["test_set_mid"]());
+ assertDerefenceNull(() => ins.exports["test_set_last"]());
+
+ ins.exports["init-non-null"]();
+ ins.exports["test_set_last"]();
+ ins.exports["test_get_first"]();
+}
+
+function testArrayGetSet(fieldType, signedness, defaultValue, numItems) {
+ const ins = wasmEvalText(`
+(module
+ (type $t (array (mut ${fieldType})))
+ (global $g (mut (ref null $t)) (ref.null $t))
+ (func (export "init-null")
+ ref.null $t
+ global.set $g
+ )
+ (func (export "init-non-null")
+ ${defaultValue}
+ i32.const ${numItems}
+ array.new $t
+ global.set $g
+ )
+ (func (export "test_get") (param i32)
+ global.get $g
+ local.get 0
+ array.get${signedness} $t
+ drop
+ )
+ (func (export "test_set") (param i32)
+ global.get $g
+ local.get 0
+ ${defaultValue}
+ array.set $t
+ )
+)`);
+ ins.exports["init-non-null"]();
+ ins.exports["test_get"](0);
+ ins.exports["test_get"](numItems >> 1);
+ ins.exports["test_get"](numItems - 1);
+ ins.exports["test_set"](0);
+ ins.exports["test_set"](numItems >> 1);
+ ins.exports["test_set"](numItems - 1);
+
+ ins.exports["init-null"]();
+ assertDerefenceNull(() => ins.exports["test_get"](0));
+ assertDerefenceNull(() => ins.exports["test_get"](numItems >> 1));
+ assertDerefenceNull(() => ins.exports["test_get"](numItems - 1));
+ assertDerefenceNull(() => ins.exports["test_set"](0));
+ assertDerefenceNull(() => ins.exports["test_set"](numItems >> 1));
+ assertDerefenceNull(() => ins.exports["test_set"](numItems - 1));
+
+ ins.exports["init-non-null"]();
+ ins.exports["test_set"](3);
+ ins.exports["test_get"](0);
+}
+
+
+function assertDerefenceNull(fun) {
+ assertErrorMessage(fun, WebAssembly.RuntimeError, /dereferencing null pointer/);
+}