| Index: chrome/renderer/extensions/object_backed_native_handler.cc
|
| diff --git a/chrome/renderer/extensions/object_backed_native_handler.cc b/chrome/renderer/extensions/object_backed_native_handler.cc
|
| index 2a4043cb74b0226d5f465a8b9684e9cc5dffbb79..53873b2e6155a8a90a70db41b528e89cb85b7bc9 100644
|
| --- a/chrome/renderer/extensions/object_backed_native_handler.cc
|
| +++ b/chrome/renderer/extensions/object_backed_native_handler.cc
|
| @@ -11,19 +11,10 @@
|
|
|
| namespace extensions {
|
|
|
| -// Data to pass to ObjectBackedNativeHandler::Router.
|
| -struct ObjectBackedNativeHandler::RouterData {
|
| - RouterData(ObjectBackedNativeHandler* self, HandlerFunction function)
|
| - : self(self), function(function) {}
|
| -
|
| - ~RouterData() {}
|
| -
|
| - // The owner of the routed data.
|
| - ObjectBackedNativeHandler* const self;
|
| -
|
| - // The function to route calls to.
|
| - HandlerFunction function;
|
| -};
|
| +namespace {
|
| +// Key for the base::Bound routed function.
|
| +const char* kHandlerFunction = "handler_function";
|
| +} // namespace
|
|
|
| ObjectBackedNativeHandler::ObjectBackedNativeHandler(
|
| v8::Handle<v8::Context> context)
|
| @@ -42,29 +33,39 @@ v8::Handle<v8::Object> ObjectBackedNativeHandler::NewInstance() {
|
| // static
|
| v8::Handle<v8::Value> ObjectBackedNativeHandler::Router(
|
| const v8::Arguments& args) {
|
| - RouterData* router_data = static_cast<RouterData*>(
|
| - args.Data().As<v8::External>()->Value());
|
| - // Router can be called during context destruction. Stop.
|
| - if (!router_data->self->is_valid())
|
| - return v8::Handle<v8::Value>();
|
| - return router_data->function.Run(args);
|
| + v8::HandleScope handle_scope;
|
| + v8::Handle<v8::Object> data = args.Data().As<v8::Object>();
|
| +
|
| + v8::Handle<v8::Value> handler_function_value =
|
| + data->Get(v8::String::New(kHandlerFunction));
|
| + // See comment in header file for why we do this.
|
| + if (handler_function_value.IsEmpty()) {
|
| + return v8::ThrowException(v8::String::New(
|
| + "Extension view no longer exists"));
|
| + }
|
| + return handle_scope.Close(static_cast<HandlerFunction*>(
|
| + handler_function_value.As<v8::External>()->Value())->Run(args));
|
| }
|
|
|
| void ObjectBackedNativeHandler::RouteFunction(
|
| const std::string& name,
|
| const HandlerFunction& handler_function) {
|
| - linked_ptr<RouterData> data(new RouterData(this, handler_function));
|
| - // TODO(koz): Investigate using v8's MakeWeak() function instead of holding
|
| - // on to these pointers here.
|
| + v8::HandleScope handle_scope;
|
| + v8::Context::Scope context_scope(v8_context_.get());
|
| +
|
| + v8::Persistent<v8::Object> data = v8::Persistent<v8::Object>::New(
|
| + v8_context_->GetIsolate(), v8::Object::New());
|
| + data->Set(v8::String::New(kHandlerFunction),
|
| + v8::External::New(new HandlerFunction(handler_function)));
|
| router_data_.push_back(data);
|
| v8::Handle<v8::FunctionTemplate> function_template =
|
| - v8::FunctionTemplate::New(Router, v8::External::New(data.get()));
|
| + v8::FunctionTemplate::New(Router, data);
|
| object_template_->Set(name.c_str(), function_template);
|
| }
|
|
|
| void ObjectBackedNativeHandler::RouteStaticFunction(
|
| const std::string& name,
|
| - const HandlerFunc handler_func) {
|
| + const HandlerFunc& handler_func) {
|
| v8::Handle<v8::FunctionTemplate> function_template =
|
| v8::FunctionTemplate::New(handler_func, v8::External::New(this));
|
| object_template_->Set(name.c_str(), function_template);
|
| @@ -73,6 +74,20 @@ void ObjectBackedNativeHandler::RouteStaticFunction(
|
| void ObjectBackedNativeHandler::Invalidate() {
|
| if (!is_valid())
|
| return;
|
| + v8::HandleScope handle_scope;
|
| + v8::Context::Scope context_scope(v8_context_.get());
|
| +
|
| + for (RouterData::iterator it = router_data_.begin();
|
| + it != router_data_.end(); ++it) {
|
| + v8::Persistent<v8::Object> data = *it;
|
| + v8::Handle<v8::Value> handler_function_value =
|
| + data->Get(v8::String::New(kHandlerFunction));
|
| + CHECK(!handler_function_value.IsEmpty());
|
| + delete static_cast<HandlerFunction*>(
|
| + handler_function_value.As<v8::External>()->Value());
|
| + data->Delete(v8::String::New(kHandlerFunction));
|
| + data.Dispose(v8_context_->GetIsolate());
|
| + }
|
| object_template_.reset();
|
| v8_context_.reset();
|
| NativeHandler::Invalidate();
|
|
|