diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index d838ae39638..444124b24b6 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -8,7 +8,6 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/v8_value_converter.h" -#include "native_mate/function_template.h" namespace atom { @@ -16,18 +15,12 @@ namespace internal { namespace { -struct CallbackHolder { - ResponseCallback callback; -}; - -// Cached JavaScript version of |HandlerCallback|. -v8::Persistent g_handler_callback_; - // The callback which is passed to |handler|. -void HandlerCallback(v8::Isolate* isolate, - v8::Local external, +void HandlerCallback(const ResponseCallback& callback, v8::Local state, mate::Arguments* args) { + v8::Isolate* isolate = args->isolate(); + // Check if the callback has already been called. v8::Local called_symbol = mate::StringToSymbol(isolate, "called"); if (state->Has(called_symbol)) @@ -36,14 +29,11 @@ void HandlerCallback(v8::Isolate* isolate, state->Set(called_symbol, v8::Boolean::New(isolate, true)); // If there is no argument passed then we failed. - scoped_ptr holder( - static_cast(external->Value())); - CHECK(holder); v8::Local value; if (!args->GetNext(&value)) { content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, - base::Bind(holder->callback, false, nullptr)); + base::Bind(callback, false, nullptr)); return; } @@ -53,42 +43,7 @@ void HandlerCallback(v8::Isolate* isolate, scoped_ptr options(converter.FromV8Value(value, context)); content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, - base::Bind(holder->callback, true, base::Passed(&options))); -} - -// func.bind(func, arg1, arg2). -// NB(zcbenz): Using C++11 version crashes VS. -v8::Local BindFunctionWith(v8::Isolate* isolate, - v8::Local context, - v8::Local func, - v8::Local arg1, - v8::Local arg2) { - v8::MaybeLocal bind = func->Get(mate::StringToV8(isolate, "bind")); - CHECK(!bind.IsEmpty()); - v8::Local bind_func = - v8::Local::Cast(bind.ToLocalChecked()); - v8::Local converted[] = { func, arg1, arg2 }; - return bind_func->Call( - context, func, arraysize(converted), converted).ToLocalChecked(); -} - -// Generate the callback that will be passed to |handler|. -v8::MaybeLocal GenerateCallback(v8::Isolate* isolate, - v8::Local context, - const ResponseCallback& callback) { - // The FunctionTemplate is cached. - if (g_handler_callback_.IsEmpty()) - g_handler_callback_.Reset( - isolate, - mate::CreateFunctionTemplate(isolate, base::Bind(&HandlerCallback))); - - v8::Local handler_callback = - v8::Local::New(isolate, g_handler_callback_); - CallbackHolder* holder = new CallbackHolder; - holder->callback = callback; - return BindFunctionWith(isolate, context, handler_callback->GetFunction(), - v8::External::New(isolate, holder), - v8::Object::New(isolate)); + base::Bind(callback, true, base::Passed(&options))); } } // namespace @@ -102,16 +57,10 @@ void AskForOptions(v8::Isolate* isolate, v8::HandleScope handle_scope(isolate); v8::Local context = isolate->GetCurrentContext(); v8::Context::Scope context_scope(context); - // We don't convert the callback to C++ directly because creating - // FunctionTemplate will cause memory leak since V8 never releases it. So we - // have to create the function object in JavaScript to work around it. - v8::MaybeLocal wrapped_callback = GenerateCallback( - isolate, context, callback); - if (wrapped_callback.IsEmpty()) { - callback.Run(false, nullptr); - return; - } - handler.Run(request, wrapped_callback.ToLocalChecked()); + v8::Local state = v8::Object::New(isolate); + handler.Run(request, + mate::ConvertToV8(isolate, + base::Bind(&HandlerCallback, callback, state))); } bool IsErrorOptions(base::Value* value, int* error) {