summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/select.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/select.js')
-rw-r--r--js/src/jit-test/tests/wasm/select.js260
1 files changed, 260 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/select.js b/js/src/jit-test/tests/wasm/select.js
new file mode 100644
index 0000000000..e546a8ff63
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/select.js
@@ -0,0 +1,260 @@
+// Test the select instruction
+
+wasmFailValidateText('(module (func (select (i32.const 0) (i32.const 0) (f32.const 0))))', mismatchError("f32", "i32"));
+
+wasmFailValidateText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" (func 0)))', /(select operand types must match)|(type mismatch: expected f32, found i32)/);
+wasmFailValidateText('(module (func (select (block ) (i32.const 0) (i32.const 0))) (export "" (func 0)))', emptyStackError);
+wasmFailValidateText('(module (func (select (return) (i32.const 0) (i32.const 0))) (export "" (func 0)))', unusedValuesError);
+assertEq(wasmEvalText('(module (func (drop (select (return) (i32.const 0) (i32.const 0)))) (export "" (func 0)))').exports[""](), undefined);
+assertEq(wasmEvalText('(module (func (result i32) (i32.add (i32.const 0) (select (return (i32.const 42)) (i32.const 0) (i32.const 0)))) (export "" (func 0)))').exports[""](), 42);
+wasmFailValidateText('(module (func (select (if (result i32) (i32.const 1) (i32.const 0) (f32.const 0)) (i32.const 0) (i32.const 0))) (export "" (func 0)))', mismatchError("f32", "i32"));
+wasmFailValidateText('(module (func) (func (select (call 0) (call 0) (i32.const 0))) (export "" (func 0)))', emptyStackError);
+
+(function testSideEffects() {
+
+var numT = 0;
+var numF = 0;
+
+var imports = {"": {
+ ifTrue: () => 1 + numT++,
+ ifFalse: () => -1 + numF++,
+}}
+
+// Test that side-effects are applied on both branches.
+var f = wasmEvalText(`
+(module
+ (import "" "ifTrue" (func (result i32)))
+ (import "" "ifFalse" (func (result i32)))
+ (func (param i32) (result i32)
+ (select
+ (call 0)
+ (call 1)
+ (local.get 0)
+ )
+ )
+ (export "" (func 2))
+)
+`, imports).exports[""];
+
+assertEq(f(-1), numT);
+assertEq(numT, 1);
+assertEq(numF, 1);
+
+assertEq(f(0), numF - 2);
+assertEq(numT, 2);
+assertEq(numF, 2);
+
+assertEq(f(1), numT);
+assertEq(numT, 3);
+assertEq(numF, 3);
+
+assertEq(f(0), numF - 2);
+assertEq(numT, 4);
+assertEq(numF, 4);
+
+assertEq(f(0), numF - 2);
+assertEq(numT, 5);
+assertEq(numF, 5);
+
+assertEq(f(1), numT);
+assertEq(numT, 6);
+assertEq(numF, 6);
+
+})();
+
+function testNumSelect(type, trueVal, falseVal) {
+ var trueJS = jsify(trueVal);
+ var falseJS = jsify(falseVal);
+
+ // Always true condition
+ var alwaysTrue = wasmEvalText(`
+ (module
+ (func (param i32) (result ${type})
+ (select
+ (${type}.const ${trueVal})
+ (${type}.const ${falseVal})
+ (i32.const 1)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(alwaysTrue(0), trueJS);
+ assertEq(alwaysTrue(1), trueJS);
+ assertEq(alwaysTrue(-1), trueJS);
+
+ // Always false condition
+ var alwaysFalse = wasmEvalText(`
+ (module
+ (func (param i32) (result ${type})
+ (select
+ (${type}.const ${trueVal})
+ (${type}.const ${falseVal})
+ (i32.const 0)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(alwaysFalse(0), falseJS);
+ assertEq(alwaysFalse(1), falseJS);
+ assertEq(alwaysFalse(-1), falseJS);
+
+ // Variable condition
+ var f = wasmEvalText(`
+ (module
+ (func (param i32) (result ${type})
+ (select
+ (${type}.const ${trueVal})
+ (${type}.const ${falseVal})
+ (local.get 0)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(f(0), falseJS);
+ assertEq(f(1), trueJS);
+ assertEq(f(-1), trueJS);
+
+ wasmFullPass(`
+ (module
+ (func (param i32) (result ${type})
+ (select
+ (${type}.const ${trueVal})
+ (${type}.const ${falseVal})
+ (local.get 0)
+ )
+ )
+ (export "run" (func 0))
+ )`,
+ trueJS,
+ {},
+ 1);
+}
+
+testNumSelect('i32', 13, 37);
+testNumSelect('i32', Math.pow(2, 31) - 1, -Math.pow(2, 31));
+
+testNumSelect('f32', Math.fround(13.37), Math.fround(19.89));
+testNumSelect('f32', 'inf', '-0');
+testNumSelect('f32', 'nan', Math.pow(2, -31));
+
+testNumSelect('f64', 13.37, 19.89);
+testNumSelect('f64', 'inf', '-0');
+testNumSelect('f64', 'nan', Math.pow(2, -31));
+
+wasmAssert(`
+(module
+ (func $f (param i32) (result i64)
+ (select
+ (i64.const 0xc0010ff08badf00d)
+ (i64.const 0x12345678deadc0de)
+ (local.get 0)
+ )
+ )
+ (export "" (func 0))
+)`, [
+ { type: 'i64', func: '$f', args: ['i32.const 0'], expected: '0x12345678deadc0de' },
+ { type: 'i64', func: '$f', args: ['i32.const 1'], expected: '0xc0010ff08badf00d' },
+ { type: 'i64', func: '$f', args: ['i32.const -1'], expected: '0xc0010ff08badf00d' },
+], {});
+
+wasmFailValidateText(`(module
+ (func (param externref)
+ (select (local.get 0) (local.get 0) (i32.const 0))
+ drop
+ ))`,
+ /(untyped select)|(type mismatch: select only takes integral types)/);
+
+wasmFailValidateText(`(module
+ (func (param funcref)
+ (select (local.get 0) (local.get 0) (i32.const 0))
+ drop
+ ))`,
+ /(untyped select)|(type mismatch: select only takes integral types)/);
+
+function testRefSelect(type, trueVal, falseVal) {
+ // Always true condition
+ var alwaysTrue = wasmEvalText(`
+ (module
+ (func (param i32 ${type} ${type}) (result ${type})
+ (select (result ${type})
+ local.get 1
+ local.get 2
+ (i32.const 1)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(alwaysTrue(0, trueVal, falseVal), trueVal);
+ assertEq(alwaysTrue(1, trueVal, falseVal), trueVal);
+ assertEq(alwaysTrue(-1, trueVal, falseVal), trueVal);
+
+ // Always false condition
+ var alwaysFalse = wasmEvalText(`
+ (module
+ (func (param i32 ${type} ${type}) (result ${type})
+ (select (result ${type})
+ local.get 1
+ local.get 2
+ (i32.const 0)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(alwaysFalse(0, trueVal, falseVal), falseVal);
+ assertEq(alwaysFalse(1, trueVal, falseVal), falseVal);
+ assertEq(alwaysFalse(-1, trueVal, falseVal), falseVal);
+
+ // Variable condition
+ var f = wasmEvalText(`
+ (module
+ (func (param i32 ${type} ${type}) (result ${type})
+ (select (result ${type})
+ local.get 1
+ local.get 2
+ (local.get 0)
+ )
+ )
+ (export "" (func 0))
+ )
+ `, {}).exports[""];
+
+ assertEq(f(0, trueVal, falseVal), falseVal);
+ assertEq(f(1, trueVal, falseVal), trueVal);
+ assertEq(f(-1, trueVal, falseVal), trueVal);
+
+ wasmFullPass(`
+ (module
+ (func (param i32 ${type} ${type}) (result ${type})
+ (select (result ${type})
+ local.get 1
+ local.get 2
+ (local.get 0)
+ )
+ )
+ (export "run" (func 0))
+ )`,
+ trueVal,
+ {},
+ 1,
+ trueVal,
+ falseVal);
+}
+
+testRefSelect('externref', {}, {});
+
+let {export1, export2} = wasmEvalText(`(module
+ (func (export "export1"))
+ (func (export "export2"))
+)`).exports;
+
+testRefSelect('funcref', export1, export2);