Commit dcbe436d authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Add signature check to new WebAssembly.Function

This CL fixes a special case where a WasmExportedFunction is passed to
the WebAssembly.Function constructor. This is a case that was not yet
implemented in V8, and which is also not specified in the proposal yet.

With this CL we do a signature check of the provided function. If it
matches, the function itself is returned. Otherwise a TypeError is
thrown.

I filed an issue: https://github.com/WebAssembly/js-types/issues/13

R=jkummerow@chromium.org

Bug: chromium:1057534
Change-Id: Ib09d1ba18abaa6a8dd451aa747fd26c03d927413
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2084813
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66610}
parent 65ff0dbe
......@@ -1515,10 +1515,34 @@ void WebAssemblyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
thrower.TypeError("Argument 1 must be a function");
return;
}
const i::wasm::FunctionSig* sig = builder.Build();
i::Handle<i::JSReceiver> callable =
Utils::OpenHandle(*args[1].As<Function>());
if (i::WasmExportedFunction::IsWasmExportedFunction(*callable)) {
if (*i::Handle<i::WasmExportedFunction>::cast(callable)->sig() == *sig) {
args.GetReturnValue().Set(Utils::ToLocal(callable));
return;
}
thrower.TypeError(
"The signature of Argument 1 (a WebAssembly function) does "
"not match the signature specified in Argument 0");
return;
}
if (i::WasmJSFunction::IsWasmJSFunction(*callable)) {
if (i::Handle<i::WasmJSFunction>::cast(callable)->MatchesSignature(sig)) {
args.GetReturnValue().Set(Utils::ToLocal(callable));
return;
}
thrower.TypeError(
"The signature of Argument 1 (a WebAssembly function) does "
"not match the signature specified in Argument 0");
return;
}
i::Handle<i::JSFunction> result =
i::WasmJSFunction::New(i_isolate, sig, callable);
args.GetReturnValue().Set(Utils::ToLocal(result));
......
......@@ -343,6 +343,39 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
() => new WebAssembly.Function({parameters:[], results:[]}, _ => 0));
})();
(function TestFunctionConstructorWithWasmExportedFunction() {
let builder = new WasmModuleBuilder();
builder.addFunction('func1', kSig_v_i).addBody([]).exportFunc();
builder.addFunction('func2', kSig_v_v).addBody([]).exportFunc();
const instance = builder.instantiate();
assertThrows(
() => new WebAssembly.Function(
{parameters: [], results: []}, instance.exports.func1),
TypeError,
'WebAssembly.Function(): The signature of Argument 1 (a ' +
'WebAssembly function) does not match the signature specified in ' +
'Argument 0');
assertDoesNotThrow(
() => new WebAssembly.Function(
{parameters: [], results: []}, instance.exports.func2));
})();
(function TestFunctionConstructorWithWasmJSFunction() {
const func = new WebAssembly.Function({parameters: [], results: []}, _ => 0);
assertDoesNotThrow(
() => new WebAssembly.Function({parameters: [], results: []}, func));
assertThrows(
() => new WebAssembly.Function({parameters: ['i32'], results: []}, func),
TypeError,
'WebAssembly.Function(): The signature of Argument 1 (a ' +
'WebAssembly function) does not match the signature specified in ' +
'Argument 0');
})();
(function TestFunctionConstructorNonArray1() {
let log = []; // Populated with a log of accesses.
let two = { toString: () => "2" }; // Just a fancy "2".
......
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