v8/test/mjsunit/wasm/nullref.js
Emanuel Ziegler 326608fec5 [wasm][reference-types] Additional nullref changes
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}
2020-01-15 16:22:49 +00:00

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));
})();