[wasm.gc] WebAssembly.Table: Allow 'i31ref' type specifier
Bug: v8:7748 Change-Id: Iec34e16219a76e83cfadf7724fda5a6cfa80f69c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4115748 Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Auto-Submit: Matthias Liedtke <mliedtke@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#84987}
This commit is contained in:
parent
ac65192ce2
commit
2c36e2213f
@ -1179,8 +1179,10 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
} else if (enabled_features.has_gc() &&
|
||||
string->StringEquals(v8_str(isolate, "arrayref"))) {
|
||||
type = i::wasm::kWasmArrayRef;
|
||||
} else if (enabled_features.has_gc() &&
|
||||
string->StringEquals(v8_str(isolate, "i31ref"))) {
|
||||
type = i::wasm::kWasmI31Ref;
|
||||
} else {
|
||||
// TODO(7748): Add "i31ref".
|
||||
thrower.TypeError(
|
||||
"Descriptor property 'element' must be a WebAssembly reference type");
|
||||
return;
|
||||
|
@ -8,14 +8,14 @@ Module instantiated.
|
||||
Tables populated.
|
||||
Setting breakpoint
|
||||
{
|
||||
columnNumber : 264
|
||||
columnNumber : 316
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
}
|
||||
Paused:
|
||||
Script wasm://wasm/19fa3802 byte offset 264: Wasm opcode 0x01 (kExprNop)
|
||||
Script wasm://wasm/2633f626 byte offset 316: Wasm opcode 0x01 (kExprNop)
|
||||
Scope:
|
||||
at $main (0:264):
|
||||
at $main (0:316):
|
||||
- scope (wasm-expression-stack):
|
||||
stack:
|
||||
- scope (local):
|
||||
@ -24,15 +24,16 @@ at $main (0:264):
|
||||
$anyref_local_i31: 30 (anyref)
|
||||
$anyref_local_null: null (anyref)
|
||||
- scope (module):
|
||||
instance: exports: "exported_ref_table" (Table), "exported_func_table" (Table), "fill_tables" (Function), "main" (Function)
|
||||
instance: exports: "exported_ref_table" (Table), "exported_func_table" (Table), "exported_i31_table" (Table), "fill_tables" (Function), "main" (Function)
|
||||
module: Module
|
||||
functions: "$my_func": (Function), "$fill_tables": (Function), "$main": (Function)
|
||||
globals: "$global0": function $my_func() { [native code] } (funcref)
|
||||
tables:
|
||||
$import.any_table: 0: Array(2) (anyref), 1: Struct ((ref $type0)), 2: null (anyref)
|
||||
$import.any_table: 0: Array(2) (anyref), 1: 321 (anyref), 2: null (anyref), 3: null (anyref)
|
||||
$import.func_table: 0: function () { [native code] } (funcref), 1: function $my_func() { [native code] } (funcref), 2: null (funcref)
|
||||
$exported_ref_table: 0: Struct ((ref $type0)), 1: Array ((ref $type1)), 2: 30 (anyref), 3: null (anyref)
|
||||
$exported_func_table: 0: function external_fct() { [native code] } (funcref), 1: function $my_func() { [native code] } (funcref), 2: null (funcref)
|
||||
$exported_i31_table: 0: 123456 (i31ref), 1: -123 (i31ref), 2: null (i31ref)
|
||||
at (anonymous) (0:17):
|
||||
- scope (global):
|
||||
-- skipped globals
|
||||
|
@ -70,13 +70,15 @@ async function instantiateWasm() {
|
||||
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
||||
let array_type = builder.addArray(kWasmI32);
|
||||
let imported_ref_table =
|
||||
builder.addImportedTable('import', 'any_table', 3, 3, kWasmAnyRef);
|
||||
builder.addImportedTable('import', 'any_table', 4, 4, kWasmAnyRef);
|
||||
let imported_func_table =
|
||||
builder.addImportedTable('import', 'func_table', 3, 3, kWasmFuncRef);
|
||||
let ref_table = builder.addTable(kWasmAnyRef, 4)
|
||||
.exportAs('exported_ref_table');
|
||||
let func_table = builder.addTable(kWasmFuncRef, 3)
|
||||
.exportAs('exported_func_table');
|
||||
let i31ref_table = builder.addTable(kWasmI31Ref, 3)
|
||||
.exportAs('exported_i31_table');
|
||||
|
||||
let func = builder.addFunction('my_func', kSig_v_v).addBody([kExprNop]);
|
||||
// Make the function "declared".
|
||||
@ -97,6 +99,10 @@ async function instantiateWasm() {
|
||||
...wasmI32Const(123), kGCPrefix, kExprStructNew, struct_type,
|
||||
kExprTableSet, imported_ref_table,
|
||||
|
||||
...wasmI32Const(1),
|
||||
...wasmI32Const(321), kGCPrefix, kExprI31New,
|
||||
kExprTableSet, imported_ref_table,
|
||||
|
||||
// Fill imported func table.
|
||||
...wasmI32Const(1),
|
||||
kExprRefFunc, func.index,
|
||||
@ -106,6 +112,15 @@ async function instantiateWasm() {
|
||||
...wasmI32Const(1),
|
||||
kExprRefFunc, func.index,
|
||||
kExprTableSet, func_table.index,
|
||||
|
||||
// Fill i31 table.
|
||||
...wasmI32Const(0),
|
||||
...wasmI32Const(123456), kGCPrefix, kExprI31New,
|
||||
kExprTableSet, i31ref_table.index,
|
||||
|
||||
...wasmI32Const(1),
|
||||
...wasmI32Const(-123), kGCPrefix, kExprI31New,
|
||||
kExprTableSet, i31ref_table.index,
|
||||
]).exportFunc();
|
||||
|
||||
let body = [
|
||||
@ -137,7 +152,7 @@ async function instantiateWasm() {
|
||||
let imports = `{'import' : {
|
||||
'any_table': (() => {
|
||||
let js_table =
|
||||
new WebAssembly.Table({element: 'anyref', initial: 3, maximum: 3});
|
||||
new WebAssembly.Table({element: 'anyref', initial: 4, maximum: 4});
|
||||
js_table.set(0, ['JavaScript', 'value']);
|
||||
return js_table;
|
||||
})(),
|
||||
|
@ -12,6 +12,7 @@ let tableTypes = {
|
||||
"eqref": kWasmEqRef,
|
||||
"structref": kWasmStructRef,
|
||||
"arrayref": kWasmArrayRef,
|
||||
"i31ref": kWasmI31Ref,
|
||||
};
|
||||
|
||||
// Test table consistency check.
|
||||
@ -115,11 +116,13 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
builder.addFunction("createI31", i31Sig)
|
||||
.addBody([kExprI32Const, 12, kGCPrefix, kExprI31New])
|
||||
.exportFunc();
|
||||
let structSig = typeName != "arrayref" ? creatorSig : creatorAnySig;
|
||||
let structSig = typeName != "arrayref" && typeName != "i31ref"
|
||||
? creatorSig : creatorAnySig;
|
||||
builder.addFunction("createStruct", structSig)
|
||||
.addBody([kExprI32Const, 12, kGCPrefix, kExprStructNew, struct])
|
||||
.exportFunc();
|
||||
let arraySig = typeName != "structref" ? creatorSig : creatorAnySig;
|
||||
let arraySig = typeName != "structref" && typeName != "i31ref"
|
||||
? creatorSig : creatorAnySig;
|
||||
builder.addFunction("createArray", arraySig)
|
||||
.addBody([
|
||||
kExprI32Const, 12,
|
||||
@ -158,7 +161,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
assertSame(table.get(2), table.get(3)); // The same smi.
|
||||
}
|
||||
// Set struct.
|
||||
if (typeName != "arrayref") {
|
||||
if (typeName != "arrayref" && typeName != "i31ref") {
|
||||
table.set(4, wasm.exported(wasm.createStruct));
|
||||
assertSame(table.get(4), wasm.tableGet(4));
|
||||
assertEquals(12, wasm.tableGetStructVal(4));
|
||||
@ -168,7 +171,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
assertNotSame(table.get(4), table.get(5));
|
||||
}
|
||||
// Set array.
|
||||
if (typeName != "structref") {
|
||||
if (typeName != "structref" && typeName != "i31ref") {
|
||||
table.set(6, wasm.exported(wasm.createArray));
|
||||
assertSame(table.get(6), wasm.tableGet(6));
|
||||
assertEquals(12, wasm.tableGetArrayVal(6));
|
||||
@ -190,7 +193,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
assertEquals(largeString, table.get(9));
|
||||
}
|
||||
|
||||
if (typeName != "arrayref") {
|
||||
if (typeName != "arrayref" && typeName != "i31ref") {
|
||||
// Grow table with explicit value.
|
||||
table.grow(2, wasm.exported(wasm.createStruct));
|
||||
assertEquals(12, wasm.tableGetStructVal(size));
|
||||
@ -205,6 +208,19 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
assertEquals("Grow using a string", wasm.tableGet(14));
|
||||
assertEquals("Grow using a string", table.get(14));
|
||||
}
|
||||
if (typeName == "i31ref" || typeName == "anyref") {
|
||||
table.set(0, 123);
|
||||
assertEquals(123, table.get(0));
|
||||
table.set(1, -123);
|
||||
assertEquals(-123, table.get(1));
|
||||
if (typeName == "i31ref") {
|
||||
assertThrows(() => table.set(0, 1 << 31), TypeError);
|
||||
} else {
|
||||
// anyref can reference boxed numbers as well.
|
||||
table.set(0, 1 << 31)
|
||||
assertEquals(1 << 31, table.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
// Set from JS with wrapped wasm value of incompatible type.
|
||||
let invalidValues = {
|
||||
@ -212,6 +228,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) {
|
||||
"eqref": [],
|
||||
"structref": ["I31", "Array"],
|
||||
"arrayref": ["I31", "Struct"],
|
||||
"i31ref": ["Struct", "Array"],
|
||||
};
|
||||
for (let invalidType of invalidValues[typeName]) {
|
||||
print(`Test invalid type ${invalidType} for ${typeName}`);
|
||||
|
@ -322,6 +322,41 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
assertEquals(1, instance.exports.null_getter(2));
|
||||
})();
|
||||
|
||||
(function TestI31RefTable() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
||||
let table = builder.addTable(kWasmI31Ref, 4, 4);
|
||||
builder.addActiveElementSegment(
|
||||
table, wasmI32Const(0),
|
||||
[[...wasmI32Const(10), kGCPrefix, kExprI31New],
|
||||
[...wasmI32Const(-42), kGCPrefix, kExprI31New],
|
||||
[kExprRefNull, kI31RefCode]],
|
||||
kWasmI31Ref);
|
||||
|
||||
builder.addFunction("i31GetI32", kSig_i_i)
|
||||
.addBody([
|
||||
kExprLocalGet, 0, kExprTableGet, 0,
|
||||
kGCPrefix, kExprI31GetS])
|
||||
.exportFunc();
|
||||
|
||||
builder.addFunction("i31GetNull", kSig_i_i)
|
||||
.addBody([kExprLocalGet, 0, kExprTableGet, 0, kExprRefIsNull])
|
||||
.exportFunc();
|
||||
|
||||
let instance = builder.instantiate({});
|
||||
assertTrue(!!instance);
|
||||
|
||||
assertEquals(0, instance.exports.i31GetNull(0));
|
||||
assertEquals(0, instance.exports.i31GetNull(1));
|
||||
assertEquals(1, instance.exports.i31GetNull(2));
|
||||
assertEquals(1, instance.exports.i31GetNull(3));
|
||||
assertEquals(10, instance.exports.i31GetI32(0));
|
||||
assertEquals(-42, instance.exports.i31GetI32(1));
|
||||
assertTraps(kTrapNullDereference, () => instance.exports.i31GetI32(2));
|
||||
assertTraps(kTrapNullDereference, () => instance.exports.i31GetI32(3));
|
||||
})();
|
||||
|
||||
(function TestArrayRefTable() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
Loading…
Reference in New Issue
Block a user