Commit 4cc547c7 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by V8 LUCI CQ

[wasm][eh] Add WebAssembly.Tag.type

R=ahaas@chromium.org

Bug: v8:8091
Change-Id: Id069ffbf76bf836b613287788b1b1fccbb577475
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3021173Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75815}
parent 8336d807
......@@ -1466,7 +1466,7 @@ void WebAssemblyTag(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Set the tag index to 0. It is only used for debugging purposes, and has no
// meaningful value when declared outside of a wasm module.
auto tag = i::WasmExceptionTag::New(i_isolate, 0);
i::Handle<i::Object> exception =
i::Handle<i::JSObject> exception =
i::WasmExceptionObject::New(i_isolate, &sig, tag);
args.GetReturnValue().Set(Utils::ToLocal(exception));
}
......@@ -1621,6 +1621,7 @@ constexpr const char* kName_WasmGlobalObject = "WebAssembly.Global";
constexpr const char* kName_WasmMemoryObject = "WebAssembly.Memory";
constexpr const char* kName_WasmInstanceObject = "WebAssembly.Instance";
constexpr const char* kName_WasmTableObject = "WebAssembly.Table";
constexpr const char* kName_WasmExceptionObject = "WebAssembly.Tag";
#define EXTRACT_THIS(var, WasmType) \
i::Handle<i::WasmType> var; \
......@@ -1852,6 +1853,25 @@ void WebAssemblyMemoryType(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(Utils::ToLocal(type));
}
// WebAssembly.Tag.type() -> FunctionType
void WebAssemblyTagType(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Tag.type()");
EXTRACT_THIS(tag, WasmExceptionObject);
if (thrower.error()) return;
int n = tag->serialized_signature().length();
std::vector<i::wasm::ValueType> data(n);
tag->serialized_signature().copy_out(0, data.data(), n);
const i::wasm::FunctionSig sig{0, data.size(), data.data()};
constexpr bool kForException = true;
auto type = i::wasm::GetTypeForFunction(i_isolate, &sig, kForException);
args.GetReturnValue().Set(Utils::ToLocal(type));
}
void WebAssemblyGlobalGetValueCommon(
const v8::FunctionCallbackInfo<v8::Value>& args, const char* name) {
v8::Isolate* isolate = args.GetIsolate();
......@@ -2290,10 +2310,14 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> exception_constructor =
InstallConstructorFunc(isolate, webassembly, "Tag", WebAssemblyTag);
context->set_wasm_exception_constructor(*exception_constructor);
SetDummyInstanceTemplate(isolate, exception_constructor);
JSFunction::EnsureHasInitialMap(exception_constructor);
Handle<JSObject> exception_proto(
JSObject::cast(exception_constructor->instance_prototype()), isolate);
if (enabled_features.has_type_reflection()) {
InstallFunc(isolate, exception_proto, "type", WebAssemblyTagType, 0);
}
Handle<Map> exception_map = isolate->factory()->NewMap(
i::WASM_EXCEPTION_OBJECT_TYPE, WasmExceptionObject::kHeaderSize);
JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
......@@ -2393,6 +2417,9 @@ void WasmJs::InstallConditionalFeatures(Isolate* isolate,
JSFunction::EnsureHasInitialMap(exception_constructor);
Handle<JSObject> exception_proto(
JSObject::cast(exception_constructor->instance_prototype()), isolate);
if (enabled_features.has_type_reflection()) {
InstallFunc(isolate, exception_proto, "type", WebAssemblyTagType, 0);
}
Handle<Map> exception_map = isolate->factory()->NewMap(
i::WASM_EXCEPTION_OBJECT_TYPE, WasmExceptionObject::kHeaderSize);
JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
......
......@@ -227,7 +227,8 @@ Handle<String> ToValueTypeString(Isolate* isolate, ValueType type) {
}
} // namespace
Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig) {
Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig,
bool for_exception) {
Factory* factory = isolate->factory();
// Extract values for the {ValueType[]} arrays.
......@@ -238,23 +239,29 @@ Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig) {
Handle<String> type_value = ToValueTypeString(isolate, type);
param_values->set(param_index++, *type_value);
}
int result_index = 0;
int result_count = static_cast<int>(sig->return_count());
Handle<FixedArray> result_values = factory->NewFixedArray(result_count);
for (ValueType type : sig->returns()) {
Handle<String> type_value = ToValueTypeString(isolate, type);
result_values->set(result_index++, *type_value);
}
// Create the resulting {FunctionType} object.
Handle<JSFunction> object_function = isolate->object_function();
Handle<JSObject> object = factory->NewJSObject(object_function);
Handle<JSArray> params = factory->NewJSArrayWithElements(param_values);
Handle<JSArray> results = factory->NewJSArrayWithElements(result_values);
Handle<String> params_string = factory->InternalizeUtf8String("parameters");
Handle<String> results_string = factory->InternalizeUtf8String("results");
JSObject::AddProperty(isolate, object, params_string, params, NONE);
JSObject::AddProperty(isolate, object, results_string, results, NONE);
// Now add the result types if needed.
if (for_exception) {
DCHECK_EQ(sig->returns().size(), 0);
} else {
int result_index = 0;
int result_count = static_cast<int>(sig->return_count());
Handle<FixedArray> result_values = factory->NewFixedArray(result_count);
for (ValueType type : sig->returns()) {
Handle<String> type_value = ToValueTypeString(isolate, type);
result_values->set(result_index++, *type_value);
}
Handle<JSArray> results = factory->NewJSArrayWithElements(result_values);
JSObject::AddProperty(isolate, object, results_string, results, NONE);
}
return object;
}
......
......@@ -469,7 +469,8 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
Handle<Context> context);
Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig);
Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig,
bool for_exception = false);
Handle<JSObject> GetTypeForGlobal(Isolate* isolate, bool is_mutable,
ValueType type);
Handle<JSObject> GetTypeForMemory(Isolate* isolate, uint32_t min_size,
......
// Copyright 2021 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: --experimental-wasm-eh --experimental-wasm-type-reflection
load("test/mjsunit/wasm/wasm-module-builder.js");
let testcases = [
{types: {parameters:[]}, sig: kSig_v_v},
{types: {parameters:["i32"]}, sig: kSig_v_i},
{types: {parameters:["i64"]}, sig: kSig_v_l},
{types: {parameters:["f64", "f64", "i32"]}, sig: kSig_v_ddi},
{types: {parameters:["f32"]}, sig: kSig_v_f},
];
(function TestExport() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
testcases.forEach(function(expected, i) {
let except = builder.addException(expected.sig);
builder.addExportOfKind("ex" + i, kExternalException, except);
});
let instance = builder.instantiate();
testcases.forEach(function(expected, i) {
assertEquals(instance.exports["ex" + i].type(), expected.types);
});
})();
(function TestImportExport() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let imports = {m: {}};
testcases.forEach(function(expected, i) {
let t = new WebAssembly.Tag(expected.types);
let index = builder.addImportedException("m", "ex" + i, expected.sig);
builder.addExportOfKind("ex" + i, kExternalException, index);
imports.m["ex" + i] = t;
});
let instance = builder.instantiate(imports);
testcases.forEach(function(expected, i) {
assertEquals(instance.exports["ex" + i].type(), expected.types);
})
})();
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