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