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

Unified Diff: src/d8.cc

Issue 2351113004: [modules] Expand API to allow linking and use it in d8 (Closed)
Patch Set: Use StrictEquals, remove check for bad instantiation behavior Created 4 years, 3 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
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 2458249d18cef06164c8e330abce2fcc9d2f1351..170eccddb6de055e3d81c09d4b2043558c695d2f 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -9,6 +9,8 @@
#include <algorithm>
#include <fstream>
+#include <map>
+#include <utility>
#include <vector>
#ifdef ENABLE_VTUNE_JIT_INTERFACE
@@ -461,7 +463,7 @@ MaybeLocal<Script> Shell::CompileString(
// Executes a string within the current v8 context.
bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Value> name, bool print_result,
- bool report_exceptions, SourceType source_type) {
+ bool report_exceptions) {
HandleScope handle_scope(isolate);
TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
@@ -472,31 +474,14 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
- if (source_type == SCRIPT) {
- Local<Script> script;
- if (!Shell::CompileString(isolate, source, name, options.compile_options)
- .ToLocal(&script)) {
- // Print errors that happened during compilation.
- if (report_exceptions) ReportException(isolate, &try_catch);
- return false;
- }
- maybe_result = script->Run(realm);
- } else {
- DCHECK_EQ(MODULE, source_type);
- Local<Module> module;
- ScriptOrigin origin(name);
- ScriptCompiler::Source script_source(source, origin);
- // TODO(adamk): Make use of compile options for Modules.
- if (!ScriptCompiler::CompileModule(isolate, &script_source)
- .ToLocal(&module)) {
- // Print errors that happened during compilation.
- if (report_exceptions) ReportException(isolate, &try_catch);
- return false;
- }
- // This can't fail until we support linking.
- CHECK(module->Instantiate(realm));
- maybe_result = module->Evaluate(realm);
+ Local<Script> script;
+ if (!Shell::CompileString(isolate, source, name, options.compile_options)
+ .ToLocal(&script)) {
+ // Print errors that happened during compilation.
+ if (report_exceptions) ReportException(isolate, &try_catch);
+ return false;
}
+ maybe_result = script->Run(realm);
EmptyMessageQueues(isolate);
data->realm_current_ = data->realm_switch_;
}
@@ -526,6 +511,95 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
return true;
}
+MaybeLocal<Module> Shell::FetchModuleTree(
+ Isolate* isolate, const std::string& file_name,
+ std::map<std::string, Global<Module>>* module_map) {
+ 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);
+ }
+ ScriptOrigin origin(
+ String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal)
+ .ToLocalChecked());
+ ScriptCompiler::Source source(source_text, origin);
+ Local<Module> module;
+ if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
+ ReportException(isolate, &try_catch);
+ return MaybeLocal<Module>();
+ }
+ module_map->insert(
+ std::make_pair(file_name, Global<Module>(isolate, module)));
+ for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) {
+ Local<String> name = module->GetModuleRequest(i);
+ // TODO(adamk): Resolve the imported module to a full path.
+ std::string str = *String::Utf8Value(name);
+ if (!module_map->count(str)) {
+ if (FetchModuleTree(isolate, str, module_map).IsEmpty()) {
+ return MaybeLocal<Module>();
+ }
+ }
+ }
+
+ return module;
+}
+
+namespace {
+
+MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
+ Local<String> specifier,
+ Local<Module> referrer,
+ Local<Value> data) {
+ Isolate* isolate = context->GetIsolate();
+ auto module_map = static_cast<std::map<std::string, Global<Module>>*>(
+ External::Cast(*data)->Value());
+ std::string str_specifier = *String::Utf8Value(specifier);
+ // TODO(adamk): Resolve the specifier using the referrer
+ auto it = module_map->find(str_specifier);
+ if (it != module_map->end()) {
+ return it->second.Get(isolate);
+ }
+ return MaybeLocal<Module>();
+}
+
+} // anonymous namespace
+
+bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
+ HandleScope handle_scope(isolate);
+
+ Local<Module> root_module;
+ std::map<std::string, Global<Module>> module_map;
+ if (!FetchModuleTree(isolate, file_name, &module_map).ToLocal(&root_module)) {
+ return false;
+ }
+
+ TryCatch try_catch(isolate);
+ try_catch.SetVerbose(true);
+
+ MaybeLocal<Value> maybe_result;
+ {
+ PerIsolateData* data = PerIsolateData::Get(isolate);
+ Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
+ Context::Scope context_scope(realm);
+
+ // This can't fail until we support linking.
+ CHECK(root_module->Instantiate(realm, ResolveModuleCallback,
+ External::New(isolate, &module_map)));
+ maybe_result = root_module->Evaluate(realm);
+ EmptyMessageQueues(isolate);
+ }
+ Local<Value> result;
+ if (!maybe_result.ToLocal(&result)) {
+ DCHECK(try_catch.HasCaught());
+ // Print errors that happened during execution.
+ ReportException(isolate, &try_catch);
+ return false;
+ }
+ DCHECK(!try_catch.HasCaught());
+ return true;
+}
PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) {
data_->realm_count_ = 1;
@@ -1580,7 +1654,6 @@ void SourceGroup::Execute(Isolate* isolate) {
bool exception_was_thrown = false;
for (int i = begin_offset_; i < end_offset_; ++i) {
const char* arg = argv_[i];
- Shell::SourceType source_type = Shell::SCRIPT;
if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
// Execute argument given to -e option directly.
HandleScope handle_scope(isolate);
@@ -1599,8 +1672,13 @@ void SourceGroup::Execute(Isolate* isolate) {
continue;
} else if (strcmp(arg, "--module") == 0 && i + 1 < end_offset_) {
// Treat the next file as a module.
- source_type = Shell::MODULE;
arg = argv_[++i];
+ Shell::options.script_executed = true;
+ if (!Shell::ExecuteModule(isolate, arg)) {
+ exception_was_thrown = true;
+ break;
+ }
+ continue;
} else if (arg[0] == '-') {
// Ignore other options. They have been parsed already.
continue;
@@ -1617,8 +1695,7 @@ void SourceGroup::Execute(Isolate* isolate) {
Shell::Exit(1);
}
Shell::options.script_executed = true;
- if (!Shell::ExecuteString(isolate, source, file_name, false, true,
- source_type)) {
+ if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
exception_was_thrown = true;
break;
}
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698