| Index: src/d8.cc
|
| diff --git a/src/d8.cc b/src/d8.cc
|
| index 170eccddb6de055e3d81c09d4b2043558c695d2f..43049499ab7a7f5b115c41b99fba13da61c44852 100644
|
| --- a/src/d8.cc
|
| +++ b/src/d8.cc
|
| @@ -511,9 +511,64 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
|
| return true;
|
| }
|
|
|
| +namespace {
|
| +
|
| +bool IsAbsolutePath(const char* path) {
|
| +#if defined(_WIN32) || defined(_WIN64)
|
| + // TODO(adamk): This is an incorrect approximation, but should
|
| + // work for all our test-running cases.
|
| + return strchr(path, ':') != nullptr;
|
| +#else
|
| + return path[0] == '/';
|
| +#endif
|
| +}
|
| +
|
| +std::string GetWorkingDirectory() {
|
| +#if defined(_WIN32) || defined(_WIN64)
|
| + char system_buffer[MAX_PATH];
|
| + // TODO(adamk): Support Unicode paths.
|
| + DWORD len = GetCurrentDirectoryA(MAX_PATH, system_buffer);
|
| + CHECK(len > 0);
|
| + return system_buffer;
|
| +#else
|
| + char curdir[PATH_MAX];
|
| + CHECK_NOT_NULL(getcwd(curdir, PATH_MAX));
|
| + return curdir;
|
| +#endif
|
| +}
|
| +
|
| +std::string DirName(const std::string& path) {
|
| + DCHECK(IsAbsolutePath(path.c_str()));
|
| + size_t last_slash = path.find_last_of("/\\");
|
| + DCHECK(last_slash != std::string::npos);
|
| + return path.substr(0, last_slash + 1);
|
| +}
|
| +
|
| +MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
|
| + Local<String> specifier,
|
| + Local<Module> referrer,
|
| + Local<Value> data) {
|
| + Isolate* isolate = context->GetIsolate();
|
| + auto module_map = static_cast<std::map<std::string, Global<Module>>*>(
|
| + External::Cast(*data)->Value());
|
| + String::Utf8Value specifier_utf8(specifier);
|
| + CHECK(!IsAbsolutePath(*specifier_utf8));
|
| + Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData());
|
| + std::string absolute_path = *String::Utf8Value(dir_name);
|
| + absolute_path.append(*specifier_utf8);
|
| + 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(
|
| Isolate* isolate, const std::string& file_name,
|
| std::map<std::string, Global<Module>>* module_map) {
|
| + DCHECK(IsAbsolutePath(file_name.c_str()));
|
| TryCatch try_catch(isolate);
|
| try_catch.SetVerbose(true);
|
| Local<String> source_text = ReadFile(isolate, file_name.c_str());
|
| @@ -532,12 +587,24 @@ MaybeLocal<Module> Shell::FetchModuleTree(
|
| }
|
| module_map->insert(
|
| std::make_pair(file_name, Global<Module>(isolate, module)));
|
| +
|
| + std::string dir_name = DirName(file_name);
|
| + 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);
|
| - // TODO(adamk): Resolve the imported module to a full path.
|
| - std::string str = *String::Utf8Value(name);
|
| - if (!module_map->count(str)) {
|
| - if (FetchModuleTree(isolate, str, module_map).IsEmpty()) {
|
| + String::Utf8Value utf8_value(name);
|
| + std::string absolute_path;
|
| + if (IsAbsolutePath(*utf8_value)) {
|
| + absolute_path = *utf8_value;
|
| + } else {
|
| + absolute_path = dir_name;
|
| + absolute_path.append(*utf8_value);
|
| + }
|
| + if (!module_map->count(absolute_path)) {
|
| + if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) {
|
| return MaybeLocal<Module>();
|
| }
|
| }
|
| @@ -546,32 +613,22 @@ MaybeLocal<Module> Shell::FetchModuleTree(
|
| return module;
|
| }
|
|
|
| -namespace {
|
| -
|
| -MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
|
| - Local<String> specifier,
|
| - Local<Module> referrer,
|
| - Local<Value> data) {
|
| - Isolate* isolate = context->GetIsolate();
|
| - auto module_map = static_cast<std::map<std::string, Global<Module>>*>(
|
| - External::Cast(*data)->Value());
|
| - std::string str_specifier = *String::Utf8Value(specifier);
|
| - // TODO(adamk): Resolve the specifier using the referrer
|
| - auto it = module_map->find(str_specifier);
|
| - if (it != module_map->end()) {
|
| - return it->second.Get(isolate);
|
| - }
|
| - return MaybeLocal<Module>();
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
|
| HandleScope handle_scope(isolate);
|
|
|
| + std::string absolute_path;
|
| + if (IsAbsolutePath(file_name)) {
|
| + absolute_path = file_name;
|
| + } else {
|
| + absolute_path = GetWorkingDirectory();
|
| + absolute_path.push_back('/');
|
| + absolute_path.append(file_name);
|
| + }
|
| +
|
| Local<Module> root_module;
|
| std::map<std::string, Global<Module>> module_map;
|
| - if (!FetchModuleTree(isolate, file_name, &module_map).ToLocal(&root_module)) {
|
| + if (!FetchModuleTree(isolate, absolute_path, &module_map)
|
| + .ToLocal(&root_module)) {
|
| return false;
|
| }
|
|
|
|
|