168fcef9b0
Bug: v8:7748 Change-Id: I4057a9288fe3d2dc0df308ce51be92e417572bd1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3865483 Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Commit-Queue: Matthias Liedtke <mliedtke@chromium.org> Cr-Commit-Position: refs/heads/main@{#82871}
547 lines
19 KiB
JavaScript
547 lines
19 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-gc
|
|
|
|
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
|
(function TestTables() {
|
|
print(arguments.callee.name);
|
|
var exporting_instance = (function() {
|
|
var builder = new WasmModuleBuilder();
|
|
var binary_type = builder.addType(kSig_i_ii);
|
|
|
|
builder.addFunction('addition', kSig_i_ii)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
|
|
.exportFunc();
|
|
|
|
builder.addFunction('succ', kSig_i_i)
|
|
.addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add])
|
|
.exportFunc();
|
|
|
|
builder.addTable(wasmRefNullType(binary_type), 1, 100).exportAs('table');
|
|
|
|
return builder.instantiate({});
|
|
})();
|
|
|
|
// Wrong type for imported table.
|
|
assertThrows(() => {
|
|
var builder = new WasmModuleBuilder();
|
|
var unary_type = builder.addType(kSig_i_i);
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefNullType(unary_type));
|
|
builder.instantiate({imports: {table: exporting_instance.exports.table}})
|
|
}, WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
// Type for imported table must match exactly.
|
|
assertThrows(() => {
|
|
var builder = new WasmModuleBuilder();
|
|
builder.addImportedTable('imports', 'table', 1, 100, kWasmFuncRef);
|
|
builder.instantiate({imports: {table: exporting_instance.exports.table}})
|
|
}, WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
var instance = (function() {
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
var unary_type = builder.addType(kSig_i_i);
|
|
var binary_type = builder.addType(kSig_i_ii);
|
|
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefNullType(binary_type));
|
|
|
|
var table =
|
|
builder.addTable(wasmRefNullType(unary_type), 10).exportAs('table');
|
|
builder.addTable(kWasmFuncRef, 1).exportAs('generic_table');
|
|
|
|
builder
|
|
.addFunction(
|
|
'table_test', makeSig([wasmRefType(unary_type)], [kWasmI32]))
|
|
// Set table[0] to input function, then retrieve it and call it.
|
|
.addBody([
|
|
kExprI32Const, 0, kExprLocalGet, 0, kExprTableSet, table.index,
|
|
kExprI32Const, 42, kExprI32Const, 0, kExprTableGet, table.index,
|
|
kExprCallRef, unary_type,
|
|
])
|
|
.exportFunc();
|
|
|
|
// Same, but with table[1] and call_indirect
|
|
builder
|
|
.addFunction(
|
|
'table_indirect_test',
|
|
makeSig([wasmRefType(unary_type)], [kWasmI32]))
|
|
.addBody([
|
|
kExprI32Const, 1, kExprLocalGet, 0, kExprTableSet, table.index,
|
|
kExprI32Const, 42, kExprI32Const, 0, kExprCallIndirect, unary_type,
|
|
table.index
|
|
])
|
|
.exportFunc();
|
|
|
|
// Instantiate with a table of the correct type.
|
|
return builder.instantiate(
|
|
{imports: {table: exporting_instance.exports.table}});
|
|
})();
|
|
|
|
// This module is valid.
|
|
assertTrue(!!instance);
|
|
|
|
// The correct function reference is preserved when setting it to and getting
|
|
// it back from a table.
|
|
assertEquals(
|
|
43, instance.exports.table_test(exporting_instance.exports.succ));
|
|
// Same for call indirect (the indirect call tables are also set correctly).
|
|
assertEquals(
|
|
43,
|
|
instance.exports.table_indirect_test(exporting_instance.exports.succ));
|
|
|
|
// Setting from JS API respects types.
|
|
instance.exports.generic_table.set(0, exporting_instance.exports.succ);
|
|
instance.exports.table.set(0, exporting_instance.exports.succ);
|
|
assertThrows(
|
|
() => instance.exports.table.set(0, exporting_instance.exports.addition),
|
|
TypeError,
|
|
/Argument 1 is invalid for table of type \(ref null 0\)/);
|
|
})();
|
|
|
|
(function TestNonNullableTables() {
|
|
print(arguments.callee.name);
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
var binary_type = builder.addType(kSig_i_ii);
|
|
|
|
var addition = builder.addFunction('addition', binary_type).addBody([
|
|
kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add
|
|
]);
|
|
var subtraction =
|
|
builder.addFunction('subtraction', binary_type)
|
|
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Sub])
|
|
.exportFunc();
|
|
|
|
var table = builder.addTable(wasmRefType(binary_type), 3, 3,
|
|
[kExprRefFunc, addition.index]);
|
|
|
|
builder.addFunction('init', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 1, kExprRefFunc, subtraction.index, kExprTableSet,
|
|
table.index
|
|
])
|
|
.exportFunc();
|
|
|
|
// (index, arg1, arg2) -> table[index](arg1, arg2)
|
|
builder.addFunction('table_test', kSig_i_iii)
|
|
.addBody([
|
|
kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, kExprCallIndirect,
|
|
binary_type, table.index
|
|
])
|
|
.exportFunc();
|
|
|
|
var instance = builder.instantiate({});
|
|
|
|
assertTrue(!!instance);
|
|
|
|
instance.exports.init();
|
|
assertEquals(44, instance.exports.table_test(0, 33, 11));
|
|
assertEquals(22, instance.exports.table_test(1, 33, 11));
|
|
})();
|
|
|
|
(function TestAnyRefTable() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let array_type = builder.addArray(kWasmI32);
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
|
|
let table = builder.addTable(kWasmAnyRef, 4, 4);
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI32Const(111), ...wasmI32Const(222),
|
|
kGCPrefix, kExprArrayNewFixed, array_type, 2],
|
|
[...wasmI32Const(-31), kGCPrefix, kExprI31New],
|
|
[...wasmI32Const(10), kGCPrefix, kExprStructNew, struct_type],
|
|
[kExprRefNull, kEqRefCode]],
|
|
kWasmAnyRef);
|
|
|
|
// return ...static_cast<array_type>(table[0])
|
|
builder.addFunction("array_getter", kSig_ii_v)
|
|
.addLocals(wasmRefNullType(array_type), 1)
|
|
.addBody([
|
|
kExprI32Const, 0, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsArray,
|
|
kGCPrefix, kExprRefCast, array_type,
|
|
kExprLocalSet, 0,
|
|
kExprLocalGet, 0,
|
|
...wasmI32Const(0), kGCPrefix, kExprArrayGet, array_type,
|
|
kExprLocalGet, 0,
|
|
...wasmI32Const(1), kGCPrefix, kExprArrayGet, array_type])
|
|
.exportFunc();
|
|
|
|
// return static_cast<i31>(table[1])
|
|
builder.addFunction("i31_getter", kSig_i_v)
|
|
.addBody([
|
|
kExprI32Const, 1, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsI31,
|
|
kGCPrefix, kExprI31GetS])
|
|
.exportFunc();
|
|
|
|
// return static_cast<struct_type>(table[2]).field_0
|
|
builder.addFunction("struct_getter", kSig_i_v)
|
|
.addBody([
|
|
kExprI32Const, 2, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsData, kGCPrefix, kExprRefCast, struct_type,
|
|
kGCPrefix, kExprStructGet, struct_type, 0])
|
|
.exportFunc();
|
|
|
|
// return table[3] == null
|
|
builder.addFunction("null_getter", kSig_i_v)
|
|
.addBody([kExprI32Const, 3, kExprTableGet, 0, kExprRefIsNull])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({});
|
|
|
|
assertTrue(!!instance);
|
|
|
|
assertEquals([111, 222], instance.exports.array_getter());
|
|
assertEquals(-31, instance.exports.i31_getter());
|
|
assertEquals(10, instance.exports.struct_getter());
|
|
assertEquals(1, instance.exports.null_getter());
|
|
})();
|
|
|
|
(function TestAnyRefTableNotNull() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let array_type = builder.addArray(kWasmI32);
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
|
|
let table = builder.addTable(wasmRefType(kWasmAnyRef), 3, 6,
|
|
[...wasmI32Const(111), ...wasmI32Const(222),
|
|
kGCPrefix, kExprArrayNewFixed, array_type, 2])
|
|
.exportAs("table");
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI32Const(111), ...wasmI32Const(222),
|
|
kGCPrefix, kExprArrayNewFixed, array_type, 2],
|
|
[...wasmI32Const(-31), kGCPrefix, kExprI31New],
|
|
[...wasmI32Const(10), kGCPrefix, kExprStructNew, struct_type]],
|
|
wasmRefType(kWasmAnyRef));
|
|
|
|
// return ...cast<array_type>(table.get(0))
|
|
builder.addFunction("array_getter", kSig_ii_v)
|
|
.addLocals(wasmRefNullType(array_type), 1)
|
|
.addBody([
|
|
kExprI32Const, 0, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsArray,
|
|
kGCPrefix, kExprRefCast, array_type,
|
|
kExprLocalSet, 0,
|
|
kExprLocalGet, 0,
|
|
...wasmI32Const(0), kGCPrefix, kExprArrayGet, array_type,
|
|
kExprLocalGet, 0,
|
|
...wasmI32Const(1), kGCPrefix, kExprArrayGet, array_type])
|
|
.exportFunc();
|
|
|
|
// return cast<i31>(table.get(1))
|
|
builder.addFunction("i31_getter", kSig_i_v)
|
|
.addBody([
|
|
kExprI32Const, 1, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsI31,
|
|
kGCPrefix, kExprI31GetS])
|
|
.exportFunc();
|
|
|
|
// return cast<struct_type>(table.get(param<0>))[0]
|
|
builder.addFunction("struct_getter", kSig_i_i)
|
|
.addBody([
|
|
kExprLocalGet, 0, kExprTableGet, 0,
|
|
kGCPrefix, kExprRefAsData, kGCPrefix, kExprRefCast, struct_type,
|
|
kGCPrefix, kExprStructGet, struct_type, 0])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("grow_table", kSig_v_v)
|
|
.addBody([
|
|
...wasmI32Const(20), kGCPrefix, kExprStructNew, struct_type,
|
|
kExprI32Const, 1,
|
|
kNumericPrefix, kExprTableGrow, 0,
|
|
kExprDrop,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("create_struct", makeSig([kWasmI32], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprStructNew, struct_type,
|
|
kGCPrefix, kExprExternExternalize,
|
|
])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({});
|
|
let wasmTable = instance.exports.table;
|
|
|
|
assertEquals([111, 222], instance.exports.array_getter());
|
|
assertEquals(-31, instance.exports.i31_getter());
|
|
assertEquals(10, instance.exports.struct_getter(2));
|
|
assertTraps(kTrapTableOutOfBounds, () => instance.exports.struct_getter(3));
|
|
instance.exports.grow_table();
|
|
assertEquals(20, instance.exports.struct_getter(3));
|
|
assertThrows(() => wasmTable.grow(1), TypeError,
|
|
/Argument 1 must be specified for non-nullable element type/);
|
|
wasmTable.grow(1, instance.exports.create_struct(33));
|
|
assertEquals(33, instance.exports.struct_getter(4));
|
|
assertThrows(() => wasmTable.set(4, undefined), TypeError,
|
|
/Argument 1 is invalid/);
|
|
assertThrows(() => wasmTable.set(4, null), TypeError,
|
|
/Argument 1 is invalid/);
|
|
})();
|
|
|
|
(function TestStructRefTable() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
|
|
let table = builder.addTable(wasmRefNullType(struct_type), 4, 4);
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI32Const(10), kGCPrefix, kExprStructNew, struct_type],
|
|
[...wasmI32Const(11), kGCPrefix, kExprStructNew, struct_type],
|
|
[kExprRefNull, struct_type]],
|
|
wasmRefNullType(struct_type));
|
|
|
|
builder.addFunction("struct_getter", kSig_i_i)
|
|
.addBody([
|
|
kExprLocalGet, 0, kExprTableGet, 0,
|
|
kGCPrefix, kExprStructGet, struct_type, 0])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("null_getter", kSig_i_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, 0, kExprRefIsNull])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({});
|
|
assertTrue(!!instance);
|
|
|
|
assertEquals(10, instance.exports.struct_getter(0));
|
|
assertEquals(11, instance.exports.struct_getter(1));
|
|
assertEquals(1, instance.exports.null_getter(2));
|
|
})();
|
|
|
|
(function TestArrayRefTable() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let array_type = builder.addArray(kWasmI32);
|
|
|
|
let table = builder.addTable(wasmRefNullType(array_type), 4, 4);
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI32Const(10), ...wasmI32Const(11), ...wasmI32Const(12),
|
|
kGCPrefix, kExprArrayNewFixed, array_type, 3],
|
|
[kGCPrefix, kExprArrayNewFixed, array_type, 0],
|
|
[kExprRefNull, array_type]],
|
|
wasmRefNullType(array_type));
|
|
|
|
builder.addFunction("array_getter", kSig_i_ii)
|
|
.addBody([
|
|
kExprLocalGet, 0, kExprTableGet, 0,
|
|
kExprLocalGet, 1,
|
|
kGCPrefix, kExprArrayGet, array_type])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("null_getter", kSig_i_i)
|
|
.addBody([kExprLocalGet, 0, kExprTableGet, 0, kExprRefIsNull])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({});
|
|
assertTrue(!!instance);
|
|
|
|
assertEquals(10, instance.exports.array_getter(0, 0));
|
|
assertEquals(11, instance.exports.array_getter(0, 1));
|
|
assertEquals(12, instance.exports.array_getter(0, 2));
|
|
assertEquals(0, instance.exports.null_getter(1));
|
|
assertTraps(kTrapArrayOutOfBounds,
|
|
() => instance.exports.array_getter(1, 0));
|
|
assertEquals(1, instance.exports.null_getter(2));
|
|
})();
|
|
|
|
(function TestRefTableInvalidSegmentType() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let struct_type_a = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let struct_type_b = builder.addStruct([makeField(kWasmI64, false)]);
|
|
|
|
let table = builder.addTable(wasmRefNullType(struct_type_a), 4, 4);
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI32Const(10), kGCPrefix, kExprStructNew, struct_type_b]],
|
|
wasmRefNullType(struct_type_b)); // Mismatches table type.
|
|
|
|
assertThrows(() => builder.instantiate({}),
|
|
WebAssembly.CompileError,
|
|
/Element segment .* is not a subtype of referenced table/);
|
|
})();
|
|
|
|
(function TestRefTableInvalidSegmentExpressionType() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let struct_type_a = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let struct_type_b = builder.addStruct([makeField(kWasmI64, false)]);
|
|
|
|
let table = builder.addTable(wasmRefNullType(struct_type_a), 4, 4);
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(0),
|
|
[[...wasmI64Const(10), kGCPrefix, kExprStructNew, struct_type_b]],
|
|
wasmRefNullType(struct_type_a));
|
|
|
|
assertThrows(() => builder.instantiate({}),
|
|
WebAssembly.CompileError,
|
|
/expected \(ref null 0\), got \(ref 1\)/);
|
|
})();
|
|
|
|
(function TestMultiModuleRefTableEquivalentTypes() {
|
|
print(arguments.callee.name);
|
|
let exporting_instance = (() => {
|
|
let builder = new WasmModuleBuilder();
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
builder.addTable(wasmRefNullType(struct_type), 1, 100).exportAs('table');
|
|
return builder.instantiate({});
|
|
})();
|
|
|
|
// Mismatching struct definition.
|
|
assertThrows(() => {
|
|
let builder = new WasmModuleBuilder();
|
|
let struct_type = builder.addStruct([makeField(kWasmI64, false)]);
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefNullType(struct_type));
|
|
builder.instantiate({imports: {table: exporting_instance.exports.table}})
|
|
}, WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
// Mismatching nullability.
|
|
assertThrows(() => {
|
|
let builder = new WasmModuleBuilder();
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefType(struct_type));
|
|
builder.instantiate({imports: {table: exporting_instance.exports.table}})
|
|
}, WebAssembly.LinkError, /imported table does not match the expected type/);
|
|
|
|
// Equivalent struct type.
|
|
let builder = new WasmModuleBuilder();
|
|
// Force type canonicalization for struct_type
|
|
builder.setSingletonRecGroups();
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let struct_type_invalid = builder.addStruct([makeField(kWasmI64, false)]);
|
|
let struct_type_sub = builder.addStruct(
|
|
[makeField(kWasmI32, false), makeField(kWasmI32, false)], struct_type);
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefNullType(struct_type));
|
|
|
|
builder.addFunction("invalid_struct", makeSig([], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprI64Const, 44,
|
|
kGCPrefix, kExprStructNew, struct_type_invalid,
|
|
kGCPrefix, kExprExternExternalize])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("valid_struct", makeSig([], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprI32Const, 44,
|
|
kGCPrefix, kExprStructNew, struct_type,
|
|
kGCPrefix, kExprExternExternalize])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("valid_struct_sub", makeSig([], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprI32Const, 55,
|
|
kExprI32Const, 66,
|
|
kGCPrefix, kExprStructNew, struct_type_sub,
|
|
kGCPrefix, kExprExternExternalize])
|
|
.exportFunc();
|
|
|
|
let table = exporting_instance.exports.table;
|
|
let instance = builder.instantiate({imports: {table}});
|
|
|
|
table.grow(5, undefined);
|
|
assertThrows(() => table.set(1, instance.exports.invalid_struct()),
|
|
TypeError);
|
|
table.set(1, instance.exports.valid_struct());
|
|
table.set(2, instance.exports.valid_struct_sub());
|
|
table.set(3, null);
|
|
assertThrows(() => table.set(1, undefined),
|
|
TypeError);
|
|
})();
|
|
|
|
(function TestMultiModuleRefTableSuperType() {
|
|
print(arguments.callee.name);
|
|
let exporting_instance = (() => {
|
|
let builder = new WasmModuleBuilder();
|
|
builder.setSingletonRecGroups();
|
|
let struct_type_base = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let struct_type =
|
|
builder.addStruct([makeField(kWasmI32, false)], struct_type_base);
|
|
builder.addTable(wasmRefNullType(struct_type), 1, 100).exportAs('table');
|
|
return builder.instantiate({});
|
|
})();
|
|
|
|
let builder = new WasmModuleBuilder();
|
|
builder.setSingletonRecGroups();
|
|
let struct_type_base = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let struct_type =
|
|
builder.addStruct([makeField(kWasmI32, false)], struct_type_base);
|
|
builder.addImportedTable(
|
|
'imports', 'table', 1, 100, wasmRefNullType(struct_type));
|
|
|
|
builder.addFunction("struct_base", makeSig([], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprI32Const, 66,
|
|
kGCPrefix, kExprStructNew, struct_type_base,
|
|
kGCPrefix, kExprExternExternalize])
|
|
.exportFunc();
|
|
|
|
let table = exporting_instance.exports.table;
|
|
let instance = builder.instantiate({imports: {table}});
|
|
assertThrows(() => table.set(0, instance.exports.struct_base()), TypeError);
|
|
assertThrows(() => table.grow(1, instance.exports.struct_base()), TypeError);
|
|
})();
|
|
|
|
(function TestRefTableNotNull() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
|
let table = builder.addTable(wasmRefType(struct_type), 2, 6,
|
|
[...wasmI32Const(111),
|
|
kGCPrefix, kExprStructNew, struct_type])
|
|
.exportAs("table");
|
|
|
|
builder.addFunction("create_struct", makeSig([kWasmI32], [kWasmExternRef]))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprStructNew, struct_type,
|
|
kGCPrefix, kExprExternExternalize,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("struct_getter", kSig_i_i)
|
|
.addBody([
|
|
kExprLocalGet, 0, kExprTableGet, 0,
|
|
kGCPrefix, kExprStructGet, struct_type, 0])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({});
|
|
let wasmTable = instance.exports.table;
|
|
|
|
// Initial values.
|
|
assertEquals(111, instance.exports.struct_getter(0));
|
|
assertEquals(111, instance.exports.struct_getter(1));
|
|
assertTraps(kTrapTableOutOfBounds, () => instance.exports.struct_getter(2));
|
|
|
|
assertThrows(() => wasmTable.grow(1), TypeError,
|
|
/Argument 1 must be specified for non-nullable element type/);
|
|
wasmTable.grow(1, instance.exports.create_struct(222));
|
|
assertEquals(222, instance.exports.struct_getter(2));
|
|
assertThrows(() => wasmTable.set(2, undefined), TypeError,
|
|
/Argument 1 is invalid/);
|
|
assertThrows(() => wasmTable.set(2, null), TypeError,
|
|
/Argument 1 is invalid/);
|
|
wasmTable.set(2, instance.exports.create_struct(333));
|
|
assertEquals(333, instance.exports.struct_getter(2));
|
|
})();
|