diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-26 03:31:04 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-26 03:31:04 +0000 |
commit | 37dacfae5e70134813abc97e59e6f4d44e70fff1 (patch) | |
tree | 517a4c81b0bd551378e09de0afcf6588fe1f1d9d /gin | |
parent | a60f20e58d6287ef8e54d474110dd31d64053f1b (diff) | |
download | chromium_src-37dacfae5e70134813abc97e59e6f4d44e70fff1.zip chromium_src-37dacfae5e70134813abc97e59e6f4d44e70fff1.tar.gz chromium_src-37dacfae5e70134813abc97e59e6f4d44e70fff1.tar.bz2 |
Use pump to generate more overloads of CreateFunctionTemplate.
Review URL: https://codereview.chromium.org/86453002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237241 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin')
-rw-r--r-- | gin/function_template.h | 120 | ||||
-rw-r--r-- | gin/function_template.h.pump | 119 | ||||
-rw-r--r-- | gin/test/gtest.cc | 14 |
3 files changed, 237 insertions, 16 deletions
diff --git a/gin/function_template.h b/gin/function_template.h index 9c5b154..7cf84f8 100644 --- a/gin/function_template.h +++ b/gin/function_template.h @@ -1,3 +1,9 @@ +// This file was GENERATED by command: +// pump.py function_template.h.pump +// DO NOT EDIT BY HAND!!! + + + // Copyright 2013 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 file. @@ -16,6 +22,8 @@ namespace gin { class PerIsolateData; +namespace internal { + template<typename T> struct RemoveConstRef { typedef T Type; @@ -25,6 +33,18 @@ struct RemoveConstRef<const T&> { typedef T Type; }; +} // namespace internal + + +// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from +// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to +// DispatchCallback, where it is invoked. +// +// v8::FunctionTemplate only supports passing void* as data so how do we know +// when to delete the base::Callback? That's where CallbackHolderBase comes in. +// It inherits from Wrappable, which delete itself when both (a) the refcount +// via base::RefCounted has dropped to zero, and (b) there are no more +// JavaScript references in V8. class CallbackHolderBase : public Wrappable { public: static void EnsureRegistered(PerIsolateData* isolate_data); @@ -48,9 +68,61 @@ class CallbackHolder : public CallbackHolderBase { virtual ~CallbackHolder() {} }; -// TODO(aa): Generate the overloads below with pump. +template<typename R> +static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<void()> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); -template<typename P1, typename P2> + holder->callback.Run(); +} + +template<typename R> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<R()> callback) { + typedef CallbackHolder<void()> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<R>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +template<typename R, typename P1> +static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<void(P1)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename internal::RemoveConstRef<P1>::Type a1; + if (!args.GetNext(&a1)) { + args.ThrowError(); + return; + } + + holder->callback.Run(a1); +} + +template<typename R, typename P1> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<R(P1)> callback) { + typedef CallbackHolder<void(P1)> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<R, P1>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +template<typename R, typename P1, typename P2> static void DispatchToCallback( const v8::FunctionCallbackInfo<v8::Value>& info) { Arguments args(info); @@ -60,8 +132,8 @@ static void DispatchToCallback( typedef CallbackHolder<void(P1, P2)> HolderT; HolderT* holder = static_cast<HolderT*>(holder_base); - typename RemoveConstRef<P1>::Type a1; - typename RemoveConstRef<P2>::Type a2; + typename internal::RemoveConstRef<P1>::Type a1; + typename internal::RemoveConstRef<P2>::Type a2; if (!args.GetNext(&a1) || !args.GetNext(&a2)) { args.ThrowError(); @@ -71,14 +143,48 @@ static void DispatchToCallback( holder->callback.Run(a1, a2); } -template<typename P1, typename P2> +template<typename R, typename P1, typename P2> v8::Local<v8::FunctionTemplate> CreateFunctionTempate( v8::Isolate* isolate, - const base::Callback<void(P1, P2)>& callback) { + const base::Callback<R(P1, P2)> callback) { typedef CallbackHolder<void(P1, P2)> HolderT; scoped_refptr<HolderT> holder(new HolderT(callback)); return v8::FunctionTemplate::New( - &DispatchToCallback<P1, P2>, + &DispatchToCallback<R, P1, P2>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +template<typename R, typename P1, typename P2, typename P3> +static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<void(P1, P2, P3)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename internal::RemoveConstRef<P1>::Type a1; + typename internal::RemoveConstRef<P2>::Type a2; + typename internal::RemoveConstRef<P3>::Type a3; + if (!args.GetNext(&a1) || + !args.GetNext(&a2) || + !args.GetNext(&a3)) { + args.ThrowError(); + return; + } + + holder->callback.Run(a1, a2, a3); +} + +template<typename R, typename P1, typename P2, typename P3> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<R(P1, P2, P3)> callback) { + typedef CallbackHolder<void(P1, P2, P3)> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<R, P1, P2, P3>, ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); } diff --git a/gin/function_template.h.pump b/gin/function_template.h.pump new file mode 100644 index 0000000..802e048b --- /dev/null +++ b/gin/function_template.h.pump @@ -0,0 +1,119 @@ +$$ 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 = 3 + +// Copyright 2013 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 file. + +#include "base/callback.h" +#include "base/logging.h" +#include "gin/arguments.h" +#include "gin/converter.h" +#include "gin/public/gin_embedders.h" +#include "gin/public/wrapper_info.h" +#include "gin/wrappable.h" + +#include "v8/include/v8.h" + +namespace gin { + +class PerIsolateData; + +namespace internal { + +template<typename T> +struct RemoveConstRef { + typedef T Type; +}; +template<typename T> +struct RemoveConstRef<const T&> { + typedef T Type; +}; + +} // namespace internal + + +// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from +// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to +// DispatchCallback, where it is invoked. +// +// v8::FunctionTemplate only supports passing void* as data so how do we know +// when to delete the base::Callback? That's where CallbackHolderBase comes in. +// It inherits from Wrappable, which delete itself when both (a) the refcount +// via base::RefCounted has dropped to zero, and (b) there are no more +// JavaScript references in V8. +class CallbackHolderBase : public Wrappable { + public: + static void EnsureRegistered(PerIsolateData* isolate_data); + virtual WrapperInfo* GetWrapperInfo() OVERRIDE; + static WrapperInfo kWrapperInfo; + protected: + virtual ~CallbackHolderBase() {} +}; + +template<> +struct Converter<CallbackHolderBase*> + : public WrappableConverter<CallbackHolderBase> {}; + +template<typename Sig> +class CallbackHolder : public CallbackHolderBase { + public: + CallbackHolder(const base::Callback<Sig>& callback) + : callback(callback) {} + base::Callback<Sig> callback; + private: + virtual ~CallbackHolder() {} +}; + +$range ARITY 0..MAX_ARITY +$for ARITY [[ +$range ARG 1..ARITY + +template<typename R$for ARG [[, typename P$(ARG)]]> +static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<void($for ARG , [[P$(ARG)]])> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + +$if ARITY != 0 [[ + + +$for ARG [[ typename internal::RemoveConstRef<P$(ARG)>::Type a$(ARG); + +]] + if ( +$for ARG || + [[!args.GetNext(&a$(ARG))]]) { + args.ThrowError(); + return; + } + +]] + + holder->callback.Run($for ARG , [[a$(ARG)]]); +} + +template<typename R$for ARG [[, typename P$(ARG)]]> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<R($for ARG , [[P$(ARG)]])> callback) { + typedef CallbackHolder<void($for ARG , [[P$(ARG)]])> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<R$for ARG [[, P$(ARG)]]>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +]] + +} // namespace gin diff --git a/gin/test/gtest.cc b/gin/test/gtest.cc index 254c735..eafff4d 100644 --- a/gin/test/gtest.cc +++ b/gin/test/gtest.cc @@ -36,14 +36,10 @@ void ExpectFalse(bool condition, const std::string& description) { EXPECT_FALSE(condition) << description; } -void ExpectEqual(const v8::FunctionCallbackInfo<v8::Value>& info) { - Arguments args(info); - - std::string description; - if (!ConvertFromV8(info[2], &description)) - return args.ThrowTypeError("Expected description."); - - EXPECT_TRUE(info[0]->StrictEquals(info[1])) << description; +void ExpectEqual(const v8::Handle<v8::Value> expected, + const v8::Handle<v8::Value> actual, + const std::string& description) { + EXPECT_TRUE(expected->StrictEquals(actual)) << description; } WrapperInfo g_wrapper_info = { kEmbedderNativeGin }; @@ -65,7 +61,7 @@ v8::Local<v8::ObjectTemplate> GTest::GetTemplate(v8::Isolate* isolate) { templ->Set(StringToSymbol(isolate, "expectFalse"), CreateFunctionTempate(isolate, base::Bind(ExpectFalse))); templ->Set(StringToSymbol(isolate, "expectEqual"), - v8::FunctionTemplate::New(ExpectEqual)); + CreateFunctionTempate(isolate, base::Bind(ExpectEqual))); data->SetObjectTemplate(&g_wrapper_info, templ); } return templ; |