326608fec5
Add tests for select, reject undefined globals for nullref and reformat JS R=ahaas@chromium.org Bug: chromium:10063 Change-Id: I97f7c86fe7435ca64ce1f4b86d8d9eadd29cc76b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2002531 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Emanuel Ziegler <ecmziegler@chromium.org> Cr-Commit-Position: refs/heads/master@{#65795}
401 lines
15 KiB
JavaScript
401 lines
15 KiB
JavaScript
// Copyright 2020 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --experimental-wasm-anyref --experimental-wasm-eh
|
|
|
|
load('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
let kSig_n_n = makeSig([kWasmNullRef], [kWasmNullRef]);
|
|
let kSig_r_n = makeSig([kWasmNullRef], [kWasmAnyRef]);
|
|
let kSig_a_n = makeSig([kWasmNullRef], [kWasmAnyFunc]);
|
|
let kSig_e_n = makeSig([kWasmNullRef], [kWasmExnRef]);
|
|
let kSig_n_v = makeSig([], [kWasmNullRef]);
|
|
let kSig_n_r = makeSig([kWasmAnyRef], [kWasmNullRef]);
|
|
let kSig_n_a = makeSig([kWasmAnyFunc], [kWasmNullRef]);
|
|
let kSig_n_e = makeSig([kWasmExnRef], [kWasmNullRef]);
|
|
let kSig_v_n = makeSig([kWasmNullRef], []);
|
|
let kSig_v_in = makeSig([kWasmI32, kWasmNullRef], []);
|
|
let kSig_n_i = makeSig([kWasmI32], [kWasmNullRef]);
|
|
let kSig_r_i = makeSig([kWasmI32], [kWasmAnyRef]);
|
|
let kSig_e_i = makeSig([kWasmI32], [kWasmExnRef]);
|
|
let kSig_n_nni = makeSig([kWasmNullRef, kWasmNullRef, kWasmI32], [kWasmNullRef]);
|
|
let kSig_r_nni = makeSig([kWasmNullRef, kWasmNullRef, kWasmI32], [kWasmAnyRef]);
|
|
let kSig_a_nni = makeSig([kWasmNullRef, kWasmNullRef, kWasmI32], [kWasmAnyFunc]);
|
|
let kSig_e_nni = makeSig([kWasmNullRef, kWasmNullRef, kWasmI32], [kWasmExnRef]);
|
|
|
|
(function testNullRefIdentityFunction() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
builder.addFunction('nullRef', kSig_n_n)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
builder.addFunction('anyRef', kSig_r_n)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
builder.addFunction('funcRef', kSig_a_n)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
builder.addFunction('exnRef', kSig_e_n)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
assertThrows(() => instance.exports.nullRef(a => a), TypeError);
|
|
assertThrows(() => instance.exports.nullRef(print), TypeError);
|
|
assertThrows(() => instance.exports.nullRef({'hello': 'world'}), TypeError);
|
|
assertEquals(null, instance.exports.nullRef(null));
|
|
assertEquals(null, instance.exports.anyRef(null));
|
|
assertEquals(null, instance.exports.funcRef(null));
|
|
assertEquals(null, instance.exports.exnRef(null));
|
|
})();
|
|
|
|
(function testNullRefFromAnyRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_r);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testNullRefFromFuncRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_a);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testNullRefFromExnRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_e);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testNullRefDefaultValue() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addLocals({nullref_count: 1})
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
const main = builder.instantiate().exports.main;
|
|
assertEquals(null, main());
|
|
})();
|
|
|
|
(function testNullRefFromAnyRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addLocals({anyref_count: 1})
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testNullRefFromFuncRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addLocals({anyfunc_count: 1})
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testNullRefFromExnRefFail() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addLocals({exnref_count: 1})
|
|
.addBody([kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
|
|
})();
|
|
|
|
(function testAssignNullRefToNullRefLocal() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_n);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprRefNull, kExprLocalSet, 0, kExprLocalGet, 0])
|
|
.exportFunc();
|
|
|
|
const main = builder.instantiate().exports.main;
|
|
assertEquals(null, main(null));
|
|
})();
|
|
|
|
(function testImplicitReturnNullRefAsNullRef() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprRefNull])
|
|
.exportFunc();
|
|
|
|
const main = builder.instantiate().exports.main;
|
|
assertEquals(null, main());
|
|
})();
|
|
|
|
(function testExplicitReturnNullRefAsNullRef() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const sig_index = builder.addType(kSig_n_v);
|
|
builder.addFunction('main', sig_index)
|
|
.addBody([kExprRefNull, kExprReturn])
|
|
.exportFunc();
|
|
|
|
const main = builder.instantiate().exports.main;
|
|
assertEquals(null, main());
|
|
})();
|
|
|
|
(function testGetNullRefGlobal() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const initialized = builder.addGlobal(kWasmNullRef, true)
|
|
.exportAs('initialized');
|
|
initialized.init = null;
|
|
const uninitialized = builder.addGlobal(kWasmNullRef, true)
|
|
.exportAs('uninitialized');
|
|
const sig_n_v = builder.addType(kSig_n_v);
|
|
const sig_v_n = builder.addType(kSig_v_n);
|
|
const sig_v_v = builder.addType(kSig_v_v);
|
|
builder.addFunction('get_initialized', sig_n_v)
|
|
.addBody([kExprGlobalGet, initialized.index])
|
|
.exportFunc();
|
|
builder.addFunction('get_uninitialized', sig_n_v)
|
|
.addBody([kExprGlobalGet, initialized.index])
|
|
.exportFunc();
|
|
builder.addFunction('set_initialized', sig_v_n)
|
|
.addBody([kExprLocalGet, 0, kExprGlobalSet, initialized.index])
|
|
.exportFunc();
|
|
builder.addFunction('reset_initialized', sig_v_v)
|
|
.addBody([kExprRefNull, kExprGlobalSet, initialized.index])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
assertTrue(instance.exports.initialized instanceof WebAssembly.Global);
|
|
assertTrue(instance.exports.uninitialized instanceof WebAssembly.Global);
|
|
assertEquals(instance.exports.initialized.value, null);
|
|
assertEquals(instance.exports.uninitialized.value, null);
|
|
assertEquals(null, instance.exports.get_initialized());
|
|
assertEquals(null, instance.exports.get_uninitialized());
|
|
|
|
instance.exports.set_initialized(null);
|
|
assertEquals(instance.exports.initialized.value, null);
|
|
assertEquals(null, instance.exports.get_initialized());
|
|
|
|
instance.exports.reset_initialized();
|
|
assertEquals(instance.exports.initialized.value, null);
|
|
assertEquals(null, instance.exports.get_initialized());
|
|
})();
|
|
|
|
(function testGetNullRefImportedGlobal() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const global_index = builder.addImportedGlobal("foo", "bar",
|
|
kWasmNullRef);
|
|
const sig_n_v = builder.addType(kSig_n_v);
|
|
const sig_v_n = builder.addType(kSig_v_n);
|
|
const sig_v_v = builder.addType(kSig_v_v);
|
|
builder.addFunction('get', sig_n_v)
|
|
.addBody([kExprGlobalGet, global_index])
|
|
.exportFunc();
|
|
|
|
assertThrows(() => builder.instantiate(), TypeError);
|
|
assertThrows(() => builder.instantiate({foo: {}}), WebAssembly.LinkError);
|
|
assertThrows(() => builder.instantiate({foo: {bar: {}}}),
|
|
WebAssembly.LinkError);
|
|
assertThrows(() => builder.instantiate({foo: {bar: a => a}}),
|
|
WebAssembly.LinkError);
|
|
|
|
const instance = builder.instantiate({foo: {bar: null}});
|
|
assertEquals(null, instance.exports.get());
|
|
})();
|
|
|
|
(function testNullRefTable() {
|
|
print(arguments.callee.name);
|
|
let table = new WebAssembly.Table({element: "nullref", initial: 2});
|
|
|
|
assertEquals(null, table.get(0));
|
|
table.set(1, null);
|
|
assertEquals(null, table.get(1));
|
|
assertThrows(() => table.set(2, null), RangeError);
|
|
|
|
table.grow(2);
|
|
|
|
assertEquals(null, table.get(2));
|
|
table.set(3, null);
|
|
assertEquals(null, table.get(3));
|
|
assertThrows(() => table.set(4, null), RangeError);
|
|
|
|
assertThrows(() => table.set(0, {}), TypeError);
|
|
assertThrows(() => table.set(0, a => a), TypeError);
|
|
})();
|
|
|
|
(function testAddNullRefTable() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const table = builder.addTable(kWasmNullRef, 3, 10);
|
|
builder.addFunction('set_null', kSig_v_i)
|
|
.addBody([kExprLocalGet, 0, kExprRefNull, kExprTableSet, table.index])
|
|
.exportFunc();
|
|
builder.addFunction('set', kSig_v_in)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprTableSet, table.index])
|
|
.exportFunc();
|
|
builder.addFunction('get_null', kSig_n_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
|
|
.exportFunc();
|
|
builder.addFunction('get_any', kSig_r_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
|
|
.exportFunc();
|
|
builder.addFunction('get_func', kSig_a_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
|
|
.exportFunc();
|
|
builder.addFunction('get_exn', kSig_e_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
instance.exports.set_null(1);
|
|
instance.exports.set(2, null);
|
|
|
|
assertEquals(null, instance.exports.get_null(0));
|
|
assertEquals(null, instance.exports.get_null(1));
|
|
assertEquals(null, instance.exports.get_null(2));
|
|
assertEquals(null, instance.exports.get_any(0));
|
|
assertEquals(null, instance.exports.get_any(1));
|
|
assertEquals(null, instance.exports.get_any(2));
|
|
assertEquals(null, instance.exports.get_func(0));
|
|
assertEquals(null, instance.exports.get_func(1));
|
|
assertEquals(null, instance.exports.get_func(2));
|
|
assertEquals(null, instance.exports.get_exn(0));
|
|
assertEquals(null, instance.exports.get_exn(1));
|
|
assertEquals(null, instance.exports.get_exn(2));
|
|
})();
|
|
|
|
(function testImportNullRefTable() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const table_index = builder.addImportedTable("imp", "table", 2, 10,
|
|
kWasmNullRef);
|
|
builder.addFunction('get_null', kSig_n_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table_index])
|
|
.exportFunc();
|
|
builder.addFunction('get_any', kSig_r_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table_index])
|
|
.exportFunc();
|
|
builder.addFunction('get_func', kSig_a_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table_index])
|
|
.exportFunc();
|
|
builder.addFunction('get_exn', kSig_e_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, table_index])
|
|
.exportFunc();
|
|
|
|
let table_func = new WebAssembly.Table({element: "anyfunc", initial: 2,
|
|
maximum: 10});
|
|
assertThrows(() => builder.instantiate({imp: {table: table_func}}),
|
|
WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
let table_any = new WebAssembly.Table({element: "anyref", initial: 2,
|
|
maximum: 10});
|
|
assertThrows(() => builder.instantiate({imp: {table: table_any}}),
|
|
WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
let table_null = new WebAssembly.Table({element: "nullref", initial: 2,
|
|
maximum: 10});
|
|
table_null.set(1, null);
|
|
const instance = builder.instantiate({imp: {table: table_null}});
|
|
|
|
assertEquals(null, instance.exports.get_null(0));
|
|
assertEquals(null, instance.exports.get_null(1));
|
|
assertEquals(null, instance.exports.get_any(0));
|
|
assertEquals(null, instance.exports.get_any(1));
|
|
assertEquals(null, instance.exports.get_func(0));
|
|
assertEquals(null, instance.exports.get_func(1));
|
|
assertEquals(null, instance.exports.get_exn(0));
|
|
assertEquals(null, instance.exports.get_exn(1));
|
|
|
|
assertThrows(() => instance.exports.get_null(2), WebAssembly.RuntimeError);
|
|
table_null.grow(1);
|
|
assertEquals(null, instance.exports.get_null(2));
|
|
})();
|
|
|
|
(function testImportNullRefTableIntoAnyRefTable() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
const table_index = builder.addImportedTable("imp", "table", 2, 10,
|
|
kWasmAnyRef);
|
|
builder.addFunction('get', kSig_r_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table_index])
|
|
.exportFunc();
|
|
|
|
let table_null = new WebAssembly.Table({element: "nullref", initial: 2,
|
|
maximum: 10});
|
|
assertThrows(() => builder.instantiate({imp: {table: table_null}}),
|
|
WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
})();
|
|
|
|
(function testSelectNullRef() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
builder.addFunction('select_null', kSig_n_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmNullRef])
|
|
.exportFunc();
|
|
builder.addFunction('select_any', kSig_r_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmAnyRef])
|
|
.exportFunc();
|
|
builder.addFunction('select_func', kSig_a_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmAnyFunc])
|
|
.exportFunc();
|
|
builder.addFunction('select_exn', kSig_e_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmExnRef])
|
|
.exportFunc();
|
|
builder.addFunction('select_null_as_any', kSig_r_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmNullRef])
|
|
.exportFunc();
|
|
builder.addFunction('select_null_as_func', kSig_a_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmNullRef])
|
|
.exportFunc();
|
|
builder.addFunction('select_null_as_exn', kSig_e_nni)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
|
|
kExprSelectWithType, 1, kWasmNullRef])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
assertEquals(null, instance.exports.select_null(null, null, 0));
|
|
assertEquals(null, instance.exports.select_any(null, null, 0));
|
|
assertEquals(null, instance.exports.select_func(null, null, 0));
|
|
assertEquals(null, instance.exports.select_exn(null, null, 0));
|
|
assertEquals(null, instance.exports.select_null_as_any(null, null, 0));
|
|
assertEquals(null, instance.exports.select_null_as_func(null, null, 0));
|
|
assertEquals(null, instance.exports.select_null_as_exn(null, null, 0));
|
|
})();
|