diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-23 20:26:51 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-23 20:26:51 +0000 |
commit | 314cde1222cbc81c1d42054fc379235598f0125a (patch) | |
tree | a9a698a4acebe708171d972cd1151455bc9da916 /gin | |
parent | 52e48aed8d0ec12cfb7b22434805758cfee5d41c (diff) | |
download | chromium_src-314cde1222cbc81c1d42054fc379235598f0125a.zip chromium_src-314cde1222cbc81c1d42054fc379235598f0125a.tar.gz chromium_src-314cde1222cbc81c1d42054fc379235598f0125a.tar.bz2 |
First cut at gin::Bind().
BUG=
Review URL: https://codereview.chromium.org/76923003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236958 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin')
-rw-r--r-- | gin/arguments.h | 6 | ||||
-rw-r--r-- | gin/function_template.cc | 26 | ||||
-rw-r--r-- | gin/function_template.h | 85 | ||||
-rw-r--r-- | gin/gin.gyp | 2 | ||||
-rw-r--r-- | gin/isolate_holder.cc | 2 | ||||
-rw-r--r-- | gin/test/gtest.cc | 45 |
6 files changed, 135 insertions, 31 deletions
diff --git a/gin/arguments.h b/gin/arguments.h index 1d59d34..8a372ea 100644 --- a/gin/arguments.h +++ b/gin/arguments.h @@ -16,11 +16,17 @@ class Arguments { ~Arguments(); template<typename T> + // TODO(aa): Rename GetHolder(). bool Holder(T* out) { return ConvertFromV8(info_.Holder(), out); } template<typename T> + bool GetData(T* out) { + return ConvertFromV8(info_.Data(), out); + } + + template<typename T> bool GetNext(T* out) { if (next_ >= info_.Length()) { insufficient_arguments_ = true; diff --git a/gin/function_template.cc b/gin/function_template.cc new file mode 100644 index 0000000..9815b67 --- /dev/null +++ b/gin/function_template.cc @@ -0,0 +1,26 @@ +// 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 "gin/function_template.h" + +#include "gin/per_isolate_data.h" + +namespace gin { + +WrapperInfo CallbackHolderBase::kWrapperInfo = { kEmbedderNativeGin }; + +// static +void CallbackHolderBase::EnsureRegistered(PerIsolateData* isolate_data) { + if (!isolate_data->GetObjectTemplate(&kWrapperInfo).IsEmpty()) + return; + v8::Handle<v8::ObjectTemplate> templ(v8::ObjectTemplate::New()); + templ->SetInternalFieldCount(kNumberOfInternalFields); + isolate_data->SetObjectTemplate(&kWrapperInfo, templ); +} + +WrapperInfo* CallbackHolderBase::GetWrapperInfo() { + return &kWrapperInfo; +} + +} // namespace gin diff --git a/gin/function_template.h b/gin/function_template.h new file mode 100644 index 0000000..9c5b154 --- /dev/null +++ b/gin/function_template.h @@ -0,0 +1,85 @@ +// 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; + +template<typename T> +struct RemoveConstRef { + typedef T Type; +}; +template<typename T> +struct RemoveConstRef<const T&> { + typedef T Type; +}; + +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() {} +}; + +// TODO(aa): Generate the overloads below with pump. + +template<typename P1, typename P2> +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)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename RemoveConstRef<P1>::Type a1; + typename RemoveConstRef<P2>::Type a2; + if (!args.GetNext(&a1) || + !args.GetNext(&a2)) { + args.ThrowError(); + return; + } + + holder->callback.Run(a1, a2); +} + +template<typename P1, typename P2> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<void(P1, P2)>& callback) { + typedef CallbackHolder<void(P1, P2)> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<P1, P2>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +} // namespace gin diff --git a/gin/gin.gyp b/gin/gin.gyp index 715db90..7c17910 100644 --- a/gin/gin.gyp +++ b/gin/gin.gyp @@ -29,6 +29,8 @@ 'converter.h', 'dictionary.cc', 'dictionary.h', + 'function_template.cc', + 'function_template.h', 'isolate_holder.cc', 'modules/console.cc', 'modules/console.h', diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 3c2bf9a..9e3109d 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc @@ -11,6 +11,7 @@ #include "base/rand_util.h" #include "base/sys_info.h" #include "gin/array_buffer.h" +#include "gin/function_template.h" #include "gin/per_isolate_data.h" namespace gin { @@ -52,6 +53,7 @@ IsolateHolder::IsolateHolder() v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); isolate_data_.reset(new PerIsolateData(isolate_)); + CallbackHolderBase::EnsureRegistered(isolate_data_.get()); } IsolateHolder::IsolateHolder(v8::Isolate* isolate) diff --git a/gin/test/gtest.cc b/gin/test/gtest.cc index 962bd9a..422d3ec 100644 --- a/gin/test/gtest.cc +++ b/gin/test/gtest.cc @@ -4,44 +4,26 @@ #include "gin/test/gtest.h" +#include "base/bind.h" +#include "base/logging.h" #include "gin/arguments.h" #include "gin/converter.h" +#include "gin/function_template.h" #include "gin/per_isolate_data.h" #include "gin/public/wrapper_info.h" +#include "gin/wrappable.h" #include "testing/gtest/include/gtest/gtest.h" -using v8::ObjectTemplate; - namespace gin { namespace { -void ExpectTrue(const v8::FunctionCallbackInfo<v8::Value>& info) { - Arguments args(info); - - bool value = false; - std::string description; - - if (!args.GetNext(&value) || - !args.GetNext(&description)) { - return args.ThrowError(); - } - - EXPECT_TRUE(value) << description; +void ExpectTrue(bool condition, const std::string& description) { + EXPECT_TRUE(condition) << description; } -void ExpectFalse(const v8::FunctionCallbackInfo<v8::Value>& info) { - Arguments args(info); - - bool value = false; - std::string description; - - if (!args.GetNext(&value) || - !args.GetNext(&description)) { - return args.ThrowError(); - } - - EXPECT_FALSE(value) << description; +void ExpectFalse(bool condition, const std::string& description) { + EXPECT_FALSE(condition) << description; } void ExpectEqual(const v8::FunctionCallbackInfo<v8::Value>& info) { @@ -60,15 +42,16 @@ WrapperInfo g_wrapper_info = { kEmbedderNativeGin }; const char GTest::kModuleName[] = "gtest"; -v8::Local<ObjectTemplate> GTest::GetTemplate(v8::Isolate* isolate) { +v8::Local<v8::ObjectTemplate> GTest::GetTemplate(v8::Isolate* isolate) { PerIsolateData* data = PerIsolateData::From(isolate); - v8::Local<ObjectTemplate> templ = data->GetObjectTemplate(&g_wrapper_info); + v8::Local<v8::ObjectTemplate> templ = + data->GetObjectTemplate(&g_wrapper_info); if (templ.IsEmpty()) { - templ = ObjectTemplate::New(); + templ = v8::ObjectTemplate::New(); templ->Set(StringToSymbol(isolate, "expectTrue"), - v8::FunctionTemplate::New(ExpectTrue)); + CreateFunctionTempate(isolate, base::Bind(ExpectTrue))); templ->Set(StringToSymbol(isolate, "expectFalse"), - v8::FunctionTemplate::New(ExpectFalse)); + CreateFunctionTempate(isolate, base::Bind(ExpectFalse))); templ->Set(StringToSymbol(isolate, "expectEqual"), v8::FunctionTemplate::New(ExpectEqual)); data->SetObjectTemplate(&g_wrapper_info, templ); |