Chromium Code Reviews| Index: src/d8.cc |
| diff --git a/src/d8.cc b/src/d8.cc |
| index 4ab7af6d2c7fedd22e61b098b0d2038285d0f3d2..d1908862502fffc3a321b5a758430fe45f52cb8d 100644 |
| --- a/src/d8.cc |
| +++ b/src/d8.cc |
| @@ -440,6 +440,8 @@ ScriptCompiler::CachedData* CompileForCachedData( |
| } |
| Isolate::CreateParams create_params; |
| create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| + create_params.host_import_module_dynamically_callback_ = |
| + Shell::HostImportModuleDynamically; |
| Isolate* temp_isolate = Isolate::New(create_params); |
| ScriptCompiler::CachedData* result = NULL; |
| { |
| @@ -448,19 +450,21 @@ ScriptCompiler::CachedData* CompileForCachedData( |
| Context::Scope context_scope(Context::New(temp_isolate)); |
| Local<String> source_copy = |
| v8::String::NewFromTwoByte(temp_isolate, source_buffer, |
| - v8::NewStringType::kNormal, |
| - source_length).ToLocalChecked(); |
| + v8::NewStringType::kNormal, source_length) |
| + .ToLocalChecked(); |
| Local<Value> name_copy; |
| if (name_buffer) { |
| - name_copy = v8::String::NewFromTwoByte(temp_isolate, name_buffer, |
| - v8::NewStringType::kNormal, |
| - name_length).ToLocalChecked(); |
| + name_copy = |
| + v8::String::NewFromTwoByte(temp_isolate, name_buffer, |
| + v8::NewStringType::kNormal, name_length) |
| + .ToLocalChecked(); |
| } else { |
| name_copy = v8::Undefined(temp_isolate); |
| } |
| ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); |
| if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source, |
| - compile_options).IsEmpty() && |
| + compile_options) |
| + .IsEmpty() && |
| script_source.GetCachedData()) { |
| int length = script_source.GetCachedData()->length; |
| uint8_t* cache = new uint8_t[length]; |
| @@ -682,7 +686,8 @@ MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, |
| } // anonymous namespace |
| MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| - const std::string& file_name) { |
| + const std::string& file_name, |
| + MaybeLocal<Value>* maybe_exception) { |
| DCHECK(IsAbsolutePath(file_name)); |
| Isolate* isolate = context->GetIsolate(); |
| TryCatch try_catch(isolate); |
| @@ -690,7 +695,7 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| Local<String> source_text = ReadFile(isolate, file_name.c_str()); |
| if (source_text.IsEmpty()) { |
| printf("Error reading '%s'\n", file_name.c_str()); |
| - Shell::Exit(1); |
| + return MaybeLocal<Module>(); |
| } |
| ScriptOrigin origin( |
| String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) |
| @@ -700,7 +705,7 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| ScriptCompiler::Source source(source_text, origin); |
| Local<Module> module; |
| if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { |
| - ReportException(isolate, &try_catch); |
| + *maybe_exception = try_catch.Exception(); |
| return MaybeLocal<Module>(); |
| } |
| @@ -718,7 +723,7 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| Local<String> name = module->GetModuleRequest(i); |
| std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); |
| if (!d->specifier_to_module_map.count(absolute_path)) { |
| - if (FetchModuleTree(context, absolute_path).IsEmpty()) { |
| + if (FetchModuleTree(context, absolute_path, maybe_exception).IsEmpty()) { |
| return MaybeLocal<Module>(); |
| } |
| } |
| @@ -727,6 +732,90 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, |
| return module; |
| } |
| +namespace { |
| + |
| +struct DynamicImportData { |
| + public: |
| + DynamicImportData(Isolate* isolate_, Local<String> referrer_, |
| + Local<String> specifier_, Local<Promise> promise_) |
| + : isolate(isolate_) { |
| + referrer.Reset(isolate, referrer_); |
| + specifier.Reset(isolate, specifier_); |
| + promise.Reset(isolate, promise_); |
| + } |
| + |
| + Isolate* isolate; |
| + Global<String> referrer; |
| + Global<String> specifier; |
| + Global<Promise> promise; |
| +}; |
| + |
| +} // namespace |
| +void Shell::HostImportModuleDynamically(Isolate* isolate, |
| + Local<String> referrer, |
| + Local<String> specifier, |
| + Local<Promise> promise) { |
| + DynamicImportData* data = |
| + new DynamicImportData(isolate, referrer, specifier, promise); |
| + isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data); |
| +} |
| + |
| +void Shell::DoHostImportModuleDynamically(void* import_data) { |
| + std::unique_ptr<DynamicImportData> import_data_( |
| + static_cast<DynamicImportData*>(import_data)); |
| + Isolate* isolate(import_data_->isolate); |
| + HandleScope handle_scope(isolate); |
| + |
| + Local<String> referrer(import_data_->referrer.Get(isolate)); |
| + Local<String> specifier(import_data_->specifier.Get(isolate)); |
| + Local<Promise> promise(import_data_->promise.Get(isolate)); |
| + |
| + PerIsolateData* data = PerIsolateData::Get(isolate); |
| + Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); |
| + Context::Scope context_scope(realm); |
| + |
| + std::string source_url = ToSTLString(referrer); |
| + std::string dir_name = |
| + IsAbsolutePath(source_url) ? DirName(source_url) : GetWorkingDirectory(); |
| + std::string file_name = ToSTLString(specifier); |
| + std::string absolute_path = NormalizePath(file_name.c_str(), dir_name); |
| + |
| + ModuleEmbedderData* d = GetModuleDataFromContext(realm); |
| + Local<Module> root_module; |
| + MaybeLocal<Value> maybe_exception; |
| + auto module_it = d->specifier_to_module_map.find(absolute_path); |
| + if (module_it != d->specifier_to_module_map.end()) { |
| + root_module = module_it->second.Get(isolate); |
| + } else if (!FetchModuleTree(realm, absolute_path, &maybe_exception) |
| + .ToLocal(&root_module)) { |
| + if (!maybe_exception.IsEmpty()) { |
|
adamk
2017/03/17 01:00:13
How could FetchModuleTree fail without an exceptio
gsathya
2017/03/17 01:13:11
Changed to be a CHECK
|
| + CHECK(Module::FinishDynamicImportFailure( |
| + realm, promise, maybe_exception.ToLocalChecked())); |
| + return; |
| + } |
| + } |
| + |
| + TryCatch try_catch(isolate); |
| + try_catch.SetVerbose(true); |
| + |
| + MaybeLocal<Value> maybe_result; |
| + if (root_module->Instantiate(realm, ResolveModuleCallback)) { |
| + maybe_result = root_module->Evaluate(realm); |
| + EmptyMessageQueues(isolate); |
| + } |
| + |
| + Local<Value> result; |
| + if (!maybe_result.ToLocal(&result)) { |
| + DCHECK(try_catch.HasCaught()); |
| + CHECK(Module::FinishDynamicImportFailure(realm, promise, |
| + try_catch.Exception())); |
| + return; |
| + } |
| + |
| + DCHECK(!try_catch.HasCaught()); |
| + CHECK(Module::FinishDynamicImportSuccess(realm, promise, root_module)); |
| +} |
| + |
| bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
| HandleScope handle_scope(isolate); |
| @@ -737,7 +826,15 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { |
| std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); |
| Local<Module> root_module; |
| - if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { |
| + MaybeLocal<Value> maybe_exception; |
| + if (!FetchModuleTree(realm, absolute_path, &maybe_exception) |
| + .ToLocal(&root_module)) { |
| + if (!maybe_exception.IsEmpty()) { |
|
adamk
2017/03/17 01:00:13
Same question here.
gsathya
2017/03/17 01:13:11
Done.
|
| + v8::String::Utf8Value exception(maybe_exception.ToLocalChecked()); |
| + CHECK(*exception); |
| + const char* exception_string = *exception; |
| + printf("%s\n", exception_string); |
| + } |
| return false; |
| } |
| @@ -2166,6 +2263,8 @@ base::Thread::Options SourceGroup::GetThreadOptions() { |
| void SourceGroup::ExecuteInThread() { |
| Isolate::CreateParams create_params; |
| create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| + create_params.host_import_module_dynamically_callback_ = |
| + Shell::HostImportModuleDynamically; |
| Isolate* isolate = Isolate::New(create_params); |
| for (int i = 0; i < Shell::options.stress_runs; ++i) { |
| next_semaphore_.Wait(); |
| @@ -2304,6 +2403,8 @@ void Worker::WaitForThread() { |
| void Worker::ExecuteInThread() { |
| Isolate::CreateParams create_params; |
| create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| + create_params.host_import_module_dynamically_callback_ = |
| + Shell::HostImportModuleDynamically; |
| Isolate* isolate = Isolate::New(create_params); |
| { |
| Isolate::Scope iscope(isolate); |
| @@ -2954,6 +3055,9 @@ int Shell::Main(int argc, char* argv[]) { |
| create_params.add_histogram_sample_callback = AddHistogramSample; |
| } |
| + create_params.host_import_module_dynamically_callback_ = |
| + Shell::HostImportModuleDynamically; |
| + |
| if (i::trap_handler::UseTrapHandler()) { |
| if (!v8::V8::RegisterDefaultSignalHandler()) { |
| fprintf(stderr, "Could not register signal handler"); |