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

Unified Diff: chrome/renderer/extensions/module_system.cc

Issue 11571014: Lazy load chrome.* APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed comments Created 7 years, 10 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: chrome/renderer/extensions/module_system.cc
diff --git a/chrome/renderer/extensions/module_system.cc b/chrome/renderer/extensions/module_system.cc
index 26590475d0bd1ac967a6575f209eab5e1b4e7367..bd469ac283ad1fb53f7fe47098a96710bdeae60d 100644
--- a/chrome/renderer/extensions/module_system.cc
+++ b/chrome/renderer/extensions/module_system.cc
@@ -4,8 +4,13 @@
#include "chrome/renderer/extensions/module_system.h"
+#include <sstream>
+
#include "base/bind.h"
#include "base/stl_util.h"
+#include "chrome/common/extensions/extension_messages.h"
+#include "chrome/renderer/extensions/chrome_v8_context.h"
+#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSuppression.h"
namespace {
@@ -21,15 +26,14 @@ namespace extensions {
ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
SourceMap* source_map)
- : NativeHandler(context->GetIsolate()),
- context_(v8::Persistent<v8::Context>::New(context->GetIsolate(),
- context)),
+ : ObjectBackedNativeHandler(context->GetIsolate()),
+ context_(context),
source_map_(source_map),
natives_enabled_(0) {
RouteFunction("require",
base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this)));
RouteFunction("requireNative",
- base::Bind(&ModuleSystem::GetNative, base::Unretained(this)));
+ base::Bind(&ModuleSystem::RequireNative, base::Unretained(this)));
v8::Handle<v8::Object> global(context_->Global());
global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New());
@@ -41,8 +45,8 @@ ModuleSystem::~ModuleSystem() {
v8::HandleScope handle_scope;
// Deleting this value here prevents future lazy field accesses from
// referencing ModuleSystem after it has been freed.
- context_->Global()->DeleteHiddenValue(v8::String::New(kModuleSystem));
- context_.Dispose(context_->GetIsolate());
+ context_->Global()->DeleteHiddenValue(
+ v8::String::New(kModuleSystem));
}
ModuleSystem::NativesEnabledScope::NativesEnabledScope(
@@ -73,13 +77,10 @@ void ModuleSystem::HandleException(const v8::TryCatch& try_catch) {
}
// static
-void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
- v8::HandleScope handle_scope;
-
+std::string ModuleSystem::CreateExceptionString(const v8::TryCatch& try_catch) {
v8::Handle<v8::Message> message(try_catch.Message());
if (message.IsEmpty()) {
- LOG(ERROR) << "try_catch has no message";
- return;
+ return "try_catch has no message";
}
std::string resource_name = "<unknown resource>";
@@ -92,6 +93,16 @@ void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
if (!message->Get().IsEmpty())
error_message = *v8::String::Utf8Value(message->Get());
+ std::stringstream ret;
+ ret << "[" << resource_name << "(" << message->GetLineNumber() << ")] "
+ << error_message;
not at google - send to devlin 2013/02/15 22:26:17 just use +, no stringstream. It's efficient enough
cduvall 2013/02/19 23:58:49 I was using a stringstream because GetLineNumber()
+ return ret.str();
+}
+
+// static
+void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
+ v8::HandleScope handle_scope;
+
std::string stack_trace = "<stack trace unavailable>";
if (!try_catch.StackTrace().IsEmpty()) {
v8::String::Utf8Value stack_value(try_catch.StackTrace());
@@ -101,14 +112,13 @@ void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
stack_trace = "<could not convert stack trace to string>";
}
- LOG(ERROR) << "[" << resource_name << "(" << message->GetLineNumber() << ")] "
- << error_message
- << "{" << stack_trace << "}";
+ LOG(ERROR) << CreateExceptionString(try_catch) << "{" << stack_trace << "}";
}
-void ModuleSystem::Require(const std::string& module_name) {
+v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) {
v8::HandleScope handle_scope;
- RequireForJsInner(v8::String::New(module_name.c_str()));
+ return handle_scope.Close(
+ RequireForJsInner(v8::String::New(module_name.c_str())));
}
v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
@@ -120,7 +130,7 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
v8::Handle<v8::String> module_name) {
v8::HandleScope handle_scope;
- v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
+ v8::Handle<v8::Object> global(context_->Global());
v8::Handle<v8::Object> modules(v8::Handle<v8::Object>::Cast(
global->GetHiddenValue(v8::String::New(kModulesField))));
v8::Handle<v8::Value> exports(modules->Get(module_name));
@@ -160,10 +170,11 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
return handle_scope.Close(exports);
}
-void ModuleSystem::CallModuleMethod(const std::string& module_name,
- const std::string& method_name) {
+v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
+ const std::string& module_name,
+ const std::string& method_name) {
std::vector<v8::Handle<v8::Value> > args;
- CallModuleMethod(module_name, method_name, &args);
+ return CallModuleMethod(module_name, method_name, &args);
}
v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
@@ -183,8 +194,7 @@ v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
return v8::Local<v8::Value>();
v8::Handle<v8::Function> func =
v8::Handle<v8::Function>::Cast(value);
- // TODO(jeremya/koz): refer to context_ here, not the current context.
- v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
+ v8::Handle<v8::Object> global(context_->Global());
v8::Local<v8::Value> result;
{
WebKit::WebScopedMicrotaskSuppression suppression;
@@ -197,6 +207,10 @@ v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
return handle_scope.Close(result);
}
+bool ModuleSystem::HasNativeHandler(const std::string& name) {
+ return native_handler_map_.find(name) != native_handler_map_.end();
+}
+
void ModuleSystem::RegisterNativeHandler(const std::string& name,
scoped_ptr<NativeHandler> native_handler) {
native_handler_map_[name] =
@@ -213,13 +227,29 @@ void ModuleSystem::RunString(const std::string& code, const std::string& name) {
}
// static
+v8::Handle<v8::Value> ModuleSystem::NativeLazyFieldGetter(
+ v8::Local<v8::String> property, const v8::AccessorInfo& info) {
+ return LazyFieldGetterInner(property,
+ info,
+ &ModuleSystem::RequireNativeFromString);
+}
+
+// static
v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter(
v8::Local<v8::String> property, const v8::AccessorInfo& info) {
+ return LazyFieldGetterInner(property, info, &ModuleSystem::Require);
+}
+
+// static
+v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner(
+ v8::Local<v8::String> property,
+ const v8::AccessorInfo& info,
+ GetModuleFunc get_module) {
CHECK(!info.Data().IsEmpty());
CHECK(info.Data()->IsObject());
v8::HandleScope handle_scope;
v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data());
- v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
+ v8::Handle<v8::Object> global(parameters->CreationContext()->Global());
v8::Handle<v8::Value> module_system_value =
global->GetHiddenValue(v8::String::New(kModuleSystem));
if (module_system_value->IsUndefined()) {
@@ -229,38 +259,61 @@ v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter(
ModuleSystem* module_system = static_cast<ModuleSystem*>(
v8::Handle<v8::External>::Cast(module_system_value)->Value());
- v8::Handle<v8::Object> module;
- {
- NativesEnabledScope scope(module_system);
- module = v8::Handle<v8::Object>::Cast(module_system->RequireForJsInner(
- parameters->Get(v8::String::New(kModuleName))->ToString()));
+ std::string name = *v8::String::AsciiValue(
+ parameters->Get(v8::String::New(kModuleName))->ToString());
+
+ NativesEnabledScope scope(module_system);
+ v8::TryCatch try_catch;
+ v8::Handle<v8::Object> module = v8::Handle<v8::Object>::Cast(
+ (module_system->*get_module)(name));
+ if (try_catch.HasCaught()) {
+ module_system->HandleException(try_catch);
+ return handle_scope.Close(v8::Handle<v8::Value>());
}
+
if (module.IsEmpty())
return handle_scope.Close(v8::Handle<v8::Value>());
v8::Handle<v8::String> field =
parameters->Get(v8::String::New(kModuleField))->ToString();
- return handle_scope.Close(module->Get(field));
+ v8::Local<v8::Value> new_field = module->Get(field);
+ return handle_scope.Close(new_field);
}
void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
const std::string& field,
const std::string& module_name,
const std::string& module_field) {
+ SetLazyField(object, field, module_name, module_field,
+ &ModuleSystem::LazyFieldGetter);
+}
+
+void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
+ const std::string& field,
+ const std::string& module_name,
+ const std::string& module_field,
+ v8::AccessorGetter getter) {
v8::HandleScope handle_scope;
v8::Handle<v8::Object> parameters = v8::Object::New();
parameters->Set(v8::String::New(kModuleName),
v8::String::New(module_name.c_str()));
parameters->Set(v8::String::New(kModuleField),
v8::String::New(module_field.c_str()));
-
object->SetAccessor(v8::String::New(field.c_str()),
- &ModuleSystem::LazyFieldGetter,
+ getter,
NULL,
parameters);
}
+void ModuleSystem::SetNativeLazyField(v8::Handle<v8::Object> object,
+ const std::string& field,
+ const std::string& module_name,
+ const std::string& module_field) {
+ SetLazyField(object, field, module_name, module_field,
+ &ModuleSystem::NativeLazyFieldGetter);
+}
+
v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code,
v8::Handle<v8::String> name) {
v8::HandleScope handle_scope;
@@ -290,13 +343,18 @@ v8::Handle<v8::Value> ModuleSystem::GetSource(
return handle_scope.Close(source_map_->GetSource(module_name));
}
-v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) {
+v8::Handle<v8::Value> ModuleSystem::RequireNative(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
+ std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
+ return RequireNativeFromString(native_name);
+}
+
+v8::Handle<v8::Value> ModuleSystem::RequireNativeFromString(
+ const std::string& native_name) {
if (natives_enabled_ == 0)
return ThrowException("Natives disabled");
- std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
if (overridden_native_handlers_.count(native_name) > 0u)
- return RequireForJs(args);
+ return RequireForJsInner(v8::String::New(native_name.c_str()));
NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
if (i == native_handler_map_.end())
return v8::Undefined();

Powered by Google App Engine
This is Rietveld 408576698