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

Unified Diff: gin/modules/module_registry.cc

Issue 74753002: Introduce gin_shell (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix more header nits Created 7 years, 1 month 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 | « gin/modules/module_registry.h ('k') | gin/modules/module_runner_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gin/modules/module_registry.cc
diff --git a/gin/modules/module_registry.cc b/gin/modules/module_registry.cc
index 78a102c0a6da5186e83987ecef41716181d4c8f0..6ac25590a42228cc6f14ff9ad894251c2621a9f1 100644
--- a/gin/modules/module_registry.cc
+++ b/gin/modules/module_registry.cc
@@ -4,18 +4,29 @@
#include "gin/modules/module_registry.h"
-#include <assert.h>
#include <string>
#include <vector>
+
+#include "base/logging.h"
#include "gin/arguments.h"
#include "gin/converter.h"
#include "gin/per_isolate_data.h"
#include "gin/wrapper_info.h"
+using v8::Context;
using v8::External;
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::FunctionTemplate;
using v8::Handle;
using v8::Isolate;
+using v8::Local;
+using v8::Object;
using v8::ObjectTemplate;
+using v8::Persistent;
+using v8::StackTrace;
+using v8::String;
+using v8::Value;
namespace gin {
@@ -25,12 +36,19 @@ struct PendingModule {
std::string id;
std::vector<std::string> dependencies;
- v8::Persistent<v8::Value> factory;
+ Persistent<Value> factory;
};
+PendingModule::PendingModule() {
+}
+
+PendingModule::~PendingModule() {
+ factory.Reset();
+}
+
namespace {
-void Define(const v8::FunctionCallbackInfo<v8::Value>& info) {
+void Define(const FunctionCallbackInfo<Value>& info) {
Arguments args(info);
if (!info.Length())
@@ -38,7 +56,7 @@ void Define(const v8::FunctionCallbackInfo<v8::Value>& info) {
std::string id;
std::vector<std::string> dependencies;
- Handle<v8::Value> factory;
+ Handle<Value> factory;
if (args.PeekNext()->IsString())
args.GetNext(&id);
@@ -47,141 +65,165 @@ void Define(const v8::FunctionCallbackInfo<v8::Value>& info) {
if (!args.GetNext(&factory))
return args.ThrowError();
- PendingModule* pending = new PendingModule;
+ scoped_ptr<PendingModule> pending(new PendingModule);
pending->id = id;
pending->dependencies = dependencies;
pending->factory.Reset(args.isolate(), factory);
ModuleRegistry* registry =
ModuleRegistry::From(args.isolate()->GetCurrentContext());
- registry->AddPendingModule(args.isolate(), pending);
+ registry->AddPendingModule(args.isolate(), pending.Pass());
}
WrapperInfo g_wrapper_info = {};
-v8::Local<v8::FunctionTemplate> GetDefineTemplate(v8::Isolate* isolate) {
+Local<FunctionTemplate> GetDefineTemplate(Isolate* isolate) {
PerIsolateData* data = PerIsolateData::From(isolate);
- v8::Local<v8::FunctionTemplate> templ = data->GetFunctionTemplate(
+ Local<FunctionTemplate> templ = data->GetFunctionTemplate(
&g_wrapper_info);
if (templ.IsEmpty()) {
- templ = v8::FunctionTemplate::New(Define);
+ templ = FunctionTemplate::New(Define);
data->SetFunctionTemplate(&g_wrapper_info, templ);
}
return templ;
}
-Handle<v8::String> GetHiddenValueKey(v8::Isolate* isolate) {
+Handle<String> GetHiddenValueKey(Isolate* isolate) {
return StringToSymbol(isolate, "::gin::ModuleRegistry");
}
-} // namespace
-
-
-PendingModule::PendingModule() {
+std::string GetImplicitModuleName(const std::string& explicit_name) {
+ if (!explicit_name.empty())
+ return explicit_name;
+ std::string implicit_name;
+ Handle<StackTrace> trace = StackTrace::CurrentStackTrace(1);
+ Handle<String> script_name = trace->GetFrame(0)->GetScriptName();
+ if (!script_name.IsEmpty())
+ ConvertFromV8(script_name, &implicit_name);
+ return implicit_name;
}
-PendingModule::~PendingModule() {
- factory.Reset();
-}
+} // namespace
-ModuleRegistry::ModuleRegistry(v8::Isolate* isolate)
- : modules_(isolate, v8::Object::New()) {
+ModuleRegistry::ModuleRegistry(Isolate* isolate)
+ : modules_(isolate, Object::New()) {
}
ModuleRegistry::~ModuleRegistry() {
- for (PendingModuleList::iterator it = pending_modules_.begin();
- it != pending_modules_.end(); ++it) {
- delete *it;
- }
modules_.Reset();
}
-void ModuleRegistry::RegisterGlobals(v8::Isolate* isolate,
- Handle<v8::ObjectTemplate> templ) {
+void ModuleRegistry::RegisterGlobals(Isolate* isolate,
+ Handle<ObjectTemplate> templ) {
templ->Set(StringToSymbol(isolate, "define"), GetDefineTemplate(isolate));
}
-void ModuleRegistry::AddBuiltinModule(Isolate* isolate,
- const std::string& id,
- Handle<ObjectTemplate> templ) {
- assert(!id.empty());
- Handle<v8::Object> modules = v8::Local<v8::Object>::New(isolate, modules_);
- modules->Set(StringToV8(isolate, id), templ->NewInstance());
-}
-
-ModuleRegistry* ModuleRegistry::From(Handle<v8::Context> context) {
- v8::Isolate* isolate = context->GetIsolate();
- Handle<v8::String> key = GetHiddenValueKey(isolate);
- Handle<v8::Value> value = context->Global()->GetHiddenValue(key);
- Handle<v8::External> external;
+ModuleRegistry* ModuleRegistry::From(Handle<Context> context) {
+ Isolate* isolate = context->GetIsolate();
+ Handle<String> key = GetHiddenValueKey(isolate);
+ Handle<Value> value = context->Global()->GetHiddenValue(key);
+ Handle<External> external;
if (value.IsEmpty() || !ConvertFromV8(value, &external)) {
PerContextData* data = PerContextData::From(context);
if (!data)
return NULL;
ModuleRegistry* registry = new ModuleRegistry(isolate);
- context->Global()->SetHiddenValue(key, v8::External::New(registry));
- data->AddSupplement(registry);
+ context->Global()->SetHiddenValue(key, External::New(isolate, registry));
+ data->AddSupplement(scoped_ptr<ContextSupplement>(registry));
return registry;
}
return static_cast<ModuleRegistry*>(external->Value());
}
-void ModuleRegistry::AddPendingModule(v8::Isolate* isolate,
- PendingModule* pending) {
- if (AttemptToLoad(isolate, pending))
- AttemptToLoadPendingModules(isolate);
+void ModuleRegistry::AddBuiltinModule(Isolate* isolate,
+ const std::string& id,
+ Handle<ObjectTemplate> templ) {
+ DCHECK(!id.empty());
+ RegisterModule(isolate, id, templ->NewInstance());
}
-void ModuleRegistry::Detach(Handle<v8::Context> context) {
- context->Global()->SetHiddenValue(GetHiddenValueKey(context->GetIsolate()),
- Handle<v8::Value>());
+void ModuleRegistry::AddPendingModule(Isolate* isolate,
+ scoped_ptr<PendingModule> pending) {
+ AttemptToLoad(isolate, pending.Pass());
+}
+
+void ModuleRegistry::RegisterModule(Isolate* isolate,
+ const std::string& id,
+ Handle<Value> module) {
+ if (id.empty() || module.IsEmpty())
+ return;
+
+ unsatisfied_dependencies_.erase(id);
+ available_modules_.insert(id);
+ Handle<Object> modules = Local<Object>::New(isolate, modules_);
+ modules->Set(StringToSymbol(isolate, id), module);
}
-bool ModuleRegistry::AttemptToLoad(v8::Isolate* isolate,
- PendingModule* pending) {
- Handle<v8::Object> modules = v8::Local<v8::Object>::New(isolate, modules_);
- Handle<v8::String> key = StringToV8(isolate, pending->id);
+void ModuleRegistry::Detach(Handle<Context> context) {
+ context->Global()->SetHiddenValue(GetHiddenValueKey(context->GetIsolate()),
+ Handle<Value>());
+}
- if (!pending->id.empty() && modules->HasOwnProperty(key)) {
- // We've already loaded a module with this name. Ignore the new one.
- delete pending;
- return true;
+bool ModuleRegistry::CheckDependencies(PendingModule* pending) {
+ size_t num_missing_dependencies = 0;
+ size_t len = pending->dependencies.size();
+ for (size_t i = 0; i < len; ++i) {
+ const std::string& dependency = pending->dependencies[i];
+ if (available_modules_.count(dependency))
+ continue;
+ unsatisfied_dependencies_.insert(dependency);
+ num_missing_dependencies++;
}
+ return num_missing_dependencies == 0;
+}
+
+void ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) {
+ if (!pending->id.empty() && available_modules_.count(pending->id))
+ return; // We've already loaded this module.
+ Handle<Object> modules = Local<Object>::New(isolate, modules_);
size_t argc = pending->dependencies.size();
- std::vector<Handle<v8::Value> > argv(argc);
+ std::vector<Handle<Value> > argv(argc);
for (size_t i = 0; i < argc; ++i) {
- Handle<v8::String> key = StringToV8(isolate, pending->dependencies[i]);
- if (!modules->HasOwnProperty(key)) {
- pending_modules_.push_back(pending);
- return false;
- }
+ Handle<String> key = StringToSymbol(isolate, pending->dependencies[i]);
+ DCHECK(modules->HasOwnProperty(key));
argv[i] = modules->Get(key);
}
- Handle<v8::Value> module = v8::Local<v8::Value>::New(
- isolate, pending->factory);
+ Handle<Value> module = Local<Value>::New(isolate, pending->factory);
- Handle<v8::Function> factory;
+ Handle<Function> factory;
if (ConvertFromV8(module, &factory)) {
- v8::Handle<v8::Object> global = isolate->GetCurrentContext()->Global();
+ Handle<Object> global = isolate->GetCurrentContext()->Global();
module = factory->Call(global, argc, argv.data());
// TODO(abarth): What should we do with exceptions?
}
- if (!pending->id.empty() && !module.IsEmpty())
- modules->Set(key, module);
+ RegisterModule(isolate, GetImplicitModuleName(pending->id), module);
+}
- delete pending;
+bool ModuleRegistry::AttemptToLoad(Isolate* isolate,
+ scoped_ptr<PendingModule> pending) {
+ if (!CheckDependencies(pending.get())) {
+ pending_modules_.push_back(pending.release());
+ return false;
+ }
+ Load(isolate, pending.Pass());
return true;
}
-void ModuleRegistry::AttemptToLoadPendingModules(v8::Isolate* isolate) {
- PendingModuleList pending_modules;
- pending_modules.swap(pending_modules_);
- for (PendingModuleList::iterator it = pending_modules.begin();
- it != pending_modules.end(); ++it) {
- AttemptToLoad(isolate, *it);
+void ModuleRegistry::AttemptToLoadMoreModules(Isolate* isolate) {
+ bool keep_trying = true;
+ while (keep_trying) {
+ keep_trying = false;
+ PendingModuleVector pending_modules;
+ pending_modules.swap(pending_modules_);
+ for (size_t i = 0; i < pending_modules.size(); ++i) {
+ scoped_ptr<PendingModule> pending(pending_modules[i]);
+ pending_modules[i] = NULL;
+ if (AttemptToLoad(isolate, pending.Pass()))
+ keep_trying = true;
+ }
}
}
« no previous file with comments | « gin/modules/module_registry.h ('k') | gin/modules/module_runner_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698