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

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: apitest.js 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..486c5eea94995a65ed96846ddc23a55e0124903d 100644
--- a/chrome/renderer/extensions/module_system.cc
+++ b/chrome/renderer/extensions/module_system.cc
@@ -4,10 +4,18 @@
#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 "chrome/renderer/extensions/extension_helper.h"
+#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSuppression.h"
+using content::ConsoleMessageLevel;
not at google - send to devlin 2013/02/13 01:45:49 not used
cduvall 2013/02/15 00:40:28 Done.
+
namespace {
const char* kModuleSystem = "module_system";
@@ -19,11 +27,10 @@ const char* kModulesField = "modules";
namespace extensions {
-ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
+ModuleSystem::ModuleSystem(ChromeV8Context* context,
SourceMap* source_map)
- : NativeHandler(context->GetIsolate()),
- context_(v8::Persistent<v8::Context>::New(context->GetIsolate(),
- context)),
+ : ObjectBackedNativeHandler(context->v8_context()->GetIsolate()),
+ context_(context),
source_map_(source_map),
natives_enabled_(0) {
RouteFunction("require",
@@ -31,7 +38,7 @@ ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
RouteFunction("requireNative",
base::Bind(&ModuleSystem::GetNative, base::Unretained(this)));
- v8::Handle<v8::Object> global(context_->Global());
+ v8::Handle<v8::Object> global(context_->v8_context()->Global());
global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New());
global->SetHiddenValue(v8::String::New(kModuleSystem),
v8::External::New(this));
@@ -41,8 +48,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_->v8_context()->Global()->DeleteHiddenValue(
+ v8::String::New(kModuleSystem));
}
ModuleSystem::NativesEnabledScope::NativesEnabledScope(
@@ -73,13 +80,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 +96,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;
+ 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 +115,19 @@ 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) {
+void ModuleSystem::LogExceptionToConsole(const v8::TryCatch& try_catch) {
+ ExtensionHelper::Get(context_->GetRenderView())->AddMessageToRootConsole(
+ content::CONSOLE_MESSAGE_LEVEL_ERROR,
+ CreateExceptionString(try_catch));
not at google - send to devlin 2013/02/13 01:45:49 Doesn't seem like this belongs in ModuleSystem (at
cduvall 2013/02/15 00:40:28 Done.
+}
+
+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) {
@@ -148,11 +167,13 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
};
{
WebKit::WebScopedMicrotaskSuppression suppression;
+ // TODO(cduvall): Figure out how to handle this and throw it for later.
not at google - send to devlin 2013/02/13 01:45:49 I think rethrow is fine. We should always throw it
cduvall 2013/02/15 00:40:28 Reverted to how this used to be because logging is
v8::TryCatch try_catch;
try_catch.SetCaptureMessage(true);
func->Call(global, 3, args);
if (try_catch.HasCaught()) {
- HandleException(try_catch);
+ // HandleException(try_catch);
+ try_catch.ReThrow();
return v8::Undefined();
}
}
@@ -160,10 +181,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(
@@ -197,6 +219,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,8 +239,24 @@ 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::GetNativeFromString);
+}
+
+// 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;
@@ -229,25 +271,46 @@ 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->LogExceptionToConsole(try_catch);
+ return handle_scope.Close(v8::Handle<v8::Value>());
not at google - send to devlin 2013/02/13 01:45:49 rethrow should be fine
cduvall 2013/02/15 00:40:28 Changed it to HandleException like the rest of the
}
+
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);
+ v8::Handle<v8::Object> object = info.This();
+ if (!new_field->IsUndefined()) {
+ object->Delete(property);
+ object->Set(property, new_field);
not at google - send to devlin 2013/02/13 01:45:49 This shouldn't be necessary since Require/RequireN
cduvall 2013/02/15 00:40:28 Done.
+ }
+ 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),
@@ -256,11 +319,19 @@ void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
v8::String::New(module_field.c_str()));
object->SetAccessor(v8::String::New(field.c_str()),
not at google - send to devlin 2013/02/13 01:45:49 As mentioned in IRC, if you use SetNamedPropertyAc
cduvall 2013/02/15 00:40:28 As you said in your email, looks like SetNamedProp
- &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;
@@ -292,11 +363,16 @@ v8::Handle<v8::Value> ModuleSystem::GetSource(
v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
+ std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
+ return GetNativeFromString(native_name);
+}
+
+v8::Handle<v8::Value> ModuleSystem::GetNativeFromString(
not at google - send to devlin 2013/02/13 01:45:49 Yeah this is confusing, can you rename it to Requi
cduvall 2013/02/15 00:40:28 Done.
+ 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