Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: src/d8.cc

Issue 2703563002: [ESNext] Implement DynamicImportCall (Closed)
Patch Set: use function_closure Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 4ab7af6d2c7fedd22e61b098b0d2038285d0f3d2..073290e8e27d10800aba8c8370b0ac479d029aec 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];
@@ -727,6 +731,142 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
return module;
}
+MaybeLocal<Module> Shell::DynamicFetchModuleTree(Local<Context> context,
+ Local<Promise> promise,
+ 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()) {
+ // TODO(gsathya): Create an exception
+ printf("Error reading '%s'\n", file_name.c_str());
+ return MaybeLocal<Module>();
+ }
+
+ ScriptOrigin origin(
+ String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal)
+ .ToLocalChecked(),
+ Local<Integer>(), Local<Integer>(), Local<Boolean>(), Local<Integer>(),
+ Local<Value>(), Local<Boolean>(), Local<Boolean>(), True(isolate));
+
+ ScriptCompiler::Source source(source_text, origin);
+ Local<Module> module;
+
+ if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
+ CHECK(Module::FinishDynamicImportFailure(context, promise,
adamk 2017/03/16 21:41:23 I think you should factor out the exception report
gsathya 2017/03/17 00:47:22 Done.
+ try_catch.Exception()));
+ return MaybeLocal<Module>();
+ }
+
+ ModuleEmbedderData* d = GetModuleDataFromContext(context);
+ CHECK(d->specifier_to_module_map
+ .insert(std::make_pair(file_name, Global<Module>(isolate, module)))
+ .second);
+
+ std::string dir_name = DirName(file_name);
+ CHECK(d->module_to_directory_map
+ .insert(std::make_pair(Global<Module>(isolate, module), dir_name))
+ .second);
+
+ for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) {
+ 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 (DynamicFetchModuleTree(context, promise, absolute_path).IsEmpty()) {
+ return MaybeLocal<Module>();
+ }
+ }
+ }
+
+ 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) {
+ DynamicImportData* import_data_ =
adamk 2017/03/16 21:41:23 This should be a std::unique_ptr so it'll get auto
gsathya 2017/03/17 00:47:22 Done.
+ 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;
+ 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 (!DynamicFetchModuleTree(realm, promise, absolute_path)
+ .ToLocal(&root_module)) {
+ delete import_data_;
+ 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()));
+ delete import_data_;
+ return;
+ }
+
+ DCHECK(!try_catch.HasCaught());
+ CHECK(Module::FinishDynamicImportSuccess(realm, promise, root_module));
+ delete import_data_;
+}
+
bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
@@ -2166,6 +2306,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 +2446,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 +3098,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");
« no previous file with comments | « src/d8.h ('k') | src/factory.h » ('j') | test/mjsunit/harmony/modules-import-2.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698