diff options
Diffstat (limited to 'js/src/jit-test/tests/wasm/ref-types/tables-fill.js')
-rw-r--r-- | js/src/jit-test/tests/wasm/ref-types/tables-fill.js | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/ref-types/tables-fill.js b/js/src/jit-test/tests/wasm/ref-types/tables-fill.js new file mode 100644 index 0000000000..b6b821f1d0 --- /dev/null +++ b/js/src/jit-test/tests/wasm/ref-types/tables-fill.js @@ -0,0 +1,212 @@ +const N = 8; + +function testTableFill(tbl_type, val_type, obj) { + assertEq(obj.length, N); + + let ins + = wasmEvalText( + `(module + (table 8 ${tbl_type}) ;; table 0 + (table $t 10 ${tbl_type}) ;; table 1 + + ;; fill/get for table 0, referenced implicitly + (func (export "fill0") (param $i i32) (param $r ${val_type}) (param $n i32) + (table.fill (local.get $i) (local.get $r) (local.get $n)) + ) + (func (export "get0") (param $i i32) (result ${tbl_type}) + (table.get (local.get $i)) + ) + + ;; fill/get for table 1, referenced explicitly + (func (export "fill1") (param $i i32) (param $r ${val_type}) (param $n i32) + (table.fill $t (local.get $i) (local.get $r) (local.get $n)) + ) + (func (export "get1") (param $i i32) (result ${tbl_type}) + (table.get $t (local.get $i)) + ) + )`); + + // An initial test to ascertain that tables 0 and 1 are independent + + // Fill in table 0, then check it. + assertEq(ins.exports.fill0(2, obj[6], 5), undefined) + assertEq(ins.exports.fill0(1, obj[7], 3), undefined); + + function check_table0() { + assertEq(ins.exports.get0(0), null); + assertEq(ins.exports.get0(1), obj[7]); + assertEq(ins.exports.get0(2), obj[7]); + assertEq(ins.exports.get0(3), obj[7]); + assertEq(ins.exports.get0(4), obj[6]); + assertEq(ins.exports.get0(5), obj[6]); + assertEq(ins.exports.get0(6), obj[6]); + assertEq(ins.exports.get0(7), null); + } + + // Check that table 0 has the expected content. + check_table0(); + + // Check that messing with table 0 above hasn't changed table 1. + for (let i = 0; i < 10; i++) { + assertEq(ins.exports.get1(i), null); + } + + // Now a bunch of tests involving only table 1. + + // Partly outside the table + assertErrorMessage(() => ins.exports.fill1(8, obj[5], 3), + WebAssembly.RuntimeError, /index out of bounds/); + + assertEq(ins.exports.get1(7), null); + assertEq(ins.exports.get1(8), null); + assertEq(ins.exports.get1(9), null); + + // Within the table + assertEq(ins.exports.fill1(2, obj[0], 3), undefined); + assertEq(ins.exports.get1(1), null); + assertEq(ins.exports.get1(2), obj[0]); + assertEq(ins.exports.get1(3), obj[0]); + assertEq(ins.exports.get1(4), obj[0]); + assertEq(ins.exports.get1(5), null); + + // Within the table + assertEq(ins.exports.fill1(4, obj[1], 2), undefined); + assertEq(ins.exports.get1(3), obj[0]); + assertEq(ins.exports.get1(4), obj[1]); + assertEq(ins.exports.get1(5), obj[1]); + assertEq(ins.exports.get1(6), null); + + // Within the table + assertEq(ins.exports.fill1(4, obj[2], 0), undefined); + assertEq(ins.exports.get1(3), obj[0]); + assertEq(ins.exports.get1(4), obj[1]); + assertEq(ins.exports.get1(5), obj[1]); + + // Within the table + assertEq(ins.exports.fill1(8, obj[3], 2), undefined); + assertEq(ins.exports.get1(7), null); + assertEq(ins.exports.get1(8), obj[3]); + assertEq(ins.exports.get1(9), obj[3]); + + // Within the table + assertEq(ins.exports.fill1(9, null, 1), undefined); + assertEq(ins.exports.get1(8), obj[3]); + assertEq(ins.exports.get1(9), null); + + // Within the table + assertEq(ins.exports.fill1(10, obj[4], 0), undefined); + assertEq(ins.exports.get1(9), null); + + // Boundary tests on table 1: at the edge of the table. + + // Length-zero fill1 at the edge of the table must succeed + assertEq(ins.exports.fill1(10, null, 0), undefined); + + // Length-one fill1 at the edge of the table fails + assertErrorMessage(() => ins.exports.fill1(10, null, 1), + WebAssembly.RuntimeError, /index out of bounds/); + + // Length-more-than-one fill1 at the edge of the table fails + assertErrorMessage(() => ins.exports.fill1(10, null, 2), + WebAssembly.RuntimeError, /index out of bounds/); + + + // Boundary tests on table 1: beyond the edge of the table: + + // Length-zero fill1 beyond the edge of the table fails + assertErrorMessage(() => ins.exports.fill1(11, null, 0), + WebAssembly.RuntimeError, /index out of bounds/); + + // Length-one fill1 beyond the edge of the table fails + assertErrorMessage(() => ins.exports.fill1(11, null, 1), + WebAssembly.RuntimeError, /index out of bounds/); + + // Length-more-than-one fill1 beyond the edge of the table fails + assertErrorMessage(() => ins.exports.fill1(11, null, 2), + WebAssembly.RuntimeError, /index out of bounds/); + + // Following all the above tests on table 1, check table 0 hasn't changed. + check_table0(); +} + +var objs = []; +for (var i = 0; i < N; i++) + objs[i] = {n:i}; +testTableFill('externref', 'externref', objs); + +var funcs = []; +for (var i = 0; i < N; i++) + funcs[i] = wasmEvalText(`(module (func (export "x") (result i32) (i32.const ${i})))`).exports.x; +testTableFill('funcref', 'funcref', funcs); + + +// Type errors. Required sig is: (i32, externref, i32) -> void + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $expected-3-args-got-0 + (table.fill $t) + ))`), + WebAssembly.CompileError, /(popping value from empty stack)|(nothing on stack)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $expected-3-args-got-1 + (table.fill $t (i32.const 0)) + ))`), + WebAssembly.CompileError, /(popping value from empty stack)|(nothing on stack)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $expected-3-args-got-2 + (table.fill $t (ref.null extern) (i32.const 0)) + ))`), + WebAssembly.CompileError, /(popping value from empty stack)|(nothing on stack)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $argty-1-wrong + (table.fill $t (i32.const 0) (ref.null extern) (f64.const 0)) + ))`), + WebAssembly.CompileError, + /(type mismatch: expression has type f64 but expected i32)|(type mismatch: expected i32, found f64)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $argty-2-wrong + (table.fill $t (i32.const 0) (f32.const 0) (i32.const 0)) + ))`), + WebAssembly.CompileError, + /(type mismatch: expression has type f32 but expected externref)|(type mismatch: expected externref, found f32)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $argty-3-wrong + (table.fill $t (i64.const 0) (ref.null extern) (i32.const 0)) + ))`), + WebAssembly.CompileError, + /(type mismatch: expression has type i64 but expected i32)|(type mismatch: expected i32, found i64)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table $t 10 externref) + (func $retty-wrong (result i32) + (table.fill $t (i32.const 0) (ref.null extern) (i32.const 0)) + ))`), + WebAssembly.CompileError, + /(popping value from empty stack)|(nothing on stack)/); + +assertErrorMessage(() => wasmEvalText( + `(module + (table 8 funcref) + (func (param $v externref) + (table.fill (i32.const 0) (local.get $v) (i32.const 0))) + )`), + WebAssembly.CompileError, + /(expression has type externref but expected funcref)|(type mismatch: expected funcref, found externref)/); |