Commit fecb695e authored by Andreas Haas's avatar Andreas Haas Committed by V8 LUCI CQ

[wasm] Introduce 'funcref' for the type reflection proposal

With a recent addition to the type reflection proposal, 'anyfunc' gets
renamed to 'funcref'. For backwards compatibility, 'anyfunc' becomes an
alias for 'funcref'. With this CL, the string 'funcref' can be used to
create a funcref table or a funcref global. Additionally, 'funcref' is
returned as the type of imported and exported functions as well as
globals and tables.

R=manoskouk@chromium.org

Change-Id: If3ed4d507de862ebfcabd4eb967bbfaae1c6ccba
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3300135Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78341}
parent 8a1bf76f
......@@ -1153,6 +1153,11 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
// The JS api uses 'anyfunc' instead of 'funcref'.
if (string->StringEquals(v8_str(isolate, "anyfunc"))) {
type = i::wasm::kWasmFuncRef;
} else if (enabled_features.has_type_reflection() &&
string->StringEquals(v8_str(isolate, "funcref"))) {
// With the type reflection proposal, "funcref" replaces "anyfunc",
// and anyfunc just becomes an alias for "funcref".
type = i::wasm::kWasmFuncRef;
} else if (enabled_features.has_reftypes() &&
string->StringEquals(v8_str(isolate, "externref"))) {
type = i::wasm::kWasmExternRef;
......@@ -1329,6 +1334,11 @@ bool GetValueType(Isolate* isolate, MaybeLocal<Value> maybe,
} else if (enabled_features.has_reftypes() &&
string->StringEquals(v8_str(isolate, "externref"))) {
*type = i::wasm::kWasmExternRef;
} else if (enabled_features.has_type_reflection() &&
string->StringEquals(v8_str(isolate, "funcref"))) {
// The type reflection proposal renames "anyfunc" to "funcref", and makes
// "anyfunc" an alias of "funcref".
*type = i::wasm::kWasmFuncRef;
} else if (enabled_features.has_reftypes() &&
string->StringEquals(v8_str(isolate, "anyfunc"))) {
// The JS api spec uses 'anyfunc' instead of 'funcref'.
......
......@@ -248,9 +248,7 @@ namespace {
// Converts the given {type} into a string representation that can be used in
// reflective functions. Should be kept in sync with the {GetValueType} helper.
Handle<String> ToValueTypeString(Isolate* isolate, ValueType type) {
return isolate->factory()->InternalizeUtf8String(
type == kWasmFuncRef ? base::CStrVector("anyfunc")
: base::VectorOf(type.name()));
return isolate->factory()->InternalizeUtf8String(base::VectorOf(type.name()));
}
} // namespace
......@@ -336,14 +334,8 @@ Handle<JSObject> GetTypeForTable(Isolate* isolate, ValueType type,
base::Optional<uint32_t> max_size) {
Factory* factory = isolate->factory();
Handle<String> element;
if (type.is_reference_to(HeapType::kFunc)) {
// TODO(wasm): We should define the "anyfunc" string in one central
// place and then use that constant everywhere.
element = factory->InternalizeUtf8String("anyfunc");
} else {
element = factory->InternalizeUtf8String(base::VectorOf(type.name()));
}
Handle<String> element =
factory->InternalizeUtf8String(base::VectorOf(type.name()));
Handle<JSFunction> object_function = isolate->object_function();
Handle<JSObject> object = factory->NewJSObject(object_function);
......
......@@ -34,9 +34,15 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals(false, type.mutable);
assertEquals(2, Object.getOwnPropertyNames(type).length);
global = new WebAssembly.Global({value: "funcref"});
type = global.type();
assertEquals("funcref", type.value);
assertEquals(false, type.mutable);
assertEquals(2, Object.getOwnPropertyNames(type).length);
global = new WebAssembly.Global({value: "anyfunc"});
type = global.type();
assertEquals("anyfunc", type.value);
assertEquals("funcref", type.value);
assertEquals(false, type.mutable);
assertEquals(2, Object.getOwnPropertyNames(type).length);
})();
......
......@@ -68,10 +68,24 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
})();
(function TestTableType() {
let table = new WebAssembly.Table({initial: 1, element: "anyfunc"});
let table = new WebAssembly.Table({initial: 1, element: "funcref"});
let type = table.type();
assertEquals(1, type.minimum);
assertEquals("anyfunc", type.element);
assertEquals("funcref", type.element);
assertEquals(undefined, type.maximum);
assertEquals(2, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({initial: 2, maximum: 15, element: "funcref"});
type = table.type();
assertEquals(2, type.minimum);
assertEquals(15, type.maximum);
assertEquals("funcref", type.element);
assertEquals(3, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({initial: 1, element: "anyfunc"});
type = table.type();
assertEquals(1, type.minimum);
assertEquals("funcref", type.element);
assertEquals(undefined, type.maximum);
assertEquals(2, Object.getOwnPropertyNames(type).length);
......@@ -79,7 +93,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
type = table.type();
assertEquals(2, type.minimum);
assertEquals(15, type.maximum);
assertEquals("anyfunc", type.element);
assertEquals("funcref", type.element);
assertEquals(3, Object.getOwnPropertyNames(type).length);
})();
......@@ -91,7 +105,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals("a", exports[0].name);
assertTrue("type" in exports[0]);
assertEquals("anyfunc", exports[0].type.element);
assertEquals("funcref", exports[0].type.element);
assertEquals(20, exports[0].type.minimum);
assertFalse("maximum" in exports[0].type);
......@@ -102,7 +116,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals("b", exports[0].name);
assertTrue("type" in exports[0]);
assertEquals("anyfunc", exports[0].type.element);
assertEquals("funcref", exports[0].type.element);
assertEquals(15, exports[0].type.minimum);
assertEquals(25, exports[0].type.maximum);
})();
......@@ -116,7 +130,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals("a", imports[0].name);
assertEquals("m", imports[0].module);
assertTrue("type" in imports[0]);
assertEquals("anyfunc", imports[0].type.element);
assertEquals("funcref", imports[0].type.element);
assertEquals(20, imports[0].type.minimum);
assertFalse("maximum" in imports[0].type);
......@@ -128,7 +142,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals("b", imports[0].name);
assertEquals("m", imports[0].module);
assertTrue("type" in imports[0]);
assertEquals("anyfunc", imports[0].type.element);
assertEquals("funcref", imports[0].type.element);
assertEquals(15, imports[0].type.minimum);
assertEquals(25, imports[0].type.maximum);
})();
......@@ -238,28 +252,28 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
})();
(function TestTableConstructorWithMinimum() {
let table = new WebAssembly.Table({minimum: 1, element: 'anyfunc'});
let table = new WebAssembly.Table({minimum: 1, element: 'funcref'});
assertTrue(table instanceof WebAssembly.Table);
let type = table.type();
assertEquals(1, type.minimum);
assertEquals('anyfunc', type.element);
assertEquals('funcref', type.element);
assertEquals(2, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({minimum: 1, element: 'anyfunc', maximum: 5});
table = new WebAssembly.Table({minimum: 1, element: 'funcref', maximum: 5});
assertTrue(table instanceof WebAssembly.Table);
type = table.type();
assertEquals(1, type.minimum);
assertEquals(5, type.maximum);
assertEquals('anyfunc', type.element);
assertEquals('funcref', type.element);
assertEquals(3, Object.getOwnPropertyNames(type).length);
assertThrows(
() => new WebAssembly.Table({minimum: 1, initial: 2, element: 'anyfunc'}),
() => new WebAssembly.Table({minimum: 1, initial: 2, element: 'funcref'}),
TypeError,
/The properties 'initial' and 'minimum' are not allowed at the same time/);
assertThrows(
() => new WebAssembly.Table({minimum: 1, initial: 2, element: 'anyfunc',
() => new WebAssembly.Table({minimum: 1, initial: 2, element: 'funcref',
maximum: 5}),
TypeError,
/The properties 'initial' and 'minimum' are not allowed at the same time/);
......
......@@ -13,13 +13,8 @@
'wpt/function/constructor.tentative': [FAIL],
'wpt/function/table.tentative': [FAIL],
'wpt/function/type.tentative': [FAIL],
# Failing tests after update
'proposals/js-types/global/type': [FAIL],
'proposals/js-types/module/exports': [FAIL],
'proposals/js-types/module/imports': [FAIL],
'proposals/js-types/table/constructor': [FAIL],
'proposals/js-types/table/type': [FAIL],
'wpt/global/type.tentative': [FAIL],
'wpt/table/type.tentative': [FAIL],
# Outdated proposal tests.
'proposals/js-types/table/get-set': [FAIL],
......@@ -33,7 +28,6 @@
# TODO(v8:10556): Remove sub-typing in the reference-types implementation
'proposals/js-types/constructor/instantiate': [FAIL],
'proposals/js-types/global/constructor': [FAIL],
'proposals/js-types/global/value-get-set': [FAIL],
'proposals/js-types/instance/constructor': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment