summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions/module_system.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/extensions/module_system.cc')
-rw-r--r--chrome/renderer/extensions/module_system.cc156
1 files changed, 36 insertions, 120 deletions
diff --git a/chrome/renderer/extensions/module_system.cc b/chrome/renderer/extensions/module_system.cc
index 74e7d3d..31146c8 100644
--- a/chrome/renderer/extensions/module_system.cc
+++ b/chrome/renderer/extensions/module_system.cc
@@ -6,10 +6,6 @@
#include "base/bind.h"
#include "base/stl_util.h"
-#include "base/stringprintf.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 {
@@ -25,35 +21,28 @@ namespace extensions {
ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
SourceMap* source_map)
- : ObjectBackedNativeHandler(context),
+ : NativeHandler(context->GetIsolate()),
+ context_(v8::Persistent<v8::Context>::New(context->GetIsolate(),
+ context)),
source_map_(source_map),
- natives_enabled_(0),
- is_valid_(true) {
+ natives_enabled_(0) {
RouteFunction("require",
base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this)));
RouteFunction("requireNative",
- base::Bind(&ModuleSystem::RequireNative, base::Unretained(this)));
+ base::Bind(&ModuleSystem::GetNative, base::Unretained(this)));
- v8::Handle<v8::Object> global(context->Global());
+ v8::Handle<v8::Object> global(context_->Global());
global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New());
global->SetHiddenValue(v8::String::New(kModuleSystem),
v8::External::New(this));
}
ModuleSystem::~ModuleSystem() {
- Invalidate();
-}
-
-bool ModuleSystem::Invalidate() {
- if (!ObjectBackedNativeHandler::Invalidate())
- return false;
-
v8::HandleScope handle_scope;
// Deleting this value here prevents future lazy field accesses from
// referencing ModuleSystem after it has been freed.
- v8_context()->Global()->DeleteHiddenValue(v8::String::New(kModuleSystem));
-
- return true;
+ context_->Global()->DeleteHiddenValue(v8::String::New(kModuleSystem));
+ context_.Dispose(context_->GetIsolate());
}
ModuleSystem::NativesEnabledScope::NativesEnabledScope(
@@ -69,7 +58,6 @@ ModuleSystem::NativesEnabledScope::~NativesEnabledScope() {
// static
bool ModuleSystem::IsPresentInCurrentContext() {
- // XXX(kalman): Not sure if this is safe. Investigate.
v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
if (global.IsEmpty())
return false;
@@ -85,10 +73,13 @@ void ModuleSystem::HandleException(const v8::TryCatch& try_catch) {
}
// static
-std::string ModuleSystem::CreateExceptionString(const v8::TryCatch& try_catch) {
+void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
+ v8::HandleScope handle_scope;
+
v8::Handle<v8::Message> message(try_catch.Message());
if (message.IsEmpty()) {
- return "try_catch has no message";
+ LOG(ERROR) << "try_catch has no message";
+ return;
}
std::string resource_name = "<unknown resource>";
@@ -101,16 +92,6 @@ std::string ModuleSystem::CreateExceptionString(const v8::TryCatch& try_catch) {
if (!message->Get().IsEmpty())
error_message = *v8::String::Utf8Value(message->Get());
- return base::StringPrintf("%s:%d: %s",
- resource_name.c_str(),
- message->GetLineNumber(),
- error_message.c_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());
@@ -120,13 +101,14 @@ void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
stack_trace = "<could not convert stack trace to string>";
}
- LOG(ERROR) << CreateExceptionString(try_catch) << "{" << stack_trace << "}";
+ LOG(ERROR) << "[" << resource_name << "(" << message->GetLineNumber() << ")] "
+ << error_message
+ << "{" << stack_trace << "}";
}
-v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) {
+void ModuleSystem::Require(const std::string& module_name) {
v8::HandleScope handle_scope;
- return handle_scope.Close(
- RequireForJsInner(v8::String::New(module_name.c_str())));
+ RequireForJsInner(v8::String::New(module_name.c_str()));
}
v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
@@ -137,9 +119,8 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
v8::Handle<v8::String> module_name) {
- CHECK(is_valid_);
v8::HandleScope handle_scope;
- v8::Handle<v8::Object> global(v8_context()->Global());
+ v8::Handle<v8::Object> global(v8::Context::GetCurrent()->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));
@@ -179,11 +160,10 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
return handle_scope.Close(exports);
}
-v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
- const std::string& module_name,
- const std::string& method_name) {
+void ModuleSystem::CallModuleMethod(const std::string& module_name,
+ const std::string& method_name) {
std::vector<v8::Handle<v8::Value> > args;
- return CallModuleMethod(module_name, method_name, &args);
+ CallModuleMethod(module_name, method_name, &args);
}
v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
@@ -203,7 +183,8 @@ v8::Local<v8::Value> ModuleSystem::CallModuleMethod(
return v8::Local<v8::Value>();
v8::Handle<v8::Function> func =
v8::Handle<v8::Function>::Cast(value);
- v8::Handle<v8::Object> global(v8_context()->Global());
+ // TODO(jeremya/koz): refer to context_ here, not the current context.
+ v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
v8::Local<v8::Value> result;
{
WebKit::WebScopedMicrotaskSuppression suppression;
@@ -216,10 +197,6 @@ 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] =
@@ -236,29 +213,13 @@ 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(parameters->CreationContext()->Global());
+ v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
v8::Handle<v8::Value> module_system_value =
global->GetHiddenValue(v8::String::New(kModuleSystem));
if (module_system_value.IsEmpty() || module_system_value->IsUndefined()) {
@@ -268,78 +229,38 @@ v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner(
ModuleSystem* module_system = static_cast<ModuleSystem*>(
v8::Handle<v8::External>::Cast(module_system_value)->Value());
- std::string name = *v8::String::AsciiValue(
- parameters->Get(v8::String::New(kModuleName))->ToString());
-
- // HACK(kalman): Switch to the context of the owner module system while
- // lazily requiring modules.
- //
- // It seems to be a common incorrect assumption throughout code that the
- // current context is the owner context. This makes that assumption true for
- // at least the period where the JavaScript is first evaluated, which is when
- // things are most likely to go wrong.
- v8::Context::Scope context_scope(parameters->CreationContext());
-
- NativesEnabledScope natives_enabled_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>());
+ 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()));
}
-
if (module.IsEmpty())
return handle_scope.Close(v8::Handle<v8::Value>());
v8::Handle<v8::String> field =
parameters->Get(v8::String::New(kModuleField))->ToString();
- v8::Local<v8::Value> new_field = module->Get(field);
- v8::Handle<v8::Object> object = info.This();
- // Delete the getter and set this field to |new_field| so the same object is
- // returned every time a certain API is accessed.
- if (!new_field->IsUndefined()) {
- object->Delete(property);
- object->Set(property, new_field);
- }
- return handle_scope.Close(new_field);
+ return handle_scope.Close(module->Get(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()),
- getter,
+ &ModuleSystem::LazyFieldGetter,
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;
@@ -369,18 +290,13 @@ v8::Handle<v8::Value> ModuleSystem::GetSource(
return handle_scope.Close(source_map_->GetSource(module_name));
}
-v8::Handle<v8::Value> ModuleSystem::RequireNative(const v8::Arguments& args) {
+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 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 RequireForJsInner(v8::String::New(native_name.c_str()));
+ return RequireForJs(args);
NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
if (i == native_handler_map_.end())
return v8::Undefined();