Index: src/d8.cc |
diff --git a/src/d8.cc b/src/d8.cc |
index 32e6636ecb0d9d423e39a15a935e4b4bfb09f258..920a6f488f203a9a871fd0db0b364677187dbace 100644 |
--- a/src/d8.cc |
+++ b/src/d8.cc |
@@ -9,7 +9,7 @@ |
#include <algorithm> |
#include <fstream> |
-#include <unordered_map> |
+#include <map> |
#include <utility> |
#include <vector> |
@@ -572,74 +572,29 @@ |
return result; |
} |
-// Per-context Module data, allowing sharing of module maps |
-// across top-level module loads. |
-class ModuleEmbedderData { |
- private: |
- class ModuleGlobalHash { |
- public: |
- explicit ModuleGlobalHash(Isolate* isolate) : isolate_(isolate) {} |
- size_t operator()(const Global<Module>& module) const { |
- return module.Get(isolate_)->GetIdentityHash(); |
- } |
- |
- private: |
- Isolate* isolate_; |
- }; |
- |
- public: |
- explicit ModuleEmbedderData(Isolate* isolate) |
- : module_to_directory_map(10, ModuleGlobalHash(isolate)) {} |
- |
- // Map from normalized module specifier to Module. |
- std::unordered_map<std::string, Global<Module>> specifier_to_module_map; |
- // Map from Module to the directory that Module was loaded from. |
- std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> |
- module_to_directory_map; |
-}; |
- |
-enum { |
- // The debugger reserves the first slot in the Context embedder data. |
- kDebugIdIndex = Context::kDebugIdIndex, |
- kModuleEmbedderDataIndex |
-}; |
- |
-void InitializeModuleEmbedderData(Local<Context> context) { |
- context->SetAlignedPointerInEmbedderData( |
- kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); |
-} |
- |
-ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { |
- return static_cast<ModuleEmbedderData*>( |
- context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); |
-} |
- |
-void DisposeModuleEmbedderData(Local<Context> context) { |
- delete GetModuleDataFromContext(context); |
- context->SetAlignedPointerInEmbedderData(kModuleEmbedderDataIndex, nullptr); |
-} |
- |
MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, |
Local<String> specifier, |
- Local<Module> referrer) { |
+ Local<Module> referrer, |
+ Local<Value> data) { |
Isolate* isolate = context->GetIsolate(); |
- ModuleEmbedderData* d = GetModuleDataFromContext(context); |
- auto dir_name_it = |
- d->module_to_directory_map.find(Global<Module>(isolate, referrer)); |
- CHECK(dir_name_it != d->module_to_directory_map.end()); |
+ auto module_map = static_cast<std::map<std::string, Global<Module>>*>( |
+ External::Cast(*data)->Value()); |
+ Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData()); |
std::string absolute_path = |
- NormalizePath(ToSTLString(specifier), dir_name_it->second); |
- auto module_it = d->specifier_to_module_map.find(absolute_path); |
- CHECK(module_it != d->specifier_to_module_map.end()); |
- return module_it->second.Get(isolate); |
+ NormalizePath(ToSTLString(specifier), ToSTLString(dir_name)); |
+ auto it = module_map->find(absolute_path); |
+ if (it != module_map->end()) { |
+ return it->second.Get(isolate); |
+ } |
+ return MaybeLocal<Module>(); |
} |
} // anonymous namespace |
-MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
- const std::string& file_name) { |
+MaybeLocal<Module> Shell::FetchModuleTree( |
+ Isolate* isolate, const std::string& file_name, |
+ std::map<std::string, Global<Module>>* module_map) { |
DCHECK(IsAbsolutePath(file_name)); |
- Isolate* isolate = context->GetIsolate(); |
TryCatch try_catch(isolate); |
try_catch.SetVerbose(true); |
Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
@@ -656,22 +611,19 @@ |
ReportException(isolate, &try_catch); |
return MaybeLocal<Module>(); |
} |
- |
- ModuleEmbedderData* d = GetModuleDataFromContext(context); |
- CHECK(d->specifier_to_module_map |
- .insert(std::make_pair(file_name, Global<Module>(isolate, module))) |
- .second); |
+ module_map->insert( |
+ std::make_pair(file_name, Global<Module>(isolate, module))); |
std::string dir_name = DirName(file_name); |
- CHECK(d->module_to_directory_map |
- .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) |
- .second); |
+ module->SetEmbedderData( |
+ String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) |
+ .ToLocalChecked()); |
for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
Local<String> name = module->GetModuleRequest(i); |
std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); |
- if (!d->specifier_to_module_map.count(absolute_path)) { |
- if (FetchModuleTree(context, absolute_path).IsEmpty()) { |
+ if (!module_map->count(absolute_path)) { |
+ if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { |
return MaybeLocal<Module>(); |
} |
} |
@@ -683,14 +635,12 @@ |
bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
HandleScope handle_scope(isolate); |
- PerIsolateData* data = PerIsolateData::Get(isolate); |
- Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
- Context::Scope context_scope(realm); |
- |
std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); |
Local<Module> root_module; |
- if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { |
+ std::map<std::string, Global<Module>> module_map; |
+ if (!FetchModuleTree(isolate, absolute_path, &module_map) |
+ .ToLocal(&root_module)) { |
return false; |
} |
@@ -698,9 +648,16 @@ |
try_catch.SetVerbose(true); |
MaybeLocal<Value> maybe_result; |
- if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
- maybe_result = root_module->Evaluate(realm); |
- EmptyMessageQueues(isolate); |
+ { |
+ PerIsolateData* data = PerIsolateData::Get(isolate); |
+ Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
+ Context::Scope context_scope(realm); |
+ |
+ if (root_module->Instantiate(realm, ResolveModuleCallback, |
+ External::New(isolate, &module_map))) { |
+ maybe_result = root_module->Evaluate(realm); |
+ EmptyMessageQueues(isolate); |
+ } |
} |
Local<Value> result; |
if (!maybe_result.ToLocal(&result)) { |
@@ -830,7 +787,6 @@ |
try_catch.ReThrow(); |
return MaybeLocal<Context>(); |
} |
- InitializeModuleEmbedderData(context); |
data->realms_[index].Reset(isolate, context); |
args.GetReturnValue().Set(index); |
return context; |
@@ -864,7 +820,6 @@ |
Throw(args.GetIsolate(), "Invalid realm index"); |
return; |
} |
- DisposeModuleEmbedderData(data->realms_[index].Get(isolate)); |
data->realms_[index].Reset(); |
isolate->ContextDisposedNotification(); |
isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime()); |
@@ -1533,7 +1488,6 @@ |
EscapableHandleScope handle_scope(isolate); |
Local<Context> context = Context::New(isolate, NULL, global_template); |
DCHECK(!context.IsEmpty()); |
- InitializeModuleEmbedderData(context); |
Context::Scope scope(context); |
i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory(); |
@@ -1859,7 +1813,6 @@ |
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
Execute(isolate); |
} |
- DisposeModuleEmbedderData(context); |
} |
Shell::CollectGarbage(isolate); |
} |
@@ -2119,7 +2072,6 @@ |
} |
} |
} |
- DisposeModuleEmbedderData(context); |
} |
Shell::CollectGarbage(isolate); |
} |
@@ -2303,7 +2255,6 @@ |
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
options.isolate_sources[0].Execute(isolate); |
} |
- DisposeModuleEmbedderData(context); |
} |
CollectGarbage(isolate); |
for (int i = 1; i < options.num_isolates; ++i) { |