summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/wasm-module.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/wasm-module.cc')
-rw-r--r--deps/v8/src/wasm/wasm-module.cc203
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);
}