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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 } | 504 } |
505 } else { | 505 } else { |
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 { |
| 515 |
| 516 bool IsAbsolutePath(const char* path) { |
| 517 #if defined(_WIN32) || defined(_WIN64) |
| 518 // TODO(adamk): This is an incorrect approximation, but should |
| 519 // work for all our test-running cases. |
| 520 return strchr(path, ':') != nullptr; |
| 521 #else |
| 522 return path[0] == '/'; |
| 523 #endif |
| 524 } |
| 525 |
| 526 std::string GetWorkingDirectory() { |
| 527 #if defined(_WIN32) || defined(_WIN64) |
| 528 char system_buffer[MAX_PATH]; |
| 529 // TODO(adamk): Support Unicode paths. |
| 530 DWORD len = GetCurrentDirectoryA(MAX_PATH, system_buffer); |
| 531 CHECK(len > 0); |
| 532 return system_buffer; |
| 533 #else |
| 534 char curdir[PATH_MAX]; |
| 535 CHECK_NOT_NULL(getcwd(curdir, PATH_MAX)); |
| 536 return curdir; |
| 537 #endif |
| 538 } |
| 539 |
| 540 std::string DirName(const std::string& path) { |
| 541 DCHECK(IsAbsolutePath(path.c_str())); |
| 542 size_t last_slash = path.find_last_of("/\\"); |
| 543 DCHECK(last_slash != std::string::npos); |
| 544 return path.substr(0, last_slash + 1); |
| 545 } |
| 546 |
| 547 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, |
| 548 Local<String> specifier, |
| 549 Local<Module> referrer, |
| 550 Local<Value> data) { |
| 551 Isolate* isolate = context->GetIsolate(); |
| 552 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( |
| 553 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()); |
| 557 std::string absolute_path = *String::Utf8Value(dir_name); |
| 558 absolute_path.append(*specifier_utf8); |
| 559 auto it = module_map->find(absolute_path); |
| 560 if (it != module_map->end()) { |
| 561 return it->second.Get(isolate); |
| 562 } |
| 563 return MaybeLocal<Module>(); |
| 564 } |
| 565 |
| 566 } // anonymous namespace |
| 567 |
514 MaybeLocal<Module> Shell::FetchModuleTree( | 568 MaybeLocal<Module> Shell::FetchModuleTree( |
515 Isolate* isolate, const std::string& file_name, | 569 Isolate* isolate, const std::string& file_name, |
516 std::map<std::string, Global<Module>>* module_map) { | 570 std::map<std::string, Global<Module>>* module_map) { |
| 571 DCHECK(IsAbsolutePath(file_name.c_str())); |
517 TryCatch try_catch(isolate); | 572 TryCatch try_catch(isolate); |
518 try_catch.SetVerbose(true); | 573 try_catch.SetVerbose(true); |
519 Local<String> source_text = ReadFile(isolate, file_name.c_str()); | 574 Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
520 if (source_text.IsEmpty()) { | 575 if (source_text.IsEmpty()) { |
521 printf("Error reading '%s'\n", file_name.c_str()); | 576 printf("Error reading '%s'\n", file_name.c_str()); |
522 Shell::Exit(1); | 577 Shell::Exit(1); |
523 } | 578 } |
524 ScriptOrigin origin( | 579 ScriptOrigin origin( |
525 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) | 580 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
526 .ToLocalChecked()); | 581 .ToLocalChecked()); |
527 ScriptCompiler::Source source(source_text, origin); | 582 ScriptCompiler::Source source(source_text, origin); |
528 Local<Module> module; | 583 Local<Module> module; |
529 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { | 584 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
530 ReportException(isolate, &try_catch); | 585 ReportException(isolate, &try_catch); |
531 return MaybeLocal<Module>(); | 586 return MaybeLocal<Module>(); |
532 } | 587 } |
533 module_map->insert( | 588 module_map->insert( |
534 std::make_pair(file_name, Global<Module>(isolate, module))); | 589 std::make_pair(file_name, Global<Module>(isolate, module))); |
| 590 |
| 591 std::string dir_name = DirName(file_name); |
| 592 module->SetEmbedderData( |
| 593 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) |
| 594 .ToLocalChecked()); |
| 595 |
535 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { | 596 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
536 Local<String> name = module->GetModuleRequest(i); | 597 Local<String> name = module->GetModuleRequest(i); |
537 // TODO(adamk): Resolve the imported module to a full path. | 598 String::Utf8Value utf8_value(name); |
538 std::string str = *String::Utf8Value(name); | 599 std::string absolute_path; |
539 if (!module_map->count(str)) { | 600 if (IsAbsolutePath(*utf8_value)) { |
540 if (FetchModuleTree(isolate, str, module_map).IsEmpty()) { | 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)) { |
| 607 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { |
541 return MaybeLocal<Module>(); | 608 return MaybeLocal<Module>(); |
542 } | 609 } |
543 } | 610 } |
544 } | 611 } |
545 | 612 |
546 return module; | 613 return module; |
547 } | 614 } |
548 | 615 |
549 namespace { | |
550 | |
551 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, | |
552 Local<String> specifier, | |
553 Local<Module> referrer, | |
554 Local<Value> data) { | |
555 Isolate* isolate = context->GetIsolate(); | |
556 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( | |
557 External::Cast(*data)->Value()); | |
558 std::string str_specifier = *String::Utf8Value(specifier); | |
559 // TODO(adamk): Resolve the specifier using the referrer | |
560 auto it = module_map->find(str_specifier); | |
561 if (it != module_map->end()) { | |
562 return it->second.Get(isolate); | |
563 } | |
564 return MaybeLocal<Module>(); | |
565 } | |
566 | |
567 } // anonymous namespace | |
568 | |
569 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { | 616 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
570 HandleScope handle_scope(isolate); | 617 HandleScope handle_scope(isolate); |
571 | 618 |
| 619 std::string absolute_path; |
| 620 if (IsAbsolutePath(file_name)) { |
| 621 absolute_path = file_name; |
| 622 } else { |
| 623 absolute_path = GetWorkingDirectory(); |
| 624 absolute_path.push_back('/'); |
| 625 absolute_path.append(file_name); |
| 626 } |
| 627 |
572 Local<Module> root_module; | 628 Local<Module> root_module; |
573 std::map<std::string, Global<Module>> module_map; | 629 std::map<std::string, Global<Module>> module_map; |
574 if (!FetchModuleTree(isolate, file_name, &module_map).ToLocal(&root_module)) { | 630 if (!FetchModuleTree(isolate, absolute_path, &module_map) |
| 631 .ToLocal(&root_module)) { |
575 return false; | 632 return false; |
576 } | 633 } |
577 | 634 |
578 TryCatch try_catch(isolate); | 635 TryCatch try_catch(isolate); |
579 try_catch.SetVerbose(true); | 636 try_catch.SetVerbose(true); |
580 | 637 |
581 MaybeLocal<Value> maybe_result; | 638 MaybeLocal<Value> maybe_result; |
582 { | 639 { |
583 PerIsolateData* data = PerIsolateData::Get(isolate); | 640 PerIsolateData* data = PerIsolateData::Get(isolate); |
584 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); | 641 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
(...skipping 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2695 } | 2752 } |
2696 | 2753 |
2697 } // namespace v8 | 2754 } // namespace v8 |
2698 | 2755 |
2699 | 2756 |
2700 #ifndef GOOGLE3 | 2757 #ifndef GOOGLE3 |
2701 int main(int argc, char* argv[]) { | 2758 int main(int argc, char* argv[]) { |
2702 return v8::Shell::Main(argc, argv); | 2759 return v8::Shell::Main(argc, argv); |
2703 } | 2760 } |
2704 #endif | 2761 #endif |
OLD | NEW |