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 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 int name_length = 0; | 431 int name_length = 0; |
432 uint16_t* name_buffer = NULL; | 432 uint16_t* name_buffer = NULL; |
433 if (name->IsString()) { | 433 if (name->IsString()) { |
434 Local<String> name_string = Local<String>::Cast(name); | 434 Local<String> name_string = Local<String>::Cast(name); |
435 name_length = name_string->Length(); | 435 name_length = name_string->Length(); |
436 name_buffer = new uint16_t[name_length]; | 436 name_buffer = new uint16_t[name_length]; |
437 name_string->Write(name_buffer, 0, name_length); | 437 name_string->Write(name_buffer, 0, name_length); |
438 } | 438 } |
439 Isolate::CreateParams create_params; | 439 Isolate::CreateParams create_params; |
440 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 440 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 441 create_params.host_import_module_dynamically_callback_ = |
| 442 Shell::HostImportModuleDynamically; |
441 Isolate* temp_isolate = Isolate::New(create_params); | 443 Isolate* temp_isolate = Isolate::New(create_params); |
442 ScriptCompiler::CachedData* result = NULL; | 444 ScriptCompiler::CachedData* result = NULL; |
443 { | 445 { |
444 Isolate::Scope isolate_scope(temp_isolate); | 446 Isolate::Scope isolate_scope(temp_isolate); |
445 HandleScope handle_scope(temp_isolate); | 447 HandleScope handle_scope(temp_isolate); |
446 Context::Scope context_scope(Context::New(temp_isolate)); | 448 Context::Scope context_scope(Context::New(temp_isolate)); |
447 Local<String> source_copy = | 449 Local<String> source_copy = |
448 v8::String::NewFromTwoByte(temp_isolate, source_buffer, | 450 v8::String::NewFromTwoByte(temp_isolate, source_buffer, |
449 v8::NewStringType::kNormal, | 451 v8::NewStringType::kNormal, source_length) |
450 source_length).ToLocalChecked(); | 452 .ToLocalChecked(); |
451 Local<Value> name_copy; | 453 Local<Value> name_copy; |
452 if (name_buffer) { | 454 if (name_buffer) { |
453 name_copy = v8::String::NewFromTwoByte(temp_isolate, name_buffer, | 455 name_copy = |
454 v8::NewStringType::kNormal, | 456 v8::String::NewFromTwoByte(temp_isolate, name_buffer, |
455 name_length).ToLocalChecked(); | 457 v8::NewStringType::kNormal, name_length) |
| 458 .ToLocalChecked(); |
456 } else { | 459 } else { |
457 name_copy = v8::Undefined(temp_isolate); | 460 name_copy = v8::Undefined(temp_isolate); |
458 } | 461 } |
459 ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); | 462 ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); |
460 if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source, | 463 if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source, |
461 compile_options).IsEmpty() && | 464 compile_options) |
| 465 .IsEmpty() && |
462 script_source.GetCachedData()) { | 466 script_source.GetCachedData()) { |
463 int length = script_source.GetCachedData()->length; | 467 int length = script_source.GetCachedData()->length; |
464 uint8_t* cache = new uint8_t[length]; | 468 uint8_t* cache = new uint8_t[length]; |
465 memcpy(cache, script_source.GetCachedData()->data, length); | 469 memcpy(cache, script_source.GetCachedData()->data, length); |
466 result = new ScriptCompiler::CachedData( | 470 result = new ScriptCompiler::CachedData( |
467 cache, length, ScriptCompiler::CachedData::BufferOwned); | 471 cache, length, ScriptCompiler::CachedData::BufferOwned); |
468 } | 472 } |
469 } | 473 } |
470 temp_isolate->Dispose(); | 474 temp_isolate->Dispose(); |
471 delete[] source_buffer; | 475 delete[] source_buffer; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 CHECK(module_it != d->specifier_to_module_map.end()); | 680 CHECK(module_it != d->specifier_to_module_map.end()); |
677 return module_it->second.Get(isolate); | 681 return module_it->second.Get(isolate); |
678 } | 682 } |
679 | 683 |
680 } // anonymous namespace | 684 } // anonymous namespace |
681 | 685 |
682 MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, | 686 MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
683 const std::string& file_name) { | 687 const std::string& file_name) { |
684 DCHECK(IsAbsolutePath(file_name)); | 688 DCHECK(IsAbsolutePath(file_name)); |
685 Isolate* isolate = context->GetIsolate(); | 689 Isolate* isolate = context->GetIsolate(); |
686 TryCatch try_catch(isolate); | |
687 try_catch.SetVerbose(true); | |
688 Local<String> source_text = ReadFile(isolate, file_name.c_str()); | 690 Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
689 if (source_text.IsEmpty()) { | 691 if (source_text.IsEmpty()) { |
690 printf("Error reading '%s'\n", file_name.c_str()); | 692 printf("Error reading '%s'\n", file_name.c_str()); |
691 Shell::Exit(1); | 693 return MaybeLocal<Module>(); |
692 } | 694 } |
693 ScriptOrigin origin( | 695 ScriptOrigin origin( |
694 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) | 696 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
695 .ToLocalChecked(), | 697 .ToLocalChecked(), |
696 Local<Integer>(), Local<Integer>(), Local<Boolean>(), Local<Integer>(), | 698 Local<Integer>(), Local<Integer>(), Local<Boolean>(), Local<Integer>(), |
697 Local<Value>(), Local<Boolean>(), Local<Boolean>(), True(isolate)); | 699 Local<Value>(), Local<Boolean>(), Local<Boolean>(), True(isolate)); |
698 ScriptCompiler::Source source(source_text, origin); | 700 ScriptCompiler::Source source(source_text, origin); |
699 Local<Module> module; | 701 Local<Module> module; |
700 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { | 702 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
701 ReportException(isolate, &try_catch); | |
702 return MaybeLocal<Module>(); | 703 return MaybeLocal<Module>(); |
703 } | 704 } |
704 | 705 |
705 ModuleEmbedderData* d = GetModuleDataFromContext(context); | 706 ModuleEmbedderData* d = GetModuleDataFromContext(context); |
706 CHECK(d->specifier_to_module_map | 707 CHECK(d->specifier_to_module_map |
707 .insert(std::make_pair(file_name, Global<Module>(isolate, module))) | 708 .insert(std::make_pair(file_name, Global<Module>(isolate, module))) |
708 .second); | 709 .second); |
709 | 710 |
710 std::string dir_name = DirName(file_name); | 711 std::string dir_name = DirName(file_name); |
711 CHECK(d->module_to_directory_map | 712 CHECK(d->module_to_directory_map |
712 .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) | 713 .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) |
713 .second); | 714 .second); |
714 | 715 |
715 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { | 716 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
716 Local<String> name = module->GetModuleRequest(i); | 717 Local<String> name = module->GetModuleRequest(i); |
717 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); | 718 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); |
718 if (!d->specifier_to_module_map.count(absolute_path)) { | 719 if (!d->specifier_to_module_map.count(absolute_path)) { |
719 if (FetchModuleTree(context, absolute_path).IsEmpty()) { | 720 if (FetchModuleTree(context, absolute_path).IsEmpty()) { |
720 return MaybeLocal<Module>(); | 721 return MaybeLocal<Module>(); |
721 } | 722 } |
722 } | 723 } |
723 } | 724 } |
724 | 725 |
725 return module; | 726 return module; |
726 } | 727 } |
727 | 728 |
| 729 namespace { |
| 730 |
| 731 struct DynamicImportData { |
| 732 DynamicImportData(Isolate* isolate_, Local<String> referrer_, |
| 733 Local<String> specifier_, Local<Promise> promise_) |
| 734 : isolate(isolate_) { |
| 735 referrer.Reset(isolate, referrer_); |
| 736 specifier.Reset(isolate, specifier_); |
| 737 promise.Reset(isolate, promise_); |
| 738 } |
| 739 |
| 740 Isolate* isolate; |
| 741 Global<String> referrer; |
| 742 Global<String> specifier; |
| 743 Global<Promise> promise; |
| 744 }; |
| 745 |
| 746 } // namespace |
| 747 void Shell::HostImportModuleDynamically(Isolate* isolate, |
| 748 Local<String> referrer, |
| 749 Local<String> specifier, |
| 750 Local<Promise> promise) { |
| 751 DynamicImportData* data = |
| 752 new DynamicImportData(isolate, referrer, specifier, promise); |
| 753 isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data); |
| 754 } |
| 755 |
| 756 void Shell::DoHostImportModuleDynamically(void* import_data) { |
| 757 std::unique_ptr<DynamicImportData> import_data_( |
| 758 static_cast<DynamicImportData*>(import_data)); |
| 759 Isolate* isolate(import_data_->isolate); |
| 760 HandleScope handle_scope(isolate); |
| 761 |
| 762 Local<String> referrer(import_data_->referrer.Get(isolate)); |
| 763 Local<String> specifier(import_data_->specifier.Get(isolate)); |
| 764 Local<Promise> promise(import_data_->promise.Get(isolate)); |
| 765 |
| 766 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 767 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
| 768 Context::Scope context_scope(realm); |
| 769 |
| 770 std::string source_url = ToSTLString(referrer); |
| 771 std::string dir_name = |
| 772 IsAbsolutePath(source_url) ? DirName(source_url) : GetWorkingDirectory(); |
| 773 std::string file_name = ToSTLString(specifier); |
| 774 std::string absolute_path = NormalizePath(file_name.c_str(), dir_name); |
| 775 |
| 776 TryCatch try_catch(isolate); |
| 777 try_catch.SetVerbose(true); |
| 778 |
| 779 ModuleEmbedderData* d = GetModuleDataFromContext(realm); |
| 780 Local<Module> root_module; |
| 781 auto module_it = d->specifier_to_module_map.find(absolute_path); |
| 782 if (module_it != d->specifier_to_module_map.end()) { |
| 783 root_module = module_it->second.Get(isolate); |
| 784 } else if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { |
| 785 CHECK(try_catch.HasCaught()); |
| 786 CHECK(Module::FinishDynamicImportFailure(realm, promise, |
| 787 try_catch.Exception())); |
| 788 return; |
| 789 } |
| 790 |
| 791 MaybeLocal<Value> maybe_result; |
| 792 if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
| 793 maybe_result = root_module->Evaluate(realm); |
| 794 EmptyMessageQueues(isolate); |
| 795 } |
| 796 |
| 797 Local<Value> result; |
| 798 if (!maybe_result.ToLocal(&result)) { |
| 799 DCHECK(try_catch.HasCaught()); |
| 800 CHECK(Module::FinishDynamicImportFailure(realm, promise, |
| 801 try_catch.Exception())); |
| 802 return; |
| 803 } |
| 804 |
| 805 DCHECK(!try_catch.HasCaught()); |
| 806 CHECK(Module::FinishDynamicImportSuccess(realm, promise, root_module)); |
| 807 } |
| 808 |
728 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { | 809 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
729 HandleScope handle_scope(isolate); | 810 HandleScope handle_scope(isolate); |
730 | 811 |
731 PerIsolateData* data = PerIsolateData::Get(isolate); | 812 PerIsolateData* data = PerIsolateData::Get(isolate); |
732 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); | 813 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
733 Context::Scope context_scope(realm); | 814 Context::Scope context_scope(realm); |
734 | 815 |
735 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); | 816 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); |
736 | 817 |
737 Local<Module> root_module; | |
738 if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { | |
739 return false; | |
740 } | |
741 | |
742 TryCatch try_catch(isolate); | 818 TryCatch try_catch(isolate); |
743 try_catch.SetVerbose(true); | 819 try_catch.SetVerbose(true); |
744 | 820 |
| 821 Local<Module> root_module; |
| 822 MaybeLocal<Value> maybe_exception; |
| 823 |
| 824 if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { |
| 825 CHECK(try_catch.HasCaught()); |
| 826 ReportException(isolate, &try_catch); |
| 827 return false; |
| 828 } |
| 829 |
745 MaybeLocal<Value> maybe_result; | 830 MaybeLocal<Value> maybe_result; |
746 if (root_module->Instantiate(realm, ResolveModuleCallback)) { | 831 if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
747 maybe_result = root_module->Evaluate(realm); | 832 maybe_result = root_module->Evaluate(realm); |
748 EmptyMessageQueues(isolate); | 833 EmptyMessageQueues(isolate); |
749 } | 834 } |
750 Local<Value> result; | 835 Local<Value> result; |
751 if (!maybe_result.ToLocal(&result)) { | 836 if (!maybe_result.ToLocal(&result)) { |
752 DCHECK(try_catch.HasCaught()); | 837 DCHECK(try_catch.HasCaught()); |
753 // Print errors that happened during execution. | 838 // Print errors that happened during execution. |
754 ReportException(isolate, &try_catch); | 839 ReportException(isolate, &try_catch); |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 2242 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less |
2158 // which is not enough to parse the big literal expressions used in tests. | 2243 // which is not enough to parse the big literal expressions used in tests. |
2159 // The stack size should be at least StackGuard::kLimitSize + some | 2244 // The stack size should be at least StackGuard::kLimitSize + some |
2160 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 2245 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
2161 return base::Thread::Options("IsolateThread", 2 * MB); | 2246 return base::Thread::Options("IsolateThread", 2 * MB); |
2162 } | 2247 } |
2163 | 2248 |
2164 void SourceGroup::ExecuteInThread() { | 2249 void SourceGroup::ExecuteInThread() { |
2165 Isolate::CreateParams create_params; | 2250 Isolate::CreateParams create_params; |
2166 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 2251 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 2252 create_params.host_import_module_dynamically_callback_ = |
| 2253 Shell::HostImportModuleDynamically; |
2167 Isolate* isolate = Isolate::New(create_params); | 2254 Isolate* isolate = Isolate::New(create_params); |
2168 for (int i = 0; i < Shell::options.stress_runs; ++i) { | 2255 for (int i = 0; i < Shell::options.stress_runs; ++i) { |
2169 next_semaphore_.Wait(); | 2256 next_semaphore_.Wait(); |
2170 { | 2257 { |
2171 Isolate::Scope iscope(isolate); | 2258 Isolate::Scope iscope(isolate); |
2172 { | 2259 { |
2173 HandleScope scope(isolate); | 2260 HandleScope scope(isolate); |
2174 PerIsolateData data(isolate); | 2261 PerIsolateData data(isolate); |
2175 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 2262 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
2176 { | 2263 { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 | 2382 |
2296 void Worker::WaitForThread() { | 2383 void Worker::WaitForThread() { |
2297 Terminate(); | 2384 Terminate(); |
2298 thread_->Join(); | 2385 thread_->Join(); |
2299 } | 2386 } |
2300 | 2387 |
2301 | 2388 |
2302 void Worker::ExecuteInThread() { | 2389 void Worker::ExecuteInThread() { |
2303 Isolate::CreateParams create_params; | 2390 Isolate::CreateParams create_params; |
2304 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 2391 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 2392 create_params.host_import_module_dynamically_callback_ = |
| 2393 Shell::HostImportModuleDynamically; |
2305 Isolate* isolate = Isolate::New(create_params); | 2394 Isolate* isolate = Isolate::New(create_params); |
2306 { | 2395 { |
2307 Isolate::Scope iscope(isolate); | 2396 Isolate::Scope iscope(isolate); |
2308 { | 2397 { |
2309 HandleScope scope(isolate); | 2398 HandleScope scope(isolate); |
2310 PerIsolateData data(isolate); | 2399 PerIsolateData data(isolate); |
2311 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 2400 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
2312 { | 2401 { |
2313 Context::Scope cscope(context); | 2402 Context::Scope cscope(context); |
2314 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 2403 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2957 base::SysInfo::AmountOfPhysicalMemory(), | 3046 base::SysInfo::AmountOfPhysicalMemory(), |
2958 base::SysInfo::AmountOfVirtualMemory()); | 3047 base::SysInfo::AmountOfVirtualMemory()); |
2959 | 3048 |
2960 Shell::counter_map_ = new CounterMap(); | 3049 Shell::counter_map_ = new CounterMap(); |
2961 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp || i::FLAG_gc_stats) { | 3050 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp || i::FLAG_gc_stats) { |
2962 create_params.counter_lookup_callback = LookupCounter; | 3051 create_params.counter_lookup_callback = LookupCounter; |
2963 create_params.create_histogram_callback = CreateHistogram; | 3052 create_params.create_histogram_callback = CreateHistogram; |
2964 create_params.add_histogram_sample_callback = AddHistogramSample; | 3053 create_params.add_histogram_sample_callback = AddHistogramSample; |
2965 } | 3054 } |
2966 | 3055 |
| 3056 create_params.host_import_module_dynamically_callback_ = |
| 3057 Shell::HostImportModuleDynamically; |
| 3058 |
2967 if (i::trap_handler::UseTrapHandler()) { | 3059 if (i::trap_handler::UseTrapHandler()) { |
2968 if (!v8::V8::RegisterDefaultSignalHandler()) { | 3060 if (!v8::V8::RegisterDefaultSignalHandler()) { |
2969 fprintf(stderr, "Could not register signal handler"); | 3061 fprintf(stderr, "Could not register signal handler"); |
2970 exit(1); | 3062 exit(1); |
2971 } | 3063 } |
2972 } | 3064 } |
2973 | 3065 |
2974 Isolate* isolate = Isolate::New(create_params); | 3066 Isolate* isolate = Isolate::New(create_params); |
2975 { | 3067 { |
2976 Isolate::Scope scope(isolate); | 3068 Isolate::Scope scope(isolate); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3053 } | 3145 } |
3054 | 3146 |
3055 } // namespace v8 | 3147 } // namespace v8 |
3056 | 3148 |
3057 | 3149 |
3058 #ifndef GOOGLE3 | 3150 #ifndef GOOGLE3 |
3059 int main(int argc, char* argv[]) { | 3151 int main(int argc, char* argv[]) { |
3060 return v8::Shell::Main(argc, argv); | 3152 return v8::Shell::Main(argc, argv); |
3061 } | 3153 } |
3062 #endif | 3154 #endif |
OLD | NEW |