diff options
Diffstat (limited to 'deps/v8/src/wasm/wasm-module.cc')
-rw-r--r-- | deps/v8/src/wasm/wasm-module.cc | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/deps/v8/src/wasm/wasm-module.cc b/deps/v8/src/wasm/wasm-module.cc index 05057301ed..5a10368a8b 100644 --- a/deps/v8/src/wasm/wasm-module.cc +++ b/deps/v8/src/wasm/wasm-module.cc @@ -113,13 +113,156 @@ bool IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) { v8::Utils::ToLocal(isolate->factory()->empty_string())); } +namespace { + +// Converts the given {type} into a string representation that can be used in +// reflective functions. Should be kept in sync with the {GetValueType} helper. +Handle<String> ToValueTypeString(Isolate* isolate, ValueType type) { + Factory* factory = isolate->factory(); + Handle<String> string; + switch (type) { + case i::wasm::kWasmI32: { + string = factory->InternalizeUtf8String("i32"); + break; + } + case i::wasm::kWasmI64: { + string = factory->InternalizeUtf8String("i64"); + break; + } + case i::wasm::kWasmF32: { + string = factory->InternalizeUtf8String("f32"); + break; + } + case i::wasm::kWasmF64: { + string = factory->InternalizeUtf8String("f64"); + break; + } + case i::wasm::kWasmAnyRef: { + string = factory->InternalizeUtf8String("anyref"); + break; + } + case i::wasm::kWasmFuncRef: { + string = factory->InternalizeUtf8String("anyfunc"); + break; + } + case i::wasm::kWasmExnRef: { + string = factory->InternalizeUtf8String("exnref"); + break; + } + default: + UNREACHABLE(); + } + return string; +} + +} // namespace + +Handle<JSObject> GetTypeForFunction(Isolate* isolate, FunctionSig* sig) { + Factory* factory = isolate->factory(); + + // Extract values for the {ValueType[]} arrays. + int param_index = 0; + int param_count = static_cast<int>(sig->parameter_count()); + Handle<FixedArray> param_values = factory->NewFixedArray(param_count); + for (ValueType type : sig->parameters()) { + 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); + + return object; +} + +Handle<JSObject> GetTypeForGlobal(Isolate* isolate, bool is_mutable, + ValueType type) { + Factory* factory = isolate->factory(); + + Handle<JSFunction> object_function = isolate->object_function(); + Handle<JSObject> object = factory->NewJSObject(object_function); + Handle<String> mutable_string = factory->InternalizeUtf8String("mutable"); + Handle<String> value_string = factory->InternalizeUtf8String("value"); + JSObject::AddProperty(isolate, object, mutable_string, + factory->ToBoolean(is_mutable), NONE); + JSObject::AddProperty(isolate, object, value_string, + ToValueTypeString(isolate, type), NONE); + + return object; +} + +Handle<JSObject> GetTypeForMemory(Isolate* isolate, uint32_t min_size, + base::Optional<uint32_t> max_size) { + Factory* factory = isolate->factory(); + + Handle<JSFunction> object_function = isolate->object_function(); + Handle<JSObject> object = factory->NewJSObject(object_function); + Handle<String> minimum_string = factory->InternalizeUtf8String("minimum"); + Handle<String> maximum_string = factory->InternalizeUtf8String("maximum"); + JSObject::AddProperty(isolate, object, minimum_string, + factory->NewNumberFromUint(min_size), NONE); + if (max_size.has_value()) { + JSObject::AddProperty(isolate, object, maximum_string, + factory->NewNumberFromUint(max_size.value()), NONE); + } + + return object; +} + +Handle<JSObject> GetTypeForTable(Isolate* isolate, ValueType type, + uint32_t min_size, + base::Optional<uint32_t> max_size) { + Factory* factory = isolate->factory(); + + Handle<String> element; + if (type == ValueType::kWasmFuncRef) { + // TODO(wasm): We should define the "anyfunc" string in one central place + // and then use that constant everywhere. + element = factory->InternalizeUtf8String("anyfunc"); + } else { + DCHECK(WasmFeaturesFromFlags().anyref && type == ValueType::kWasmAnyRef); + element = factory->InternalizeUtf8String("anyref"); + } + + Handle<JSFunction> object_function = isolate->object_function(); + Handle<JSObject> object = factory->NewJSObject(object_function); + Handle<String> element_string = factory->InternalizeUtf8String("element"); + Handle<String> minimum_string = factory->InternalizeUtf8String("minimum"); + Handle<String> maximum_string = factory->InternalizeUtf8String("maximum"); + JSObject::AddProperty(isolate, object, element_string, element, NONE); + JSObject::AddProperty(isolate, object, minimum_string, + factory->NewNumberFromUint(min_size), NONE); + if (max_size.has_value()) { + JSObject::AddProperty(isolate, object, maximum_string, + factory->NewNumberFromUint(max_size.value()), NONE); + } + + return object; +} + Handle<JSArray> GetImports(Isolate* isolate, Handle<WasmModuleObject> module_object) { + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(isolate); Factory* factory = isolate->factory(); Handle<String> module_string = factory->InternalizeUtf8String("module"); Handle<String> name_string = factory->InternalizeUtf8String("name"); Handle<String> kind_string = factory->InternalizeUtf8String("kind"); + Handle<String> type_string = factory->InternalizeUtf8String("type"); Handle<String> function_string = factory->InternalizeUtf8String("function"); Handle<String> table_string = factory->InternalizeUtf8String("table"); @@ -145,17 +288,43 @@ Handle<JSArray> GetImports(Isolate* isolate, Handle<JSObject> entry = factory->NewJSObject(object_function); Handle<String> import_kind; + Handle<JSObject> type_value; switch (import.kind) { case kExternalFunction: + if (enabled_features.type_reflection) { + auto& func = module->functions[import.index]; + type_value = GetTypeForFunction(isolate, func.sig); + } import_kind = function_string; break; case kExternalTable: + if (enabled_features.type_reflection) { + auto& table = module->tables[import.index]; + base::Optional<uint32_t> maximum_size; + if (table.has_maximum_size) maximum_size.emplace(table.maximum_size); + type_value = GetTypeForTable(isolate, table.type, table.initial_size, + maximum_size); + } import_kind = table_string; break; case kExternalMemory: + if (enabled_features.type_reflection) { + DCHECK_EQ(0, import.index); // Only one memory supported. + base::Optional<uint32_t> maximum_size; + if (module->has_maximum_pages) { + maximum_size.emplace(module->maximum_pages); + } + type_value = + GetTypeForMemory(isolate, module->initial_pages, maximum_size); + } import_kind = memory_string; break; case kExternalGlobal: + if (enabled_features.type_reflection) { + auto& global = module->globals[import.index]; + type_value = + GetTypeForGlobal(isolate, global.mutability, global.type); + } import_kind = global_string; break; case kExternalException: @@ -178,6 +347,9 @@ Handle<JSArray> GetImports(Isolate* isolate, JSObject::AddProperty(isolate, entry, name_string, import_name.ToHandleChecked(), NONE); JSObject::AddProperty(isolate, entry, kind_string, import_kind, NONE); + if (!type_value.is_null()) { + JSObject::AddProperty(isolate, entry, type_string, type_value, NONE); + } storage->set(index, *entry); } @@ -187,10 +359,12 @@ Handle<JSArray> GetImports(Isolate* isolate, Handle<JSArray> GetExports(Isolate* isolate, Handle<WasmModuleObject> module_object) { + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(isolate); Factory* factory = isolate->factory(); Handle<String> name_string = factory->InternalizeUtf8String("name"); Handle<String> kind_string = factory->InternalizeUtf8String("kind"); + Handle<String> type_string = factory->InternalizeUtf8String("type"); Handle<String> function_string = factory->InternalizeUtf8String("function"); Handle<String> table_string = factory->InternalizeUtf8String("table"); @@ -214,17 +388,43 @@ Handle<JSArray> GetExports(Isolate* isolate, const WasmExport& exp = module->export_table[index]; Handle<String> export_kind; + Handle<JSObject> type_value; switch (exp.kind) { case kExternalFunction: + if (enabled_features.type_reflection) { + auto& func = module->functions[exp.index]; + type_value = GetTypeForFunction(isolate, func.sig); + } export_kind = function_string; break; case kExternalTable: + if (enabled_features.type_reflection) { + auto& table = module->tables[exp.index]; + base::Optional<uint32_t> maximum_size; + if (table.has_maximum_size) maximum_size.emplace(table.maximum_size); + type_value = GetTypeForTable(isolate, table.type, table.initial_size, + maximum_size); + } export_kind = table_string; break; case kExternalMemory: + if (enabled_features.type_reflection) { + DCHECK_EQ(0, exp.index); // Only one memory supported. + base::Optional<uint32_t> maximum_size; + if (module->has_maximum_pages) { + maximum_size.emplace(module->maximum_pages); + } + type_value = + GetTypeForMemory(isolate, module->initial_pages, maximum_size); + } export_kind = memory_string; break; case kExternalGlobal: + if (enabled_features.type_reflection) { + auto& global = module->globals[exp.index]; + type_value = + GetTypeForGlobal(isolate, global.mutability, global.type); + } export_kind = global_string; break; case kExternalException: @@ -243,6 +443,9 @@ Handle<JSArray> GetExports(Isolate* isolate, JSObject::AddProperty(isolate, entry, name_string, export_name.ToHandleChecked(), NONE); JSObject::AddProperty(isolate, entry, kind_string, export_kind, NONE); + if (!type_value.is_null()) { + JSObject::AddProperty(isolate, entry, type_string, type_value, NONE); + } storage->set(index, *entry); } |