summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-23 20:26:51 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-23 20:26:51 +0000
commit314cde1222cbc81c1d42054fc379235598f0125a (patch)
treea9a698a4acebe708171d972cd1151455bc9da916 /gin
parent52e48aed8d0ec12cfb7b22434805758cfee5d41c (diff)
downloadchromium_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.h6
-rw-r--r--gin/function_template.cc26
-rw-r--r--gin/function_template.h85
-rw-r--r--gin/gin.gyp2
-rw-r--r--gin/isolate_holder.cc2
-rw-r--r--gin/test/gtest.cc45
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);