Index: chrome/renderer/extensions/module_system.cc |
diff --git a/chrome/renderer/extensions/module_system.cc b/chrome/renderer/extensions/module_system.cc |
index 85050a7d6eceeae9be91aad8413bb9023445d07b..58d497ab9080e1c628dbb22136a1fad2e5583363 100644 |
--- a/chrome/renderer/extensions/module_system.cc |
+++ b/chrome/renderer/extensions/module_system.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/renderer/extensions/module_system.h" |
#include "base/bind.h" |
+#include "base/debug/trace_event.h" |
#include "base/stl_util.h" |
#include "base/string_util.h" |
#include "base/stringprintf.h" |
@@ -12,6 +13,7 @@ |
#include "chrome/renderer/extensions/chrome_v8_context.h" |
#include "chrome/renderer/extensions/console.h" |
#include "content/public/renderer/render_view.h" |
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSuppression.h" |
namespace extensions { |
@@ -23,8 +25,31 @@ const char* kModuleName = "module_name"; |
const char* kModuleField = "module_field"; |
const char* kModulesField = "modules"; |
-// Formats |try_catch| as a nice string. |
-std::string CreateExceptionString(const v8::TryCatch& try_catch) { |
+// Default exception handler which logs the exception. |
+class DefaultExceptionHandler : public ModuleSystem::ExceptionHandler { |
+ public: |
+ // Fatally dumps the debug info from |try_catch| to the console. |
+ // Make sure this is never used for exceptions that originate in external |
+ // code! |
+ virtual void HandleUncaughtException(const v8::TryCatch& try_catch) OVERRIDE { |
+ v8::HandleScope handle_scope; |
+ std::string stack_trace = "<stack trace unavailable>"; |
+ if (!try_catch.StackTrace().IsEmpty()) { |
+ v8::String::Utf8Value stack_value(try_catch.StackTrace()); |
+ if (*stack_value) |
+ stack_trace.assign(*stack_value, stack_value.length()); |
+ else |
+ stack_trace = "<could not convert stack trace to string>"; |
+ } |
+ console::Fatal(v8::Context::GetCalling(), |
+ CreateExceptionString(try_catch) + "{" + stack_trace + "}"); |
+ } |
+}; |
+ |
+} // namespace |
+ |
+std::string ModuleSystem::ExceptionHandler::CreateExceptionString( |
+ const v8::TryCatch& try_catch) { |
v8::Handle<v8::Message> message(try_catch.Message()); |
if (message.IsEmpty()) { |
return "try_catch has no message"; |
@@ -49,37 +74,19 @@ std::string CreateExceptionString(const v8::TryCatch& try_catch) { |
error_message.c_str()); |
} |
-// Fatally dumps the debug info from |try_catch| to the console. |
-// Don't use this for logging exceptions that might originate in external code! |
-void 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()); |
- if (*stack_value) |
- stack_trace.assign(*stack_value, stack_value.length()); |
- else |
- stack_trace = "<could not convert stack trace to string>"; |
- } |
- |
- console::Fatal(v8::Context::GetCalling(), |
- CreateExceptionString(try_catch) + "{" + stack_trace + "}"); |
-} |
- |
-} // namespace |
- |
-ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context, |
+ModuleSystem::ModuleSystem(ChromeV8Context* context, |
SourceMap* source_map) |
- : ObjectBackedNativeHandler(context), |
+ : ObjectBackedNativeHandler(context->v8_context()), |
+ context_(context), |
source_map_(source_map), |
- natives_enabled_(0) { |
+ natives_enabled_(0), |
+ exception_handler_(new DefaultExceptionHandler()) { |
RouteFunction("require", |
base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this))); |
RouteFunction("requireNative", |
base::Bind(&ModuleSystem::RequireNative, 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)); |
@@ -123,10 +130,7 @@ ModuleSystem::NativesEnabledScope::~NativesEnabledScope() { |
} |
void ModuleSystem::HandleException(const v8::TryCatch& try_catch) { |
- if (exception_handler_) |
- exception_handler_->HandleUncaughtException(); |
- else |
- DumpException(try_catch); |
+ exception_handler_->HandleUncaughtException(try_catch); |
} |
v8::Handle<v8::Value> ModuleSystem::Require(const std::string& module_name) { |
@@ -190,10 +194,9 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJsInner( |
exports, |
}; |
{ |
- WebKit::WebScopedMicrotaskSuppression suppression; |
v8::TryCatch try_catch; |
try_catch.SetCaptureMessage(true); |
- func->Call(global, 3, args); |
+ context_->CallFunction(func, arraysize(args), args); |
if (try_catch.HasCaught()) { |
HandleException(try_catch); |
return v8::Undefined(); |
@@ -206,18 +209,38 @@ v8::Handle<v8::Value> ModuleSystem::RequireForJsInner( |
v8::Local<v8::Value> 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); |
+ v8::HandleScope handle_scope; |
+ v8::Handle<v8::Value> no_args; |
+ return CallModuleMethod(module_name, method_name, 0, &no_args); |
} |
v8::Local<v8::Value> 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->size(), vector_as_array(args)); |
+} |
+ |
+v8::Local<v8::Value> ModuleSystem::CallModuleMethod( |
+ const std::string& module_name, |
+ const std::string& method_name, |
+ int argc, |
+ v8::Handle<v8::Value> argv[]) { |
+ TRACE_EVENT2("v8", "v8.callModuleMethod", |
+ "module_name", module_name, |
+ "method_name", method_name); |
+ |
v8::HandleScope handle_scope; |
- v8::Local<v8::Value> module = |
- v8::Local<v8::Value>::New( |
- RequireForJsInner(v8::String::New(module_name.c_str()))); |
+ v8::Context::Scope context_scope(v8_context()); |
+ |
+ v8::Local<v8::Value> module; |
+ { |
+ NativesEnabledScope natives_enabled(this); |
+ module = v8::Local<v8::Value>::New( |
+ RequireForJsInner(v8::String::New(module_name.c_str()))); |
+ } |
+ |
if (module.IsEmpty() || !module->IsObject()) { |
console::Error( |
v8::Context::GetCalling(), |
@@ -234,17 +257,16 @@ v8::Local<v8::Value> ModuleSystem::CallModuleMethod( |
return handle_scope.Close(v8::Undefined()); |
} |
- v8::Handle<v8::Function> func = |
- v8::Handle<v8::Function>::Cast(value); |
- v8::Handle<v8::Object> global(v8_context()->Global()); |
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value); |
v8::Local<v8::Value> result; |
{ |
- WebKit::WebScopedMicrotaskSuppression suppression; |
v8::TryCatch try_catch; |
try_catch.SetCaptureMessage(true); |
- result = func->Call(global, args->size(), vector_as_array(args)); |
- if (try_catch.HasCaught()) |
+ result = context_->CallFunction(func, argc, argv); |
+ if (try_catch.HasCaught()) { |
+ LOG(WARNING) << "caught exception"; |
HandleException(try_catch); |
+ } |
} |
return handle_scope.Close(result); |
} |
@@ -388,6 +410,7 @@ void ModuleSystem::SetNativeLazyField(v8::Handle<v8::Object> object, |
v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code, |
v8::Handle<v8::String> name) { |
v8::HandleScope handle_scope; |
+ v8::Context::Scope context_scope(v8_context()); |
WebKit::WebScopedMicrotaskSuppression suppression; |
v8::TryCatch try_catch; |