[wasm][externref] Support default value for the table.set

WebAssembly.Table.set allows a default value instead of the second
parameter, which was not supported by V8 so far.

R=thibaudm@chromium.org

Bug: v8:7581
Change-Id: I417790722b1cb4f854cd0056ecb8377c330c45fa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3141574
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76846}
This commit is contained in:
Andreas Haas 2021-09-15 14:07:53 +02:00 committed by V8 LUCI CQ
parent 11045926ca
commit 6b57898062
5 changed files with 40 additions and 12 deletions

View File

@ -1902,7 +1902,12 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
i::Handle<i::Object> element = Utils::OpenHandle(*args[1]);
i::Handle<i::Object> element;
if (args.Length() >= 2) {
element = Utils::OpenHandle(*args[1]);
} else {
element = i_isolate->factory()->null_value();
}
if (!i::WasmTableObject::IsValidElement(i_isolate, table_object, element)) {
thrower.TypeError(
"Argument 1 must be null or a WebAssembly function of type compatible "

View File

@ -92,18 +92,19 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(table.get(2), testObject);
})();
function getDummy(val) {
let builder = new WasmModuleBuilder();
builder.addFunction('dummy', kSig_i_v)
.addBody([kExprI32Const, val])
.exportAs('dummy');
return builder.instantiate().exports.dummy;
}
(function TestFuncRefTableConstructorWithDefaultValue() {
print(arguments.callee.name);
const expected = 6;
let dummy =
(() => {
let builder = new WasmModuleBuilder();
builder.addFunction('dummy', kSig_i_v)
.addBody([kExprI32Const, expected])
.exportAs('dummy');
return builder.instantiate().exports.dummy;
})();
let dummy = getDummy(expected);
const argument = { "element": "anyfunc", "initial": 3 };
const table = new WebAssembly.Table(argument, dummy);
@ -112,3 +113,26 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(table.get(1)(), expected);
assertEquals(table.get(2)(), expected);
})();
(function TestExternFuncTableSetWithoutValue() {
print(arguments.callee.name);
const expected = 6;
const dummy = getDummy(expected);
const argument = { "element": "externref", "initial": 3 };
const table = new WebAssembly.Table(argument, dummy);
assertEquals(table.get(1)(), expected);
table.set(1);
assertEquals(table.get(1), null);
})();
(function TestExternRefTableSetWithoutValue() {
print(arguments.callee.name);
const testObject = {};
const argument = { "element": "externref", "initial": 3 };
const table = new WebAssembly.Table(argument, testObject);
assertEquals(table.get(1), testObject);
table.set(1);
assertEquals(table.get(1), null);
})();

View File

@ -697,8 +697,6 @@ assertThrows(
() => set.call(), TypeError, /Receiver is not a WebAssembly.Table/);
assertThrows(
() => set.call({}), TypeError, /Receiver is not a WebAssembly.Table/);
assertThrows(
() => set.call(tbl1, 0), TypeError, /must be null or a WebAssembly function/);
assertThrows(
() => set.call(tbl1, undefined), TypeError,
/must be convertible to a valid number/);

View File

@ -196,7 +196,6 @@ function assertTableIsValid(table, length) {
assertThrows(() => table.set(key, f), RangeError);
}
assertThrows(() => table.set(0), TypeError);
for (let val of [undefined, 0, "", {}, [], () => {}]) {
assertThrows(() => table.set(0, val), TypeError);
}

View File

@ -22,6 +22,8 @@
'wpt/memory/type.tentative': [FAIL],
'wpt/function/type.tentative': [FAIL],
'wpt/table/grow-reftypes.tentative': [FAIL],
# Outdated test, does not conform with the spec
'table/get-set': [FAIL],
# TODO(v8:10556): Remove sub-typing in the reference-types implementation
'constructor/instantiate': [FAIL],