| 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> |
| 11 #include <fstream> | 11 #include <fstream> |
| 12 #include <map> | 12 #include <unordered_map> |
| 13 #include <utility> | 13 #include <utility> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #ifdef ENABLE_VTUNE_JIT_INTERFACE | 16 #ifdef ENABLE_VTUNE_JIT_INTERFACE |
| 17 #include "src/third_party/vtune/v8-vtune.h" | 17 #include "src/third_party/vtune/v8-vtune.h" |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 #include "src/d8.h" | 20 #include "src/d8.h" |
| 21 #include "src/ostreams.h" | 21 #include "src/ostreams.h" |
| 22 | 22 |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 result = dir_name + '/' + path; | 565 result = dir_name + '/' + path; |
| 566 } | 566 } |
| 567 std::replace(result.begin(), result.end(), '\\', '/'); | 567 std::replace(result.begin(), result.end(), '\\', '/'); |
| 568 size_t i; | 568 size_t i; |
| 569 while ((i = result.find("/./")) != std::string::npos) { | 569 while ((i = result.find("/./")) != std::string::npos) { |
| 570 result.erase(i, 2); | 570 result.erase(i, 2); |
| 571 } | 571 } |
| 572 return result; | 572 return result; |
| 573 } | 573 } |
| 574 | 574 |
| 575 // Per-context Module data, allowing sharing of module maps |
| 576 // across top-level module loads. |
| 577 class ModuleEmbedderData { |
| 578 private: |
| 579 class ModuleGlobalHash { |
| 580 public: |
| 581 explicit ModuleGlobalHash(Isolate* isolate) : isolate_(isolate) {} |
| 582 size_t operator()(const Global<Module>& module) const { |
| 583 return module.Get(isolate_)->GetIdentityHash(); |
| 584 } |
| 585 |
| 586 private: |
| 587 Isolate* isolate_; |
| 588 }; |
| 589 |
| 590 public: |
| 591 explicit ModuleEmbedderData(Isolate* isolate) |
| 592 : module_to_directory_map(10, ModuleGlobalHash(isolate)) {} |
| 593 |
| 594 // Map from normalized module specifier to Module. |
| 595 std::unordered_map<std::string, Global<Module>> specifier_to_module_map; |
| 596 // Map from Module to the directory that Module was loaded from. |
| 597 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> |
| 598 module_to_directory_map; |
| 599 }; |
| 600 |
| 601 enum { |
| 602 // The debugger reserves the first slot in the Context embedder data. |
| 603 kDebugIdIndex = Context::kDebugIdIndex, |
| 604 kModuleEmbedderDataIndex |
| 605 }; |
| 606 |
| 607 void InitializeModuleEmbedderData(Local<Context> context) { |
| 608 context->SetAlignedPointerInEmbedderData( |
| 609 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); |
| 610 } |
| 611 |
| 612 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { |
| 613 return static_cast<ModuleEmbedderData*>( |
| 614 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); |
| 615 } |
| 616 |
| 617 void DisposeModuleEmbedderData(Local<Context> context) { |
| 618 delete GetModuleDataFromContext(context); |
| 619 context->SetAlignedPointerInEmbedderData(kModuleEmbedderDataIndex, nullptr); |
| 620 } |
| 621 |
| 575 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, | 622 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, |
| 576 Local<String> specifier, | 623 Local<String> specifier, |
| 577 Local<Module> referrer, | 624 Local<Module> referrer) { |
| 578 Local<Value> data) { | |
| 579 Isolate* isolate = context->GetIsolate(); | 625 Isolate* isolate = context->GetIsolate(); |
| 580 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( | 626 ModuleEmbedderData* d = GetModuleDataFromContext(context); |
| 581 External::Cast(*data)->Value()); | 627 auto dir_name_it = |
| 582 Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData()); | 628 d->module_to_directory_map.find(Global<Module>(isolate, referrer)); |
| 629 CHECK(dir_name_it != d->module_to_directory_map.end()); |
| 583 std::string absolute_path = | 630 std::string absolute_path = |
| 584 NormalizePath(ToSTLString(specifier), ToSTLString(dir_name)); | 631 NormalizePath(ToSTLString(specifier), dir_name_it->second); |
| 585 auto it = module_map->find(absolute_path); | 632 auto module_it = d->specifier_to_module_map.find(absolute_path); |
| 586 if (it != module_map->end()) { | 633 CHECK(module_it != d->specifier_to_module_map.end()); |
| 587 return it->second.Get(isolate); | 634 return module_it->second.Get(isolate); |
| 588 } | |
| 589 return MaybeLocal<Module>(); | |
| 590 } | 635 } |
| 591 | 636 |
| 592 } // anonymous namespace | 637 } // anonymous namespace |
| 593 | 638 |
| 594 MaybeLocal<Module> Shell::FetchModuleTree( | 639 MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| 595 Isolate* isolate, const std::string& file_name, | 640 const std::string& file_name) { |
| 596 std::map<std::string, Global<Module>>* module_map) { | |
| 597 DCHECK(IsAbsolutePath(file_name)); | 641 DCHECK(IsAbsolutePath(file_name)); |
| 642 Isolate* isolate = context->GetIsolate(); |
| 598 TryCatch try_catch(isolate); | 643 TryCatch try_catch(isolate); |
| 599 try_catch.SetVerbose(true); | 644 try_catch.SetVerbose(true); |
| 600 Local<String> source_text = ReadFile(isolate, file_name.c_str()); | 645 Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
| 601 if (source_text.IsEmpty()) { | 646 if (source_text.IsEmpty()) { |
| 602 printf("Error reading '%s'\n", file_name.c_str()); | 647 printf("Error reading '%s'\n", file_name.c_str()); |
| 603 Shell::Exit(1); | 648 Shell::Exit(1); |
| 604 } | 649 } |
| 605 ScriptOrigin origin( | 650 ScriptOrigin origin( |
| 606 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) | 651 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
| 607 .ToLocalChecked()); | 652 .ToLocalChecked()); |
| 608 ScriptCompiler::Source source(source_text, origin); | 653 ScriptCompiler::Source source(source_text, origin); |
| 609 Local<Module> module; | 654 Local<Module> module; |
| 610 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { | 655 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
| 611 ReportException(isolate, &try_catch); | 656 ReportException(isolate, &try_catch); |
| 612 return MaybeLocal<Module>(); | 657 return MaybeLocal<Module>(); |
| 613 } | 658 } |
| 614 module_map->insert( | 659 |
| 615 std::make_pair(file_name, Global<Module>(isolate, module))); | 660 ModuleEmbedderData* d = GetModuleDataFromContext(context); |
| 661 CHECK(d->specifier_to_module_map |
| 662 .insert(std::make_pair(file_name, Global<Module>(isolate, module))) |
| 663 .second); |
| 616 | 664 |
| 617 std::string dir_name = DirName(file_name); | 665 std::string dir_name = DirName(file_name); |
| 618 module->SetEmbedderData( | 666 CHECK(d->module_to_directory_map |
| 619 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) | 667 .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) |
| 620 .ToLocalChecked()); | 668 .second); |
| 621 | 669 |
| 622 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { | 670 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
| 623 Local<String> name = module->GetModuleRequest(i); | 671 Local<String> name = module->GetModuleRequest(i); |
| 624 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); | 672 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); |
| 625 if (!module_map->count(absolute_path)) { | 673 if (!d->specifier_to_module_map.count(absolute_path)) { |
| 626 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { | 674 if (FetchModuleTree(context, absolute_path).IsEmpty()) { |
| 627 return MaybeLocal<Module>(); | 675 return MaybeLocal<Module>(); |
| 628 } | 676 } |
| 629 } | 677 } |
| 630 } | 678 } |
| 631 | 679 |
| 632 return module; | 680 return module; |
| 633 } | 681 } |
| 634 | 682 |
| 635 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { | 683 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
| 636 HandleScope handle_scope(isolate); | 684 HandleScope handle_scope(isolate); |
| 637 | 685 |
| 686 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 687 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
| 688 Context::Scope context_scope(realm); |
| 689 |
| 638 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); | 690 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); |
| 639 | 691 |
| 640 Local<Module> root_module; | 692 Local<Module> root_module; |
| 641 std::map<std::string, Global<Module>> module_map; | 693 if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { |
| 642 if (!FetchModuleTree(isolate, absolute_path, &module_map) | |
| 643 .ToLocal(&root_module)) { | |
| 644 return false; | 694 return false; |
| 645 } | 695 } |
| 646 | 696 |
| 647 TryCatch try_catch(isolate); | 697 TryCatch try_catch(isolate); |
| 648 try_catch.SetVerbose(true); | 698 try_catch.SetVerbose(true); |
| 649 | 699 |
| 650 MaybeLocal<Value> maybe_result; | 700 MaybeLocal<Value> maybe_result; |
| 651 { | 701 if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
| 652 PerIsolateData* data = PerIsolateData::Get(isolate); | 702 maybe_result = root_module->Evaluate(realm); |
| 653 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); | 703 EmptyMessageQueues(isolate); |
| 654 Context::Scope context_scope(realm); | |
| 655 | |
| 656 if (root_module->Instantiate(realm, ResolveModuleCallback, | |
| 657 External::New(isolate, &module_map))) { | |
| 658 maybe_result = root_module->Evaluate(realm); | |
| 659 EmptyMessageQueues(isolate); | |
| 660 } | |
| 661 } | 704 } |
| 662 Local<Value> result; | 705 Local<Value> result; |
| 663 if (!maybe_result.ToLocal(&result)) { | 706 if (!maybe_result.ToLocal(&result)) { |
| 664 DCHECK(try_catch.HasCaught()); | 707 DCHECK(try_catch.HasCaught()); |
| 665 // Print errors that happened during execution. | 708 // Print errors that happened during execution. |
| 666 ReportException(isolate, &try_catch); | 709 ReportException(isolate, &try_catch); |
| 667 return false; | 710 return false; |
| 668 } | 711 } |
| 669 DCHECK(!try_catch.HasCaught()); | 712 DCHECK(!try_catch.HasCaught()); |
| 670 return true; | 713 return true; |
| 671 } | 714 } |
| 672 | 715 |
| 673 PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) { | 716 PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) { |
| 674 data_->realm_count_ = 1; | 717 data_->realm_count_ = 1; |
| 675 data_->realm_current_ = 0; | 718 data_->realm_current_ = 0; |
| 676 data_->realm_switch_ = 0; | 719 data_->realm_switch_ = 0; |
| 677 data_->realms_ = new Global<Context>[1]; | 720 data_->realms_ = new Global<Context>[1]; |
| 678 data_->realms_[0].Reset(data_->isolate_, | 721 data_->realms_[0].Reset(data_->isolate_, |
| 679 data_->isolate_->GetEnteredContext()); | 722 data_->isolate_->GetEnteredContext()); |
| 680 } | 723 } |
| 681 | 724 |
| 682 | 725 |
| 683 PerIsolateData::RealmScope::~RealmScope() { | 726 PerIsolateData::RealmScope::~RealmScope() { |
| 684 // Drop realms to avoid keeping them alive. | 727 // Drop realms to avoid keeping them alive. |
| 685 for (int i = 0; i < data_->realm_count_; ++i) | 728 for (int i = 0; i < data_->realm_count_; ++i) { |
| 686 data_->realms_[i].Reset(); | 729 Global<Context>& realm = data_->realms_[i]; |
| 730 if (realm.IsEmpty()) continue; |
| 731 DisposeModuleEmbedderData(realm.Get(data_->isolate_)); |
| 732 // TODO(adamk): No need to reset manually, Globals reset when destructed. |
| 733 realm.Reset(); |
| 734 } |
| 687 delete[] data_->realms_; | 735 delete[] data_->realms_; |
| 736 // TODO(adamk): No need to reset manually, Globals reset when destructed. |
| 688 if (!data_->realm_shared_.IsEmpty()) | 737 if (!data_->realm_shared_.IsEmpty()) |
| 689 data_->realm_shared_.Reset(); | 738 data_->realm_shared_.Reset(); |
| 690 } | 739 } |
| 691 | 740 |
| 692 | 741 |
| 693 int PerIsolateData::RealmFind(Local<Context> context) { | 742 int PerIsolateData::RealmFind(Local<Context> context) { |
| 694 for (int i = 0; i < realm_count_; ++i) { | 743 for (int i = 0; i < realm_count_; ++i) { |
| 695 if (realms_[i] == context) return i; | 744 if (realms_[i] == context) return i; |
| 696 } | 745 } |
| 697 return -1; | 746 return -1; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 old_realms[i].Reset(); | 829 old_realms[i].Reset(); |
| 781 } | 830 } |
| 782 delete[] old_realms; | 831 delete[] old_realms; |
| 783 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); | 832 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); |
| 784 Local<Context> context = Context::New(isolate, NULL, global_template); | 833 Local<Context> context = Context::New(isolate, NULL, global_template); |
| 785 if (context.IsEmpty()) { | 834 if (context.IsEmpty()) { |
| 786 DCHECK(try_catch.HasCaught()); | 835 DCHECK(try_catch.HasCaught()); |
| 787 try_catch.ReThrow(); | 836 try_catch.ReThrow(); |
| 788 return MaybeLocal<Context>(); | 837 return MaybeLocal<Context>(); |
| 789 } | 838 } |
| 839 InitializeModuleEmbedderData(context); |
| 790 data->realms_[index].Reset(isolate, context); | 840 data->realms_[index].Reset(isolate, context); |
| 791 args.GetReturnValue().Set(index); | 841 args.GetReturnValue().Set(index); |
| 792 return context; | 842 return context; |
| 793 } | 843 } |
| 794 | 844 |
| 795 // Realm.create() creates a new realm with a distinct security token | 845 // Realm.create() creates a new realm with a distinct security token |
| 796 // and returns its index. | 846 // and returns its index. |
| 797 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) { | 847 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 798 CreateRealm(args); | 848 CreateRealm(args); |
| 799 } | 849 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 813 void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) { | 863 void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 814 Isolate* isolate = args.GetIsolate(); | 864 Isolate* isolate = args.GetIsolate(); |
| 815 PerIsolateData* data = PerIsolateData::Get(isolate); | 865 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 816 int index = data->RealmIndexOrThrow(args, 0); | 866 int index = data->RealmIndexOrThrow(args, 0); |
| 817 if (index == -1) return; | 867 if (index == -1) return; |
| 818 if (index == 0 || | 868 if (index == 0 || |
| 819 index == data->realm_current_ || index == data->realm_switch_) { | 869 index == data->realm_current_ || index == data->realm_switch_) { |
| 820 Throw(args.GetIsolate(), "Invalid realm index"); | 870 Throw(args.GetIsolate(), "Invalid realm index"); |
| 821 return; | 871 return; |
| 822 } | 872 } |
| 873 DisposeModuleEmbedderData(data->realms_[index].Get(isolate)); |
| 823 data->realms_[index].Reset(); | 874 data->realms_[index].Reset(); |
| 824 isolate->ContextDisposedNotification(); | 875 isolate->ContextDisposedNotification(); |
| 825 isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime()); | 876 isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime()); |
| 826 } | 877 } |
| 827 | 878 |
| 828 | 879 |
| 829 // Realm.switch(i) switches to the realm i for consecutive interactive inputs. | 880 // Realm.switch(i) switches to the realm i for consecutive interactive inputs. |
| 830 void Shell::RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) { | 881 void Shell::RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 831 Isolate* isolate = args.GetIsolate(); | 882 Isolate* isolate = args.GetIsolate(); |
| 832 PerIsolateData* data = PerIsolateData::Get(isolate); | 883 PerIsolateData* data = PerIsolateData::Get(isolate); |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 | 1532 |
| 1482 | 1533 |
| 1483 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { | 1534 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { |
| 1484 // This needs to be a critical section since this is not thread-safe | 1535 // This needs to be a critical section since this is not thread-safe |
| 1485 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer()); | 1536 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer()); |
| 1486 // Initialize the global objects | 1537 // Initialize the global objects |
| 1487 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); | 1538 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); |
| 1488 EscapableHandleScope handle_scope(isolate); | 1539 EscapableHandleScope handle_scope(isolate); |
| 1489 Local<Context> context = Context::New(isolate, NULL, global_template); | 1540 Local<Context> context = Context::New(isolate, NULL, global_template); |
| 1490 DCHECK(!context.IsEmpty()); | 1541 DCHECK(!context.IsEmpty()); |
| 1542 InitializeModuleEmbedderData(context); |
| 1491 Context::Scope scope(context); | 1543 Context::Scope scope(context); |
| 1492 | 1544 |
| 1493 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory(); | 1545 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory(); |
| 1494 i::JSArguments js_args = i::FLAG_js_arguments; | 1546 i::JSArguments js_args = i::FLAG_js_arguments; |
| 1495 i::Handle<i::FixedArray> arguments_array = | 1547 i::Handle<i::FixedArray> arguments_array = |
| 1496 factory->NewFixedArray(js_args.argc); | 1548 factory->NewFixedArray(js_args.argc); |
| 1497 for (int j = 0; j < js_args.argc; j++) { | 1549 for (int j = 0; j < js_args.argc; j++) { |
| 1498 i::Handle<i::String> arg = | 1550 i::Handle<i::String> arg = |
| 1499 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked(); | 1551 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked(); |
| 1500 arguments_array->set(j, *arg); | 1552 arguments_array->set(j, *arg); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1806 Isolate::Scope iscope(isolate); | 1858 Isolate::Scope iscope(isolate); |
| 1807 { | 1859 { |
| 1808 HandleScope scope(isolate); | 1860 HandleScope scope(isolate); |
| 1809 PerIsolateData data(isolate); | 1861 PerIsolateData data(isolate); |
| 1810 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 1862 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
| 1811 { | 1863 { |
| 1812 Context::Scope cscope(context); | 1864 Context::Scope cscope(context); |
| 1813 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1865 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 1814 Execute(isolate); | 1866 Execute(isolate); |
| 1815 } | 1867 } |
| 1868 DisposeModuleEmbedderData(context); |
| 1816 } | 1869 } |
| 1817 Shell::CollectGarbage(isolate); | 1870 Shell::CollectGarbage(isolate); |
| 1818 } | 1871 } |
| 1819 done_semaphore_.Signal(); | 1872 done_semaphore_.Signal(); |
| 1820 } | 1873 } |
| 1821 | 1874 |
| 1822 isolate->Dispose(); | 1875 isolate->Dispose(); |
| 1823 } | 1876 } |
| 1824 | 1877 |
| 1825 | 1878 |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2065 if (Shell::DeserializeValue(isolate, *data, &offset) | 2118 if (Shell::DeserializeValue(isolate, *data, &offset) |
| 2066 .ToLocal(&data_value)) { | 2119 .ToLocal(&data_value)) { |
| 2067 Local<Value> argv[] = {data_value}; | 2120 Local<Value> argv[] = {data_value}; |
| 2068 (void)onmessage_fun->Call(context, global, 1, argv); | 2121 (void)onmessage_fun->Call(context, global, 1, argv); |
| 2069 } | 2122 } |
| 2070 delete data; | 2123 delete data; |
| 2071 } | 2124 } |
| 2072 } | 2125 } |
| 2073 } | 2126 } |
| 2074 } | 2127 } |
| 2128 DisposeModuleEmbedderData(context); |
| 2075 } | 2129 } |
| 2076 Shell::CollectGarbage(isolate); | 2130 Shell::CollectGarbage(isolate); |
| 2077 } | 2131 } |
| 2078 isolate->Dispose(); | 2132 isolate->Dispose(); |
| 2079 | 2133 |
| 2080 // Post NULL to wake the thread waiting on GetMessage() if there is one. | 2134 // Post NULL to wake the thread waiting on GetMessage() if there is one. |
| 2081 out_queue_.Enqueue(NULL); | 2135 out_queue_.Enqueue(NULL); |
| 2082 out_semaphore_.Signal(); | 2136 out_semaphore_.Signal(); |
| 2083 } | 2137 } |
| 2084 | 2138 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2248 Local<Context> context = CreateEvaluationContext(isolate); | 2302 Local<Context> context = CreateEvaluationContext(isolate); |
| 2249 if (last_run && options.use_interactive_shell()) { | 2303 if (last_run && options.use_interactive_shell()) { |
| 2250 // Keep using the same context in the interactive shell. | 2304 // Keep using the same context in the interactive shell. |
| 2251 evaluation_context_.Reset(isolate, context); | 2305 evaluation_context_.Reset(isolate, context); |
| 2252 } | 2306 } |
| 2253 { | 2307 { |
| 2254 Context::Scope cscope(context); | 2308 Context::Scope cscope(context); |
| 2255 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 2309 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 2256 options.isolate_sources[0].Execute(isolate); | 2310 options.isolate_sources[0].Execute(isolate); |
| 2257 } | 2311 } |
| 2312 DisposeModuleEmbedderData(context); |
| 2258 } | 2313 } |
| 2259 CollectGarbage(isolate); | 2314 CollectGarbage(isolate); |
| 2260 for (int i = 1; i < options.num_isolates; ++i) { | 2315 for (int i = 1; i < options.num_isolates; ++i) { |
| 2261 if (last_run) { | 2316 if (last_run) { |
| 2262 options.isolate_sources[i].JoinThread(); | 2317 options.isolate_sources[i].JoinThread(); |
| 2263 } else { | 2318 } else { |
| 2264 options.isolate_sources[i].WaitForThread(); | 2319 options.isolate_sources[i].WaitForThread(); |
| 2265 } | 2320 } |
| 2266 } | 2321 } |
| 2267 CleanupWorkers(); | 2322 CleanupWorkers(); |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2764 } | 2819 } |
| 2765 | 2820 |
| 2766 } // namespace v8 | 2821 } // namespace v8 |
| 2767 | 2822 |
| 2768 | 2823 |
| 2769 #ifndef GOOGLE3 | 2824 #ifndef GOOGLE3 |
| 2770 int main(int argc, char* argv[]) { | 2825 int main(int argc, char* argv[]) { |
| 2771 return v8::Shell::Main(argc, argv); | 2826 return v8::Shell::Main(argc, argv); |
| 2772 } | 2827 } |
| 2773 #endif | 2828 #endif |
| OLD | NEW |