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

[wasm] Implement anyfunc parameters

Implementation of anyfunc parameters. Different to anyref parameters we
have to do a validation in the js-to-wasm wrapper: Only exported wasm
functions are allowed. I implemented this check in a runtime function.

R=titzer@chromium.org

Bug: v8:7581
Change-Id: I6145782fb8578124ddc21b50133c82235d666f19
Reviewed-on: https://chromium-review.googlesource.com/c/1417470Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58885}
parent edfb8cad
...@@ -4802,6 +4802,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4802,6 +4802,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
case wasm::kWasmF64: case wasm::kWasmF64:
return BuildChangeFloat64ToTagged(node); return BuildChangeFloat64ToTagged(node);
case wasm::kWasmAnyRef: case wasm::kWasmAnyRef:
case wasm::kWasmAnyFunc:
return node; return node;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -4860,6 +4861,26 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4860,6 +4861,26 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return node; return node;
} }
if (type == wasm::kWasmAnyFunc) {
Node* check =
BuildChangeSmiToInt32(SetEffect(BuildCallToRuntimeWithContext(
Runtime::kWasmIsValidAnyFuncValue, js_context, &node, 1, effect_,
Control())));
Diamond type_check(graph(), mcgraph()->common(), check,
BranchHint::kTrue);
type_check.Chain(Control());
Node* effect = Effect();
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, js_context,
nullptr, 0, &effect, type_check.if_false);
SetEffect(type_check.EffectPhi(Effect(), effect));
SetControl(type_check.merge);
return node;
}
Node* num = nullptr; Node* num = nullptr;
if (type != wasm::kWasmI64) { if (type != wasm::kWasmI64) {
......
...@@ -56,6 +56,20 @@ class ClearThreadInWasmScope { ...@@ -56,6 +56,20 @@ class ClearThreadInWasmScope {
} // namespace } // namespace
RUNTIME_FUNCTION(Runtime_WasmIsValidAnyFuncValue) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, function, 0);
if (function->IsNull(isolate)) {
return Smi::FromInt(true);
}
if (WasmExportedFunction::IsWasmExportedFunction(*function)) {
return Smi::FromInt(true);
}
return Smi::FromInt(false);
}
RUNTIME_FUNCTION(Runtime_WasmMemoryGrow) { RUNTIME_FUNCTION(Runtime_WasmMemoryGrow) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(2, args.length()); DCHECK_EQ(2, args.length());
......
...@@ -541,6 +541,7 @@ namespace internal { ...@@ -541,6 +541,7 @@ namespace internal {
F(WasmThrowTypeError, 0, 1) \ F(WasmThrowTypeError, 0, 1) \
F(WasmTableInit, 5, 1) \ F(WasmTableInit, 5, 1) \
F(WasmTableCopy, 4, 1) \ F(WasmTableCopy, 4, 1) \
F(WasmIsValidAnyFuncValue, 1, 1) \
F(WasmCompileLazy, 2, 1) F(WasmCompileLazy, 2, 1)
#define FOR_EACH_INTRINSIC_RETURN_PAIR_IMPL(F, I) \ #define FOR_EACH_INTRINSIC_RETURN_PAIR_IMPL(F, I) \
......
...@@ -269,6 +269,7 @@ class V8_EXPORT_PRIVATE ValueTypes { ...@@ -269,6 +269,7 @@ class V8_EXPORT_PRIVATE ValueTypes {
case kWasmF64: case kWasmF64:
return MachineRepresentation::kFloat64; return MachineRepresentation::kFloat64;
case kWasmAnyRef: case kWasmAnyRef:
case kWasmAnyFunc:
case kWasmExceptRef: case kWasmExceptRef:
return MachineRepresentation::kTaggedPointer; return MachineRepresentation::kTaggedPointer;
case kWasmS128: case kWasmS128:
...@@ -313,6 +314,8 @@ class V8_EXPORT_PRIVATE ValueTypes { ...@@ -313,6 +314,8 @@ class V8_EXPORT_PRIVATE ValueTypes {
return 'd'; return 'd';
case kWasmAnyRef: case kWasmAnyRef:
return 'r'; return 'r';
case kWasmAnyFunc:
return 'a';
case kWasmS128: case kWasmS128:
return 's'; return 's';
case kWasmStmt: case kWasmStmt:
...@@ -335,7 +338,9 @@ class V8_EXPORT_PRIVATE ValueTypes { ...@@ -335,7 +338,9 @@ class V8_EXPORT_PRIVATE ValueTypes {
case kWasmF64: case kWasmF64:
return "f64"; return "f64";
case kWasmAnyRef: case kWasmAnyRef:
return "ref"; return "anyref";
case kWasmAnyFunc:
return "anyfunc";
case kWasmExceptRef: case kWasmExceptRef:
return "exn"; return "exn";
case kWasmS128: case kWasmS128:
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-anyref --expose-gc
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
(function testAnyRefIdentityFunction() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_a_a)
.addBody([kExprGetLocal, 0])
.exportFunc();
const instance = builder.instantiate();
assertThrows(() => instance.exports.main(print), TypeError);
assertThrows(() => instance.exports.main({'hello' : 'world'}), TypeError);
assertSame(
instance.exports.main, instance.exports.main(instance.exports.main));
})();
(function testPassAnyRefToImportedFunction() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_v_a);
const imp_index = builder.addImport("q", "func", sig_index);
builder.addFunction('main', sig_index)
.addBody([kExprGetLocal, 0,
kExprCallFunction, imp_index])
.exportFunc();
const main = builder.instantiate({q: {func: checkFunction}}).exports.main;
function checkFunction(value) {
assertSame(main, value);
}
main(main);
})();
...@@ -96,6 +96,7 @@ let kWasmF32 = 0x7d; ...@@ -96,6 +96,7 @@ let kWasmF32 = 0x7d;
let kWasmF64 = 0x7c; let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b; let kWasmS128 = 0x7b;
let kWasmAnyRef = 0x6f; let kWasmAnyRef = 0x6f;
let kWasmAnyFunc = 0x70;
let kWasmExceptRef = 0x68; let kWasmExceptRef = 0x68;
let kExternalFunction = 0; let kExternalFunction = 0;
...@@ -145,8 +146,10 @@ let kSig_f_f = makeSig([kWasmF32], [kWasmF32]); ...@@ -145,8 +146,10 @@ let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]); let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]); let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]); let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]);
let kSig_a_a = makeSig([kWasmAnyFunc], [kWasmAnyFunc]);
let kSig_i_r = makeSig([kWasmAnyRef], [kWasmI32]); let kSig_i_r = makeSig([kWasmAnyRef], [kWasmI32]);
let kSig_v_r = makeSig([kWasmAnyRef], []); let kSig_v_r = makeSig([kWasmAnyRef], []);
let kSig_v_a = makeSig([kWasmAnyFunc], []);
let kSig_v_rr = makeSig([kWasmAnyRef, kWasmAnyRef], []); let kSig_v_rr = makeSig([kWasmAnyRef, kWasmAnyRef], []);
let kSig_r_v = makeSig([], [kWasmAnyRef]); let kSig_r_v = makeSig([], [kWasmAnyRef]);
......
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