diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/wasm/extended-const | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/wasm/extended-const')
4 files changed, 196 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/extended-const/basic.js b/js/src/jit-test/tests/wasm/extended-const/basic.js new file mode 100644 index 0000000000..bf0ce460d5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/extended-const/basic.js @@ -0,0 +1,95 @@ +// |jit-test| skip-if: !wasmExtendedConstEnabled() + +function testPrivateGlobal(valtype, expr, result) { + // Immutable private globals have a single cell for wasm. + let { get } = wasmEvalText(`(module + (global $global ${valtype} ${expr}) + (func (export "get") (result ${valtype}) + global.get $global + ) + )`).exports; + assertEq(get(), result); +} +function testExportedGlobal(valtype, expr, result) { + // Immutable exported globals have a separate cell for wasm and the exported + // global object. + let { global, get } = wasmEvalText(`(module + (global $global (export "global") ${valtype} ${expr}) + (func (export "get") (result ${valtype}) + global.get $global + ) + )`).exports; + assertEq(get(), result); + assertEq(global.value, result); +} +function testIndirectGlobal(valtype, expr, result) { + // Mutable exported globals share an indirect cell for wasm and the exported + // global object. + let { global } = wasmEvalText(`(module + (global (export "global") (mut ${valtype}) ${expr}) + )`).exports; + assertEq(global.value, result); +} + +// i32 tests + +const I32_SQ_OVERFLOW = 0xFFFF + 1; +const MAX_I32 = 0xFFFF_FFFF; +function testI32(expr, result) { + testPrivateGlobal('i32', expr, result); + testExportedGlobal('i32', expr, result); + testIndirectGlobal('i32', expr, result); +} +testI32('i32.const 1', 1); + +testI32('i32.const 1 i32.const 2 i32.add', 3); +testI32(`i32.const ${MAX_I32} i32.const 1 i32.add`, 0); + +testI32('i32.const 1 i32.const 2 i32.sub', -1); +testI32(`i32.const 1 i32.const 0 i32.sub`, 1); + +testI32('i32.const 1 i32.const 2 i32.mul', 2); +testI32(`i32.const ${I32_SQ_OVERFLOW} i32.const ${I32_SQ_OVERFLOW} i32.mul`, 0); + +// i64 tests + +const I64_SQ_OVERFLOW = 0xFFFF_FFFFn + 1n; +const MAX_I64 = 0xFFFF_FFFF_FFFF_FFFFn; +function testI64(expr, result) { + testPrivateGlobal('i64', expr, result); + testExportedGlobal('i64', expr, result); + testIndirectGlobal('i64', expr, result); +} +testI64('i64.const 1', 1n); + +testI64('i64.const 1 i64.const 2 i64.add', 3n); +testI64(`i64.const ${MAX_I64} i64.const 1 i64.add`, 0n); + +testI64('i64.const 1 i64.const 2 i64.sub', -1n); +testI64(`i64.const 1 i64.const 0 i64.sub`, 1n); + +testI64('i64.const 1 i64.const 2 i64.mul', 2n); +testI64(`i64.const ${I64_SQ_OVERFLOW} i64.const ${I64_SQ_OVERFLOW} i64.mul`, 0n); + +// test global.get + +function testGlobalGet(valtype, aExpr, bExpr, cExpr, cResult) { + let { a, b } = wasmEvalText(`(module + (global (export "a") ${valtype} ${aExpr}) + (global (export "b") ${valtype} ${bExpr}) + )`).exports; + let { c } = wasmEvalText(`(module + (global $a (import "" "a") ${valtype}) + (global $b (import "" "b") ${valtype}) + (global (export "c") ${valtype} ${cExpr}) + )`, {"": {a, b}}).exports; + assertEq(c.value, cResult); +} + +testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.add', 5); +testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.sub', -1); +testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.mul', 6); + +testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.add', 5n); +testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.sub', -1n); +testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.mul', 6n); diff --git a/js/src/jit-test/tests/wasm/extended-const/directives.txt b/js/src/jit-test/tests/wasm/extended-const/directives.txt new file mode 100644 index 0000000000..0d16de6524 --- /dev/null +++ b/js/src/jit-test/tests/wasm/extended-const/directives.txt @@ -0,0 +1 @@ +|jit-test| --wasm-extended-const; test-also=--wasm-compiler=optimizing; test-also=--wasm-test-serialization; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; include:wasm.js diff --git a/js/src/jit-test/tests/wasm/extended-const/disabled.js b/js/src/jit-test/tests/wasm/extended-const/disabled.js new file mode 100644 index 0000000000..01e64f6c44 --- /dev/null +++ b/js/src/jit-test/tests/wasm/extended-const/disabled.js @@ -0,0 +1,22 @@ +// |jit-test| skip-if: wasmExtendedConstEnabled() + +const { CompileError, validate } = WebAssembly; + +const DISABLED = /extended constant expressions not enabled|unrecognized opcode/; + +let tests = [ + "(module (global i32 i32.const 0 i32.const 0 i32.add))", + "(module (global i32 i32.const 0 i32.const 0 i32.sub))", + "(module (global i32 i32.const 0 i32.const 0 i32.mul))", + "(module (global i64 i64.const 0 i64.const 0 i64.add))", + "(module (global i64 i64.const 0 i64.const 0 i64.sub))", + "(module (global i64 i64.const 0 i64.const 0 i64.mul))", +]; + +// Test that use of extended constants fails when disabled. + +for (let src of tests) { + let bin = wasmTextToBinary(src); + assertEq(validate(bin), false); + wasmCompilationShouldFail(bin, DISABLED); +} diff --git a/js/src/jit-test/tests/wasm/extended-const/pathological.js b/js/src/jit-test/tests/wasm/extended-const/pathological.js new file mode 100644 index 0000000000..e3695f3625 --- /dev/null +++ b/js/src/jit-test/tests/wasm/extended-const/pathological.js @@ -0,0 +1,78 @@ +// |jit-test| skip-if: !wasmExtendedConstEnabled() + +// Let's calculate zero in some elaborate ways. +function testFancyZeroOffset(fancyZero, memType = 'i32') { + try { + const { mem } = wasmEvalText(`(module + (memory (export "mem") ${memType} 1) + (data (offset ${fancyZero}) "hi") + )`).exports; + const str = String.fromCharCode(...new Uint8Array(mem.buffer).slice(0, 2)); + assertEq(str, 'hi'); + } catch (e) { + const { getOffset } = wasmEvalText(`(module + (func (export "getOffset") (result ${memType}) + ${fancyZero} + ) + )`).exports; + console.log('Computed offset:', getOffset()); + throw e; + } +} + +// Do plus one minus one a thousand times +testFancyZeroOffset('i32.const 0 ' + ( + '(i32.add (i32.const 1)) ' + + '(i32.sub (i32.const 1)) ' +).repeat(1000)); + +// Do some jank fibonacci +{ + let fib = '(i32.const 1)\n' + let a = 1; let b = 1; let next; + for (let i = 0; i < 45; i++) { + fib += `(i32.const ${a})\n`; + fib += '(i32.add)\n'; + next = a + b; + a = b; + b = next; + } + fib += `(i32.sub (i32.const ${next}))\n`; + testFancyZeroOffset(fib); +} + +// Run the collatz conjecture as long as possible +{ + let val = 837799; // should reach 1 in 524 steps + let expr = `(i32.const ${val})\n`; + while (val != 1) { + if (val % 2 == 0) { + expr += `(i32.sub (i32.const ${val / 2}))\n`; // we can't divide in constant expressions lol + val /= 2; + } else { + expr += `(i32.mul (i32.const 3))\n`; + expr += `(i32.add (i32.const 1))\n`; + val = val * 3 + 1; + } + } + expr += `(i32.sub (i32.const 1))\n`; + testFancyZeroOffset(expr); +} + +// The collatz conjecture would be even more fun with 64-bit numbers... +if (wasmMemory64Enabled()) { + let val = 1899148184679; // should reach 1 in 1411 steps + let expr = `(i64.const ${val})\n`; + while (val != 1) { + if (val % 2 == 0) { + expr += `(i64.sub (i64.const ${val / 2}))\n`; // we can't divide in constant expressions lol + val /= 2; + } else { + expr += `(i64.mul (i64.const 3))\n`; + expr += `(i64.add (i64.const 1))\n`; + val = val * 3 + 1; + } + } + expr += `(i64.sub (i64.const 1))\n`; + testFancyZeroOffset(expr, 'i64'); +} |