| Index: src/d8.cc
|
| diff --git a/src/d8.cc b/src/d8.cc
|
| index c9aaa2b6f0d4a5cdf7f3272236e6a86a54ad8478..8bb3ea11a7c95c4e5964528633ae6d99b530a2d0 100644
|
| --- a/src/d8.cc
|
| +++ b/src/d8.cc
|
| @@ -438,6 +438,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;
|
| {
|
| @@ -446,19 +448,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];
|
| @@ -683,12 +687,10 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
|
| const std::string& file_name) {
|
| DCHECK(IsAbsolutePath(file_name));
|
| Isolate* isolate = context->GetIsolate();
|
| - TryCatch try_catch(isolate);
|
| - try_catch.SetVerbose(true);
|
| 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)
|
| @@ -698,7 +700,6 @@ 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);
|
| return MaybeLocal<Module>();
|
| }
|
|
|
| @@ -725,6 +726,86 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
|
| return module;
|
| }
|
|
|
| +namespace {
|
| +
|
| +struct DynamicImportData {
|
| + 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);
|
| +
|
| + TryCatch try_catch(isolate);
|
| + try_catch.SetVerbose(true);
|
| +
|
| + ModuleEmbedderData* d = GetModuleDataFromContext(realm);
|
| + Local<Module> root_module;
|
| + 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).ToLocal(&root_module)) {
|
| + CHECK(try_catch.HasCaught());
|
| + CHECK(Module::FinishDynamicImportFailure(realm, promise,
|
| + try_catch.Exception()));
|
| + return;
|
| + }
|
| +
|
| + 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);
|
|
|
| @@ -734,14 +815,18 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
|
|
|
| std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
|
|
|
| + TryCatch try_catch(isolate);
|
| + try_catch.SetVerbose(true);
|
| +
|
| Local<Module> root_module;
|
| + MaybeLocal<Value> maybe_exception;
|
| +
|
| if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) {
|
| + CHECK(try_catch.HasCaught());
|
| + ReportException(isolate, &try_catch);
|
| return false;
|
| }
|
|
|
| - TryCatch try_catch(isolate);
|
| - try_catch.SetVerbose(true);
|
| -
|
| MaybeLocal<Value> maybe_result;
|
| if (root_module->Instantiate(realm, ResolveModuleCallback)) {
|
| maybe_result = root_module->Evaluate(realm);
|
| @@ -2164,6 +2249,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();
|
| @@ -2302,6 +2389,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);
|
| @@ -2964,6 +3053,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");
|
|
|