Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1587050 - Adjust table.copy part 1. r=jseward
Browse files Browse the repository at this point in the history
  • Loading branch information
Lars T Hansen committed Oct 11, 2019
1 parent e8a3d33 commit 93aac07
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 30 deletions.
28 changes: 19 additions & 9 deletions js/src/jit-test/tests/wasm/gc/tables-fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@

const N = 8;

function testTableFill(type, obj) {
function testTableFill(tbl_type, val_type, obj) {
assertEq(obj.length, N);

let ins
= wasmEvalText(
`(module
(table 8 ${type}) ;; table 0
(table $t 10 ${type}) ;; table 1
(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 ${type}) (param $n i32)
(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 ${type})
(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 ${type}) (param $n i32)
(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 ${type})
(func (export "get1") (param $i i32) (result ${tbl_type})
(table.get $t (local.get $i))
)
)`);
Expand Down Expand Up @@ -133,12 +133,13 @@ function testTableFill(type, obj) {
var objs = [];
for (var i = 0; i < N; i++)
objs[i] = {n:i};
testTableFill('anyref', objs);
testTableFill('anyref', 'anyref', 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', funcs);
testTableFill('funcref', 'funcref', funcs);
testTableFill('anyref', 'funcref', funcs); // funcref <: anyref so implicit upcast on fill


// Type errors. Required sig is: (i32, anyref, i32) -> void
Expand Down Expand Up @@ -202,3 +203,12 @@ assertErrorMessage(() => wasmEvalText(
))`),
WebAssembly.CompileError,
/popping value from empty stack/);

assertErrorMessage(() => wasmEvalText(
`(module
(table 8 funcref)
(func (param $v anyref)
(table.fill (i32.const 0) (local.get $v) (i32.const 0)))
)`),
WebAssembly.CompileError,
/expression has type anyref but expected funcref/);
107 changes: 86 additions & 21 deletions js/src/jit-test/tests/wasm/gc/tables-generalized.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,52 @@ new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
assertEq(t.get(9), objs[9]);
}

// Wasm: element segments targeting table-of-anyref is forbidden
// Wasm: table.copy from table(funcref) to table(anyref) should work

{
let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
`(module
(table (export "t") 10 anyref)
(func $f1)
(func $f2)
(func $f3)
(func $f4)
(func $f5)
(table 5 funcref)
(elem (table 1) (i32.const 0) func $f1 $f2 $f3 $f4 $f5)
(func (export "f")
(table.copy 0 (i32.const 5) 1 (i32.const 0) (i32.const 5))))`)));
ins.exports.f();
let t = ins.exports.t;
let xs = [];
for (let i=0; i < 5; i++) {
xs[i] = t.get(i+5);
assertEq(typeof xs[i], "function");
}
for (let i=0; i < 5; i++) {
for (j=i+1; j < 5; j++)
assertEq(xs[i] != xs[j], true);
}
}

// Wasm: table.copy from table(anyref) to table(funcref) should not work

assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func $f1 (result i32) (i32.const 0))
(table 10 funcref)
(table 10 anyref)
(elem 0 (i32.const 0) func $f1))`)),
(func (export "f")
(table.copy 0 (i32.const 0) 1 (i32.const 0) (i32.const 5))))`)),
WebAssembly.CompileError,
/only tables of 'funcref' may have element segments/);
/expression has type anyref but expected funcref/);

// Wasm: table.init on table-of-anyref is forbidden
// Wasm: element segments targeting table-of-anyref is forbidden

assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func $f1 (result i32) (i32.const 0))
(table 10 anyref)
(elem func $f1)
(func
(table.init 0 (i32.const 0) (i32.const 0) (i32.const 0))))`)),
(elem 0 (i32.const 0) func $f1))`)),
WebAssembly.CompileError,
/only tables of 'funcref' may have element segments/);

Expand Down Expand Up @@ -197,24 +224,35 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
// table.set with null - works
// table.set out of bounds - fails

function testTableSet(type, x) {
function testTableSet(lhs_type, rhs_type, x) {
let ins = wasmEvalText(
`(module
(table (export "t") 10 ${type})
(func (export "set_anyref") (param i32) (param ${type})
(table (export "t") 10 ${lhs_type})
(func (export "set_ref") (param i32) (param ${rhs_type})
(table.set (local.get 0) (local.get 1)))
(func (export "set_null") (param i32)
(table.set (local.get 0) (ref.null))))`);
ins.exports.set_anyref(3, x);
ins.exports.set_ref(3, x);
assertEq(ins.exports.t.get(3), x);
ins.exports.set_null(3);
assertEq(ins.exports.t.get(3), null);

assertErrorMessage(() => ins.exports.set_anyref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_anyref(-1, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_ref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_ref(-1, x), RangeError, /index out of bounds/);
}
testTableSet('anyref', {});
testTableSet('funcref', wasmFun);
testTableSet('anyref', 'anyref', {});
testTableSet('funcref', 'funcref', wasmFun);
testTableSet('anyref', 'funcref', wasmFun);

// Wasm: table.set on table(funcref) with anyref value should fail

assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(table (export "t") 10 funcref)
(func (export "set_ref") (param i32) (param anyref)
(table.set (local.get 0) (local.get 1))))`)),
WebAssembly.CompileError,
/type mismatch: expression has type anyref but expected funcref/);

// table.set with non-i32 index - fails validation

Expand Down Expand Up @@ -252,13 +290,13 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/table index out of range for table.set/);

function testTableGrow(type, x) {
function testTableGrow(lhs_type, rhs_type, x) {
let ins = wasmEvalText(
`(module
(table (export "t") 10 20 ${type})
(table (export "t") 10 20 ${lhs_type})
(func (export "grow") (param i32) (result i32)
(table.grow (ref.null) (local.get 0)))
(func (export "grow2") (param i32) (param ${type}) (result i32)
(func (export "grow2") (param i32) (param ${rhs_type}) (result i32)
(table.grow (local.get 1) (local.get 0))))`);

// we can grow table of references
Expand Down Expand Up @@ -287,8 +325,19 @@ function testTableGrow(type, x) {
assertEq(ins.exports.grow(-1), -1);
assertEq(ins.exports.t.length, 20)
}
testTableGrow('anyref', 42);
testTableGrow('funcref', wasmFun);
testTableGrow('anyref', 'anyref', 42);
testTableGrow('funcref', 'funcref', wasmFun);
testTableGrow('anyref', 'funcref', wasmFun);

// Wasm: table.grow on table(funcref) with anyref initializer should fail

assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(table (export "t") 10 20 funcref)
(func (export "grow2") (param i32) (param anyref) (result i32)
(table.grow (local.get 1) (local.get 0))))`)),
WebAssembly.CompileError,
/type mismatch: expression has type anyref but expected funcref/);

// Special case for private tables without a maximum

Expand Down Expand Up @@ -410,3 +459,19 @@ let VALUES = [null,
t.grow(0, 1789);
assertEq(t.get(0), 1337);
}

// Currently 'anyref' segments are not allowed whether passive or active,
// though that will change

assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(elem (i32.const 0) anyref (ref.null)))`)),
SyntaxError,
/parsing wasm text/);


assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(elem anyref (ref.null)))`)),
SyntaxError,
/parsing wasm text/);

0 comments on commit 93aac07

Please sign in to comment.