diff --git a/native_mate/callback.h b/native_mate/callback.h new file mode 100644 index 00000000000..98a63a2e46e --- /dev/null +++ b/native_mate/callback.h @@ -0,0 +1,291 @@ +// This file was GENERATED by command: +// pump.py callback.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/callback.h" +#include "native_mate/function_template.h" +#include "native_mate/locker.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; + Locker locker(isolate); + MATE_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) { + Locker locker(isolate); + MATE_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; + Locker locker(isolate); + MATE_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) { + Locker locker(isolate); + MATE_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; + Locker locker(isolate); + MATE_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) { + Locker locker(isolate); + MATE_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; + Locker locker(isolate); + MATE_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) { + Locker locker(isolate); + MATE_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; + Locker locker(isolate); + MATE_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) { + Locker locker(isolate); + MATE_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); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4, P5 a5) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + }; + 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, P5 a5) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + }; + 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, P5 a5, P6 a6) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + ConvertToV8(isolate, a6), + }; + 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, P5 a5, P6 a6) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + v8::Handle args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + ConvertToV8(isolate, a6), + }; + 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 diff --git a/native_mate/callback.h.pump b/native_mate/callback.h.pump new file mode 100644 index 00000000000..0203065ce0c --- /dev/null +++ b/native_mate/callback.h.pump @@ -0,0 +1,111 @@ +$$ This is a pump file for generating file templates. Pump is a python +$$ script that is part of the Google Test suite of utilities. Description +$$ can be found here: +$$ +$$ http://code.google.com/p/googletest/wiki/PumpManual +$$ +$var MAX_ARITY = 6 +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/callback.h" +#include "native_mate/function_template.h" +#include "native_mate/locker.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; + +$range ARITY 0..MAX_ARITY +$for ARITY [[ +$range ARG 1..ARITY + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function$for ARG [[, P$(ARG) a$(ARG)]]) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + +$if ARITY == 0 [[ + v8::Handle val(holder->Call(holder, 0, NULL)); +]] $else [[ + v8::Handle args[] = { +$for ARG [[ + + ConvertToV8(isolate, a$(ARG)), +]] + + }; + v8::Handle val(holder->Call(holder, arraysize(args), args)); +]] + + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template<$for ARG , [[typename P$(ARG)]]> +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function$for ARG [[, P$(ARG) a$(ARG)]]) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Handle holder = function->NewHandle(); + +$if ARITY == 0 [[ + holder->Call(holder, 0, NULL); +]] $else [[ + v8::Handle args[] = { +$for ARG [[ + + ConvertToV8(isolate, a$(ARG)), +]] + + }; + 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 diff --git a/native_mate/locker.cc b/native_mate/locker.cc new file mode 100644 index 00000000000..c85e68e35f3 --- /dev/null +++ b/native_mate/locker.cc @@ -0,0 +1,17 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE.chromium file. + +#include "native_mate/locker.h" + +namespace mate { + +Locker::Locker(v8::Isolate* isolate) { + if (v8::Locker::IsActive()) + locker_.reset(new v8::Locker(isolate)); +} + +Locker::~Locker() { +} + +} // namespace mate diff --git a/native_mate/locker.h b/native_mate/locker.h new file mode 100644 index 00000000000..07acfbb0be9 --- /dev/null +++ b/native_mate/locker.h @@ -0,0 +1,30 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE.chromium file. + +#ifndef NATIVE_MATE_LOCKER_H_ +#define NATIVE_MATE_LOCKER_H_ + +#include "base/memory/scoped_ptr.h" +#include "v8/include/v8.h" + +namespace mate { + +// Only lock when lockers are used in current thread. +class Locker { + public: + explicit Locker(v8::Isolate* isolate); + ~Locker(); + + private: + void* operator new(size_t size); + void operator delete(void*, size_t); + + scoped_ptr locker_; + + DISALLOW_COPY_AND_ASSIGN(Locker); +}; + +} // namespace mate + +#endif // NATIVE_MATE_LOCKER_H_ diff --git a/native_mate/scoped_persistent.h b/native_mate/scoped_persistent.h index 44580221ba0..8c6ee0c3580 100644 --- a/native_mate/scoped_persistent.h +++ b/native_mate/scoped_persistent.h @@ -56,7 +56,7 @@ class ScopedPersistent { v8::Handle NewHandle(v8::Isolate* isolate) const { if (handle_.IsEmpty()) return v8::Local(); - return v8::Local::New(isolate, handle_); + return MATE_PERSISTENT_TO_LOCAL(T, isolate, handle_); } template diff --git a/native_mate_files.gypi b/native_mate_files.gypi index a9e9de3375a..e67e5597371 100644 --- a/native_mate_files.gypi +++ b/native_mate_files.gypi @@ -3,6 +3,7 @@ 'native_mate_files': [ 'native_mate/arguments.cc', 'native_mate/arguments.h', + 'native_mate/callback.h', 'native_mate/compat.h', 'native_mate/constructor.h', 'native_mate/converter.cc', @@ -12,6 +13,8 @@ 'native_mate/function_template.cc', 'native_mate/function_template.h', 'native_mate/handle.h', + 'native_mate/locker.cc', + 'native_mate/locker.h', 'native_mate/object_template_builder.cc', 'native_mate/object_template_builder.h', 'native_mate/scoped_persistent.h',