Commit 94aa48ef authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Fix interaction of WebAssembly.Function with globals.

This makes sure that functions constructed via {WebAssembly.Function}
can be properly stored in globals of type "funcref". For now it is not
possible to call functions in such globals, but values can be loaded and
stored.

R=ahaas@chromium.org
TEST=mjsunit/wasm/type-reflection-with-anyref
BUG=v8:7742

Change-Id: I88ad1b5a57fd50e28723430803c528e674a94321
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1876815Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64539}
parent 4a4ca6d5
......@@ -71,7 +71,7 @@ RUNTIME_FUNCTION(Runtime_WasmIsValidFuncRefValue) {
if (function->IsNull(isolate)) {
return Smi::FromInt(true);
}
if (WasmExportedFunction::IsWasmExportedFunction(*function)) {
if (WasmExternalFunction::IsWasmExternalFunction(*function)) {
return Smi::FromInt(true);
}
return Smi::FromInt(false);
......
......@@ -186,7 +186,7 @@ void WasmGlobalObject::SetAnyRef(Handle<Object> value) {
bool WasmGlobalObject::SetFuncRef(Isolate* isolate, Handle<Object> value) {
DCHECK_EQ(type(), wasm::kWasmFuncRef);
if (!value->IsNull(isolate) &&
!WasmExportedFunction::IsWasmExportedFunction(*value) &&
!WasmExternalFunction::IsWasmExternalFunction(*value) &&
!WasmCapiFunction::IsWasmCapiFunction(*value)) {
return false;
}
......
......@@ -41,6 +41,38 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals(2, Object.getOwnPropertyNames(type).length);
})();
(function TestFunctionGlobalGetAndSet() {
let builder = new WasmModuleBuilder();
let fun1 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => 7);
let fun2 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => 9);
builder.addGlobal(kWasmAnyFunc, true).exportAs("f");
builder.addFunction('get_global', kSig_a_v)
.addBody([
kExprGlobalGet, 0,
])
.exportFunc();
builder.addFunction('set_global', kSig_v_a)
.addBody([
kExprLocalGet, 0,
kExprGlobalSet, 0,
])
.exportFunc();
let instance = builder.instantiate();
// Test getting and setting "funcref" global via WebAssembly.
assertEquals(null, instance.exports.get_global());
instance.exports.set_global(fun1);
assertEquals(fun1, instance.exports.get_global());
// Test getting and setting "funcref" global via JavaScript.
assertEquals(fun1, instance.exports.f.value);
instance.exports.f.value = fun2;
assertEquals(fun2, instance.exports.f.value);
// Test the full round-trip of an "funcref" global.
assertEquals(fun2, instance.exports.get_global());
})();
// This is an extension of "type-reflection.js/TestFunctionTableSetAndCall" to
// multiple table indexes. If --experimental-wasm-anyref is enabled by default
// this test case can supersede the other one.
......
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