Index: chrome/renderer/extensions/module_system.cc |
diff --git a/chrome/renderer/extensions/module_system.cc b/chrome/renderer/extensions/module_system.cc |
index 74e7d3d8d998fc99b1fc719e6dd32f4aff94342d..860ea17caf2330ec7085e4d822c517c6890f9799 100644 |
--- a/chrome/renderer/extensions/module_system.cc |
+++ b/chrome/renderer/extensions/module_system.cc |
@@ -5,7 +5,9 @@ |
#include "chrome/renderer/extensions/module_system.h" |
#include "base/bind.h" |
+#include "base/debug/alias.h" |
#include "base/stl_util.h" |
+#include "base/string_util.h" |
#include "base/stringprintf.h" |
#include "chrome/common/extensions/extension_messages.h" |
#include "chrome/renderer/extensions/chrome_v8_context.h" |
@@ -27,8 +29,7 @@ ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context, |
SourceMap* source_map) |
: ObjectBackedNativeHandler(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", |
@@ -44,16 +45,14 @@ 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; |
+void ModuleSystem::Invalidate() { |
+ if (!is_valid()) |
+ return; |
+ for (NativeHandlerMap::iterator it = native_handler_map_.begin(); |
+ it != native_handler_map_.end(); ++it) { |
+ it->second->Invalidate(); |
+ } |
+ ObjectBackedNativeHandler::Invalidate(); |
} |
ModuleSystem::NativesEnabledScope::NativesEnabledScope( |
@@ -67,17 +66,6 @@ ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { |
CHECK_GE(module_system_->natives_enabled_, 0); |
} |
-// 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; |
- v8::Handle<v8::Value> module_system = |
- global->GetHiddenValue(v8::String::New(kModuleSystem)); |
- return !module_system.IsEmpty() && !module_system->IsUndefined(); |
-} |
- |
void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { |
DumpException(try_catch); |
if (exception_handler_.get()) |
@@ -137,7 +125,6 @@ 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> modules(v8::Handle<v8::Object>::Cast( |
@@ -253,7 +240,7 @@ v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter( |
v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner( |
v8::Local<v8::String> property, |
const v8::AccessorInfo& info, |
- GetModuleFunc get_module) { |
+ RequireFunction require_function) { |
CHECK(!info.Data().IsEmpty()); |
CHECK(info.Data()->IsObject()); |
v8::HandleScope handle_scope; |
@@ -271,20 +258,10 @@ v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner( |
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)); |
+ (module_system->*require_function)(name)); |
if (try_catch.HasCaught()) { |
module_system->HandleException(try_catch); |
return handle_scope.Close(v8::Handle<v8::Value>()); |
@@ -296,10 +273,19 @@ v8::Handle<v8::Value> ModuleSystem::LazyFieldGetterInner( |
v8::Handle<v8::String> field = |
parameters->Get(v8::String::New(kModuleField))->ToString(); |
+ // http://crbug.com/179741. |
+ std::string field_name = *v8::String::AsciiValue(field); |
+ char stack_debug[64]; |
+ base::debug::Alias(&stack_debug); |
+ base::snprintf(stack_debug, arraysize(stack_debug), |
+ "%s.%s", name.c_str(), field_name.c_str()); |
+ |
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. |
+ // CHECK is for http://crbug.com/179741. |
+ CHECK(!new_field.IsEmpty()) << "Empty require " << name << "." << field_name; |
if (!new_field->IsUndefined()) { |
object->Delete(property); |
object->Set(property, new_field); |