Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: src/d8.cc

Issue 2405313002: [modules] Store Module metadata in per-Context EmbedderData (Closed)
Patch Set: Formatting Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698