Reland "[wasm][eh] Add WebAssembly.Tag.type"
This is a reland of 4cc547c759
Change: prevent a memcpy to nullptr by skipping the call to copy_out()
when the length is zero.
Original change's description:
> [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/+/3021173
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#75815}
Bug: v8:8091
Change-Id: I22f400b6e36d1322a4eabd20a68b4bdd70d61377
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3041436
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75847}
This commit is contained in:
parent
c58862c360
commit
ee445477fb
@ -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,27 @@ 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);
|
||||
if (n > 0) {
|
||||
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 +2312,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 +2419,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,
|
||||
|
@ -237,7 +237,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.
|
||||
@ -248,23 +249,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;
|
||||
}
|
||||
|
@ -472,7 +472,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,
|
||||
|
49
test/mjsunit/wasm/exceptions-type-reflection.js
Normal file
49
test/mjsunit/wasm/exceptions-type-reflection.js
Normal file
@ -0,0 +1,49 @@
|
||||
// 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);
|
||||
})
|
||||
})();
|
Loading…
Reference in New Issue
Block a user