diff --git a/atom.gyp b/atom.gyp index a69667f2af65..444c3e6e9b1b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -160,6 +160,8 @@ 'atom/common/api/atom_extensions.h', 'atom/common/api/object_life_monitor.cc', 'atom/common/api/object_life_monitor.h', + 'atom/common/browser_v8_locker.cc', + 'atom/common/browser_v8_locker.h', 'atom/common/crash_reporter/crash_reporter.cc', 'atom/common/crash_reporter/crash_reporter.h', 'atom/common/crash_reporter/crash_reporter_linux.cc', @@ -178,6 +180,7 @@ 'atom/common/draggable_region.h', 'atom/common/linux/application_info.cc', 'atom/common/native_mate_converters/file_path_converter.h', + 'atom/common/native_mate_converters/function_converter.h', 'atom/common/native_mate_converters/string16_converter.h', 'atom/common/native_mate_converters/v8_value_converter.cc', 'atom/common/native_mate_converters/v8_value_converter.h', diff --git a/atom/common/browser_v8_locker.cc b/atom/common/browser_v8_locker.cc new file mode 100644 index 000000000000..6dcb9f186e3c --- /dev/null +++ b/atom/common/browser_v8_locker.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "atom/common/browser_v8_locker.h" + +namespace node { +extern bool g_standalone_mode; +} + +namespace atom { + +BrowserV8Locker::BrowserV8Locker(v8::Isolate* isolate) { + if (node::g_standalone_mode) + locker_.reset(new v8::Locker(isolate)); +} + +BrowserV8Locker::~BrowserV8Locker() { +} + +} // namespace atom diff --git a/atom/common/browser_v8_locker.h b/atom/common/browser_v8_locker.h new file mode 100644 index 000000000000..4e508e2556bc --- /dev/null +++ b/atom/common/browser_v8_locker.h @@ -0,0 +1,28 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_LOCKED_HANDLE_SCOPE_H_ +#define ATOM_COMMON_LOCKED_HANDLE_SCOPE_H_ + +#include "base/memory/scoped_ptr.h" +#include "v8/include/v8.h" + +namespace atom { + +// Like v8::Locker, but only do lock when in browser process. +class BrowserV8Locker { + public: + BrowserV8Locker(v8::Isolate* isolate); + ~BrowserV8Locker(); + + private: + void* operator new(size_t size); + void operator delete(void*, size_t); + + scoped_ptr locker_; +}; + +} // namespace atom + +#endif // ATOM_COMMON_LOCKED_HANDLE_SCOPE_H_ diff --git a/atom/common/native_mate_converters/function_converter.h b/atom/common/native_mate_converters/function_converter.h new file mode 100644 index 000000000000..170a8cc32dbe --- /dev/null +++ b/atom/common/native_mate_converters/function_converter.h @@ -0,0 +1,209 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_ + +#include "atom/common/browser_v8_locker.h" +#include "base/bind.h" +#include "base/callback.h" +#include "native_mate/constructor.h" +#include "native_mate/scoped_persistent.h" + +namespace mate { + +namespace internal { + +typedef scoped_refptr > SafeV8Function; + +// Helper to convert type to V8 with storage type (const T& to T). +template +v8::Handle ConvertToV8(v8::Isolate* isolate, T a) { + return Converter::StorageType> + ::ToV8(isolate, a); +} + +// This set of templates invokes a V8::Function by converting the C++ types. +template +struct V8FunctionInvoker; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function) { + R ret; + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle val(holder->Call(holder, 0, NULL)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template<> +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function) { + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + holder->Call(holder, 0, NULL); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { + R ret; + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + }; + v8::Handle val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { + R ret; + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + }; + v8::Handle val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3) { + R ret; + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + }; + v8::Handle val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3) { + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4) { + R ret; + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + }; + v8::Handle val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4) { + atom::BrowserV8Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +} // namespace internal + +template +struct Converter > { + static v8::Handle ToV8(v8::Isolate* isolate, + const base::Callback& val) { + return CreateFunctionTemplate(isolate, val)->GetFunction(); + } + static bool FromV8(v8::Isolate* isolate, + v8::Handle val, + base::Callback* out) { + if (!val->IsFunction()) + return false; + + internal::SafeV8Function function( + new RefCountedPersistent(val)); + *out = base::Bind(&internal::V8FunctionInvoker::Go, isolate, function); + return true; + } +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_ diff --git a/vendor/native_mate b/vendor/native_mate index 94dec0ff85c9..9cc90ac7d52e 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 94dec0ff85c9337d33cae01638897bc1059b7dca +Subproject commit 9cc90ac7d52e04d909ffdceda130e12d8f79e0e8