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 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 int name_length = 0; | 433 int name_length = 0; |
434 uint16_t* name_buffer = NULL; | 434 uint16_t* name_buffer = NULL; |
435 if (name->IsString()) { | 435 if (name->IsString()) { |
436 Local<String> name_string = Local<String>::Cast(name); | 436 Local<String> name_string = Local<String>::Cast(name); |
437 name_length = name_string->Length(); | 437 name_length = name_string->Length(); |
438 name_buffer = new uint16_t[name_length]; | 438 name_buffer = new uint16_t[name_length]; |
439 name_string->Write(name_buffer, 0, name_length); | 439 name_string->Write(name_buffer, 0, name_length); |
440 } | 440 } |
441 Isolate::CreateParams create_params; | 441 Isolate::CreateParams create_params; |
442 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 442 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 443 create_params.host_import_module_dynamically_callback_ = |
| 444 Shell::HostImportModuleDynamically; |
443 Isolate* temp_isolate = Isolate::New(create_params); | 445 Isolate* temp_isolate = Isolate::New(create_params); |
444 ScriptCompiler::CachedData* result = NULL; | 446 ScriptCompiler::CachedData* result = NULL; |
445 { | 447 { |
446 Isolate::Scope isolate_scope(temp_isolate); | 448 Isolate::Scope isolate_scope(temp_isolate); |
447 HandleScope handle_scope(temp_isolate); | 449 HandleScope handle_scope(temp_isolate); |
448 Context::Scope context_scope(Context::New(temp_isolate)); | 450 Context::Scope context_scope(Context::New(temp_isolate)); |
449 Local<String> source_copy = | 451 Local<String> source_copy = |
450 v8::String::NewFromTwoByte(temp_isolate, source_buffer, | 452 v8::String::NewFromTwoByte(temp_isolate, source_buffer, |
451 v8::NewStringType::kNormal, | 453 v8::NewStringType::kNormal, source_length) |
452 source_length).ToLocalChecked(); | 454 .ToLocalChecked(); |
453 Local<Value> name_copy; | 455 Local<Value> name_copy; |
454 if (name_buffer) { | 456 if (name_buffer) { |
455 name_copy = v8::String::NewFromTwoByte(temp_isolate, name_buffer, | 457 name_copy = |
456 v8::NewStringType::kNormal, | 458 v8::String::NewFromTwoByte(temp_isolate, name_buffer, |
457 name_length).ToLocalChecked(); | 459 v8::NewStringType::kNormal, name_length) |
| 460 .ToLocalChecked(); |
458 } else { | 461 } else { |
459 name_copy = v8::Undefined(temp_isolate); | 462 name_copy = v8::Undefined(temp_isolate); |
460 } | 463 } |
461 ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); | 464 ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); |
462 if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source, | 465 if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source, |
463 compile_options).IsEmpty() && | 466 compile_options) |
| 467 .IsEmpty() && |
464 script_source.GetCachedData()) { | 468 script_source.GetCachedData()) { |
465 int length = script_source.GetCachedData()->length; | 469 int length = script_source.GetCachedData()->length; |
466 uint8_t* cache = new uint8_t[length]; | 470 uint8_t* cache = new uint8_t[length]; |
467 memcpy(cache, script_source.GetCachedData()->data, length); | 471 memcpy(cache, script_source.GetCachedData()->data, length); |
468 result = new ScriptCompiler::CachedData( | 472 result = new ScriptCompiler::CachedData( |
469 cache, length, ScriptCompiler::CachedData::BufferOwned); | 473 cache, length, ScriptCompiler::CachedData::BufferOwned); |
470 } | 474 } |
471 } | 475 } |
472 temp_isolate->Dispose(); | 476 temp_isolate->Dispose(); |
473 delete[] source_buffer; | 477 delete[] source_buffer; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 if (!d->specifier_to_module_map.count(absolute_path)) { | 724 if (!d->specifier_to_module_map.count(absolute_path)) { |
721 if (FetchModuleTree(context, absolute_path).IsEmpty()) { | 725 if (FetchModuleTree(context, absolute_path).IsEmpty()) { |
722 return MaybeLocal<Module>(); | 726 return MaybeLocal<Module>(); |
723 } | 727 } |
724 } | 728 } |
725 } | 729 } |
726 | 730 |
727 return module; | 731 return module; |
728 } | 732 } |
729 | 733 |
| 734 MaybeLocal<Module> Shell::DynamicFetchModuleTree(Local<Context> context, |
| 735 Local<Promise> promise, |
| 736 const std::string& file_name) { |
| 737 DCHECK(IsAbsolutePath(file_name)); |
| 738 Isolate* isolate = context->GetIsolate(); |
| 739 TryCatch try_catch(isolate); |
| 740 try_catch.SetVerbose(true); |
| 741 |
| 742 Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
| 743 |
| 744 if (source_text.IsEmpty()) { |
| 745 // TODO(gsathya): Create an exception |
| 746 printf("Error reading '%s'\n", file_name.c_str()); |
| 747 return MaybeLocal<Module>(); |
| 748 } |
| 749 |
| 750 ScriptOrigin origin( |
| 751 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
| 752 .ToLocalChecked(), |
| 753 Local<Integer>(), Local<Integer>(), Local<Boolean>(), Local<Integer>(), |
| 754 Local<Value>(), Local<Boolean>(), Local<Boolean>(), True(isolate)); |
| 755 |
| 756 ScriptCompiler::Source source(source_text, origin); |
| 757 Local<Module> module; |
| 758 |
| 759 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
| 760 CHECK(Module::FinishDynamicImportFailure(context, promise, |
| 761 try_catch.Exception())); |
| 762 return MaybeLocal<Module>(); |
| 763 } |
| 764 |
| 765 ModuleEmbedderData* d = GetModuleDataFromContext(context); |
| 766 CHECK(d->specifier_to_module_map |
| 767 .insert(std::make_pair(file_name, Global<Module>(isolate, module))) |
| 768 .second); |
| 769 |
| 770 std::string dir_name = DirName(file_name); |
| 771 CHECK(d->module_to_directory_map |
| 772 .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) |
| 773 .second); |
| 774 |
| 775 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { |
| 776 Local<String> name = module->GetModuleRequest(i); |
| 777 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); |
| 778 if (!d->specifier_to_module_map.count(absolute_path)) { |
| 779 if (DynamicFetchModuleTree(context, promise, absolute_path).IsEmpty()) { |
| 780 return MaybeLocal<Module>(); |
| 781 } |
| 782 } |
| 783 } |
| 784 |
| 785 return module; |
| 786 } |
| 787 |
| 788 namespace { |
| 789 |
| 790 struct DynamicImportData { |
| 791 public: |
| 792 DynamicImportData(Isolate* isolate_, Local<String> referrer_, |
| 793 Local<String> specifier_, Local<Promise> promise_) |
| 794 : isolate(isolate_) { |
| 795 referrer.Reset(isolate, referrer_); |
| 796 specifier.Reset(isolate, specifier_); |
| 797 promise.Reset(isolate, promise_); |
| 798 } |
| 799 |
| 800 Isolate* isolate; |
| 801 Global<String> referrer; |
| 802 Global<String> specifier; |
| 803 Global<Promise> promise; |
| 804 }; |
| 805 |
| 806 } // namespace |
| 807 void Shell::HostImportModuleDynamically(Isolate* isolate, |
| 808 Local<String> referrer, |
| 809 Local<String> specifier, |
| 810 Local<Promise> promise) { |
| 811 DynamicImportData* data = |
| 812 new DynamicImportData(isolate, referrer, specifier, promise); |
| 813 isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data); |
| 814 } |
| 815 |
| 816 void Shell::DoHostImportModuleDynamically(void* import_data) { |
| 817 DynamicImportData* import_data_ = |
| 818 static_cast<DynamicImportData*>(import_data); |
| 819 Isolate* isolate(import_data_->isolate); |
| 820 HandleScope handle_scope(isolate); |
| 821 |
| 822 Local<String> referrer(import_data_->referrer.Get(isolate)); |
| 823 Local<String> specifier(import_data_->specifier.Get(isolate)); |
| 824 Local<Promise> promise(import_data_->promise.Get(isolate)); |
| 825 |
| 826 PerIsolateData* data = PerIsolateData::Get(isolate); |
| 827 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
| 828 Context::Scope context_scope(realm); |
| 829 |
| 830 std::string source_url = ToSTLString(referrer); |
| 831 std::string dir_name = |
| 832 IsAbsolutePath(source_url) ? DirName(source_url) : GetWorkingDirectory(); |
| 833 std::string file_name = ToSTLString(specifier); |
| 834 std::string absolute_path = NormalizePath(file_name.c_str(), dir_name); |
| 835 |
| 836 ModuleEmbedderData* d = GetModuleDataFromContext(realm); |
| 837 Local<Module> root_module; |
| 838 auto module_it = d->specifier_to_module_map.find(absolute_path); |
| 839 if (module_it != d->specifier_to_module_map.end()) { |
| 840 root_module = module_it->second.Get(isolate); |
| 841 } else if (!DynamicFetchModuleTree(realm, promise, absolute_path) |
| 842 .ToLocal(&root_module)) { |
| 843 delete import_data_; |
| 844 return; |
| 845 } |
| 846 |
| 847 TryCatch try_catch(isolate); |
| 848 try_catch.SetVerbose(true); |
| 849 |
| 850 MaybeLocal<Value> maybe_result; |
| 851 if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
| 852 maybe_result = root_module->Evaluate(realm); |
| 853 EmptyMessageQueues(isolate); |
| 854 } |
| 855 |
| 856 Local<Value> result; |
| 857 if (!maybe_result.ToLocal(&result)) { |
| 858 DCHECK(try_catch.HasCaught()); |
| 859 CHECK(Module::FinishDynamicImportFailure(realm, promise, |
| 860 try_catch.Exception())); |
| 861 delete import_data_; |
| 862 return; |
| 863 } |
| 864 |
| 865 DCHECK(!try_catch.HasCaught()); |
| 866 CHECK(Module::FinishDynamicImportSuccess(realm, promise, root_module)); |
| 867 delete import_data_; |
| 868 } |
| 869 |
730 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { | 870 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
731 HandleScope handle_scope(isolate); | 871 HandleScope handle_scope(isolate); |
732 | 872 |
733 PerIsolateData* data = PerIsolateData::Get(isolate); | 873 PerIsolateData* data = PerIsolateData::Get(isolate); |
734 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); | 874 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
735 Context::Scope context_scope(realm); | 875 Context::Scope context_scope(realm); |
736 | 876 |
737 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); | 877 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); |
738 | 878 |
739 Local<Module> root_module; | 879 Local<Module> root_module; |
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 2299 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less |
2160 // which is not enough to parse the big literal expressions used in tests. | 2300 // which is not enough to parse the big literal expressions used in tests. |
2161 // The stack size should be at least StackGuard::kLimitSize + some | 2301 // The stack size should be at least StackGuard::kLimitSize + some |
2162 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 2302 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
2163 return base::Thread::Options("IsolateThread", 2 * MB); | 2303 return base::Thread::Options("IsolateThread", 2 * MB); |
2164 } | 2304 } |
2165 | 2305 |
2166 void SourceGroup::ExecuteInThread() { | 2306 void SourceGroup::ExecuteInThread() { |
2167 Isolate::CreateParams create_params; | 2307 Isolate::CreateParams create_params; |
2168 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 2308 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 2309 create_params.host_import_module_dynamically_callback_ = |
| 2310 Shell::HostImportModuleDynamically; |
2169 Isolate* isolate = Isolate::New(create_params); | 2311 Isolate* isolate = Isolate::New(create_params); |
2170 for (int i = 0; i < Shell::options.stress_runs; ++i) { | 2312 for (int i = 0; i < Shell::options.stress_runs; ++i) { |
2171 next_semaphore_.Wait(); | 2313 next_semaphore_.Wait(); |
2172 { | 2314 { |
2173 Isolate::Scope iscope(isolate); | 2315 Isolate::Scope iscope(isolate); |
2174 { | 2316 { |
2175 HandleScope scope(isolate); | 2317 HandleScope scope(isolate); |
2176 PerIsolateData data(isolate); | 2318 PerIsolateData data(isolate); |
2177 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 2319 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
2178 { | 2320 { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 | 2439 |
2298 void Worker::WaitForThread() { | 2440 void Worker::WaitForThread() { |
2299 Terminate(); | 2441 Terminate(); |
2300 thread_->Join(); | 2442 thread_->Join(); |
2301 } | 2443 } |
2302 | 2444 |
2303 | 2445 |
2304 void Worker::ExecuteInThread() { | 2446 void Worker::ExecuteInThread() { |
2305 Isolate::CreateParams create_params; | 2447 Isolate::CreateParams create_params; |
2306 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 2448 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 2449 create_params.host_import_module_dynamically_callback_ = |
| 2450 Shell::HostImportModuleDynamically; |
2307 Isolate* isolate = Isolate::New(create_params); | 2451 Isolate* isolate = Isolate::New(create_params); |
2308 { | 2452 { |
2309 Isolate::Scope iscope(isolate); | 2453 Isolate::Scope iscope(isolate); |
2310 { | 2454 { |
2311 HandleScope scope(isolate); | 2455 HandleScope scope(isolate); |
2312 PerIsolateData data(isolate); | 2456 PerIsolateData data(isolate); |
2313 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 2457 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
2314 { | 2458 { |
2315 Context::Scope cscope(context); | 2459 Context::Scope cscope(context); |
2316 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 2460 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2947 base::SysInfo::AmountOfPhysicalMemory(), | 3091 base::SysInfo::AmountOfPhysicalMemory(), |
2948 base::SysInfo::AmountOfVirtualMemory()); | 3092 base::SysInfo::AmountOfVirtualMemory()); |
2949 | 3093 |
2950 Shell::counter_map_ = new CounterMap(); | 3094 Shell::counter_map_ = new CounterMap(); |
2951 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp || i::FLAG_gc_stats) { | 3095 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp || i::FLAG_gc_stats) { |
2952 create_params.counter_lookup_callback = LookupCounter; | 3096 create_params.counter_lookup_callback = LookupCounter; |
2953 create_params.create_histogram_callback = CreateHistogram; | 3097 create_params.create_histogram_callback = CreateHistogram; |
2954 create_params.add_histogram_sample_callback = AddHistogramSample; | 3098 create_params.add_histogram_sample_callback = AddHistogramSample; |
2955 } | 3099 } |
2956 | 3100 |
| 3101 create_params.host_import_module_dynamically_callback_ = |
| 3102 Shell::HostImportModuleDynamically; |
| 3103 |
2957 if (i::trap_handler::UseTrapHandler()) { | 3104 if (i::trap_handler::UseTrapHandler()) { |
2958 if (!v8::V8::RegisterDefaultSignalHandler()) { | 3105 if (!v8::V8::RegisterDefaultSignalHandler()) { |
2959 fprintf(stderr, "Could not register signal handler"); | 3106 fprintf(stderr, "Could not register signal handler"); |
2960 exit(1); | 3107 exit(1); |
2961 } | 3108 } |
2962 } | 3109 } |
2963 | 3110 |
2964 Isolate* isolate = Isolate::New(create_params); | 3111 Isolate* isolate = Isolate::New(create_params); |
2965 { | 3112 { |
2966 Isolate::Scope scope(isolate); | 3113 Isolate::Scope scope(isolate); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 } | 3190 } |
3044 | 3191 |
3045 } // namespace v8 | 3192 } // namespace v8 |
3046 | 3193 |
3047 | 3194 |
3048 #ifndef GOOGLE3 | 3195 #ifndef GOOGLE3 |
3049 int main(int argc, char* argv[]) { | 3196 int main(int argc, char* argv[]) { |
3050 return v8::Shell::Main(argc, argv); | 3197 return v8::Shell::Main(argc, argv); |
3051 } | 3198 } |
3052 #endif | 3199 #endif |
OLD | NEW |