| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <errno.h> | 5 #include <errno.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 v8::String::Utf8Value str(Stringify(isolate, result)); | 506 v8::String::Utf8Value str(Stringify(isolate, result)); |
| 507 fwrite(*str, sizeof(**str), str.length(), stdout); | 507 fwrite(*str, sizeof(**str), str.length(), stdout); |
| 508 printf("\n"); | 508 printf("\n"); |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 return true; | 511 return true; |
| 512 } | 512 } |
| 513 | 513 |
| 514 namespace { | 514 namespace { |
| 515 | 515 |
| 516 bool IsAbsolutePath(const char* path) { | 516 std::string ToSTLString(Local<String> v8_str) { |
| 517 String::Utf8Value utf8(v8_str); |
| 518 // Should not be able to fail since the input is a String. |
| 519 CHECK(*utf8); |
| 520 return *utf8; |
| 521 } |
| 522 |
| 523 bool IsAbsolutePath(const std::string& path) { |
| 517 #if defined(_WIN32) || defined(_WIN64) | 524 #if defined(_WIN32) || defined(_WIN64) |
| 518 // TODO(adamk): This is an incorrect approximation, but should | 525 // TODO(adamk): This is an incorrect approximation, but should |
| 519 // work for all our test-running cases. | 526 // work for all our test-running cases. |
| 520 return strchr(path, ':') != nullptr; | 527 return path.find(':') != std::string::npos; |
| 521 #else | 528 #else |
| 522 return path[0] == '/'; | 529 return path[0] == '/'; |
| 523 #endif | 530 #endif |
| 524 } | 531 } |
| 525 | 532 |
| 526 std::string GetWorkingDirectory() { | 533 std::string GetWorkingDirectory() { |
| 527 #if defined(_WIN32) || defined(_WIN64) | 534 #if defined(_WIN32) || defined(_WIN64) |
| 528 char system_buffer[MAX_PATH]; | 535 char system_buffer[MAX_PATH]; |
| 529 // TODO(adamk): Support Unicode paths. | 536 // TODO(adamk): Support Unicode paths. |
| 530 DWORD len = GetCurrentDirectoryA(MAX_PATH, system_buffer); | 537 DWORD len = GetCurrentDirectoryA(MAX_PATH, system_buffer); |
| 531 CHECK(len > 0); | 538 CHECK(len > 0); |
| 532 return system_buffer; | 539 return system_buffer; |
| 533 #else | 540 #else |
| 534 char curdir[PATH_MAX]; | 541 char curdir[PATH_MAX]; |
| 535 CHECK_NOT_NULL(getcwd(curdir, PATH_MAX)); | 542 CHECK_NOT_NULL(getcwd(curdir, PATH_MAX)); |
| 536 return curdir; | 543 return curdir; |
| 537 #endif | 544 #endif |
| 538 } | 545 } |
| 539 | 546 |
| 547 // Returns the directory part of path, without the trailing '/'. |
| 540 std::string DirName(const std::string& path) { | 548 std::string DirName(const std::string& path) { |
| 541 DCHECK(IsAbsolutePath(path.c_str())); | 549 DCHECK(IsAbsolutePath(path)); |
| 542 size_t last_slash = path.find_last_of("/\\"); | 550 size_t last_slash = path.find_last_of('/'); |
| 543 DCHECK(last_slash != std::string::npos); | 551 DCHECK(last_slash != std::string::npos); |
| 544 return path.substr(0, last_slash + 1); | 552 return path.substr(0, last_slash); |
| 553 } |
| 554 |
| 555 std::string EnsureAbsolutePath(const std::string& path, |
| 556 const std::string& dir_name) { |
| 557 return IsAbsolutePath(path) ? path : dir_name + '/' + path; |
| 545 } | 558 } |
| 546 | 559 |
| 547 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, | 560 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, |
| 548 Local<String> specifier, | 561 Local<String> specifier, |
| 549 Local<Module> referrer, | 562 Local<Module> referrer, |
| 550 Local<Value> data) { | 563 Local<Value> data) { |
| 551 Isolate* isolate = context->GetIsolate(); | 564 Isolate* isolate = context->GetIsolate(); |
| 552 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( | 565 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( |
| 553 External::Cast(*data)->Value()); | 566 External::Cast(*data)->Value()); |
| 554 String::Utf8Value specifier_utf8(specifier); | |
| 555 CHECK(!IsAbsolutePath(*specifier_utf8)); | |
| 556 Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData()); | 567 Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData()); |
| 557 std::string absolute_path = *String::Utf8Value(dir_name); | 568 std::string absolute_path = |
| 558 absolute_path.append(*specifier_utf8); | 569 EnsureAbsolutePath(ToSTLString(specifier), ToSTLString(dir_name)); |
| 559 auto it = module_map->find(absolute_path); | 570 auto it = module_map->find(absolute_path); |
| 560 if (it != module_map->end()) { | 571 if (it != module_map->end()) { |
| 561 return it->second.Get(isolate); | 572 return it->second.Get(isolate); |
| 562 } | 573 } |
| 563 return MaybeLocal<Module>(); | 574 return MaybeLocal<Module>(); |
| 564 } | 575 } |
| 565 | 576 |
| 566 } // anonymous namespace | 577 } // anonymous namespace |
| 567 | 578 |
| 568 MaybeLocal<Module> Shell::FetchModuleTree( | 579 MaybeLocal<Module> Shell::FetchModuleTree( |
| 569 Isolate* isolate, const std::string& file_name, | 580 Isolate* isolate, const std::string& file_name, |
| 570 std::map<std::string, Global<Module>>* module_map) { | 581 std::map<std::string, Global<Module>>* module_map) { |
| 571 DCHECK(IsAbsolutePath(file_name.c_str())); | 582 DCHECK(IsAbsolutePath(file_name)); |
| 572 TryCatch try_catch(isolate); | 583 TryCatch try_catch(isolate); |
| 573 try_catch.SetVerbose(true); | 584 try_catch.SetVerbose(true); |
| 574 Local<String> source_text = ReadFile(isolate, file_name.c_str()); | 585 Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
| 575 if (source_text.IsEmpty()) { | 586 if (source_text.IsEmpty()) { |
| 576 printf("Error reading '%s'\n", file_name.c_str()); | 587 printf("Error reading '%s'\n", file_name.c_str()); |
| 577 Shell::Exit(1); | 588 Shell::Exit(1); |
| 578 } | 589 } |
| 579 ScriptOrigin origin( | 590 ScriptOrigin origin( |
| 580 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) | 591 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
| 581 .ToLocalChecked()); | 592 .ToLocalChecked()); |
| 582 ScriptCompiler::Source source(source_text, origin); | 593 ScriptCompiler::Source source(source_text, origin); |
| 583 Local<Module> module; | 594 Local<Module> module; |
| 584 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { | 595 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
| 585 ReportException(isolate, &try_catch); | 596 ReportException(isolate, &try_catch); |
| 586 return MaybeLocal<Module>(); | 597 return MaybeLocal<Module>(); |
| 587 } | 598 } |
| 588 module_map->insert( | 599 module_map->insert( |
| 589 std::make_pair(file_name, Global<Module>(isolate, module))); | 600 std::make_pair(file_name, Global<Module>(isolate, module))); |
| 590 | 601 |
| 591 std::string dir_name = DirName(file_name); | 602 std::string dir_name = DirName(file_name); |
| 592 module->SetEmbedderData( | 603 module->SetEmbedderData( |
| 593 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) | 604 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) |
| 594 .ToLocalChecked()); | 605 .ToLocalChecked()); |
| 595 | 606 |
| 596 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { | 607 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
| 597 Local<String> name = module->GetModuleRequest(i); | 608 Local<String> name = module->GetModuleRequest(i); |
| 598 String::Utf8Value utf8_value(name); | 609 std::string absolute_path = EnsureAbsolutePath(ToSTLString(name), dir_name); |
| 599 std::string absolute_path; | |
| 600 if (IsAbsolutePath(*utf8_value)) { | |
| 601 absolute_path = *utf8_value; | |
| 602 } else { | |
| 603 absolute_path = dir_name; | |
| 604 absolute_path.append(*utf8_value); | |
| 605 } | |
| 606 if (!module_map->count(absolute_path)) { | 610 if (!module_map->count(absolute_path)) { |
| 607 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { | 611 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { |
| 608 return MaybeLocal<Module>(); | 612 return MaybeLocal<Module>(); |
| 609 } | 613 } |
| 610 } | 614 } |
| 611 } | 615 } |
| 612 | 616 |
| 613 return module; | 617 return module; |
| 614 } | 618 } |
| 615 | 619 |
| 616 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { | 620 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
| 617 HandleScope handle_scope(isolate); | 621 HandleScope handle_scope(isolate); |
| 618 | 622 |
| 619 std::string absolute_path; | 623 std::string absolute_path = |
| 620 if (IsAbsolutePath(file_name)) { | 624 EnsureAbsolutePath(file_name, GetWorkingDirectory()); |
| 621 absolute_path = file_name; | 625 std::replace(absolute_path.begin(), absolute_path.end(), '\\', '/'); |
| 622 } else { | |
| 623 absolute_path = GetWorkingDirectory(); | |
| 624 absolute_path.push_back('/'); | |
| 625 absolute_path.append(file_name); | |
| 626 } | |
| 627 | 626 |
| 628 Local<Module> root_module; | 627 Local<Module> root_module; |
| 629 std::map<std::string, Global<Module>> module_map; | 628 std::map<std::string, Global<Module>> module_map; |
| 630 if (!FetchModuleTree(isolate, absolute_path, &module_map) | 629 if (!FetchModuleTree(isolate, absolute_path, &module_map) |
| 631 .ToLocal(&root_module)) { | 630 .ToLocal(&root_module)) { |
| 632 return false; | 631 return false; |
| 633 } | 632 } |
| 634 | 633 |
| 635 TryCatch try_catch(isolate); | 634 TryCatch try_catch(isolate); |
| 636 try_catch.SetVerbose(true); | 635 try_catch.SetVerbose(true); |
| (...skipping 2115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2752 } | 2751 } |
| 2753 | 2752 |
| 2754 } // namespace v8 | 2753 } // namespace v8 |
| 2755 | 2754 |
| 2756 | 2755 |
| 2757 #ifndef GOOGLE3 | 2756 #ifndef GOOGLE3 |
| 2758 int main(int argc, char* argv[]) { | 2757 int main(int argc, char* argv[]) { |
| 2759 return v8::Shell::Main(argc, argv); | 2758 return v8::Shell::Main(argc, argv); |
| 2760 } | 2759 } |
| 2761 #endif | 2760 #endif |
| OLD | NEW |