summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-17 21:47:04 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-17 21:47:04 +0000
commitcb6c2bb25fa9cb9aaa7713fb829f77d660899b39 (patch)
treeee85fec3be3152fcb7ad8c8caa8dac19072a37e8 /gin
parent22c17bcb2e798ed74c25cd366b40d8483c7eaf24 (diff)
downloadchromium_src-cb6c2bb25fa9cb9aaa7713fb829f77d660899b39.zip
chromium_src-cb6c2bb25fa9cb9aaa7713fb829f77d660899b39.tar.gz
chromium_src-cb6c2bb25fa9cb9aaa7713fb829f77d660899b39.tar.bz2
[gin] Introduce Wrappable::GetObjectTemplate
Instead of explicitly registering object templates for all wrapper infos, add a method on wrappable that returns the template when needed. BUG=none R=aa@chromium.org,abarth@chromium.org Review URL: https://codereview.chromium.org/113893005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241370 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin')
-rw-r--r--gin/function_template.cc17
-rw-r--r--gin/function_template.h5
-rw-r--r--gin/function_template.h.pump6
-rw-r--r--gin/isolate_holder.cc1
-rw-r--r--gin/object_template_builder.cc2
-rw-r--r--gin/wrappable.cc24
-rw-r--r--gin/wrappable.h37
-rw-r--r--gin/wrappable_unittest.cc30
8 files changed, 62 insertions, 60 deletions
diff --git a/gin/function_template.cc b/gin/function_template.cc
index 5dd5ecd..243ac12 100644
--- a/gin/function_template.cc
+++ b/gin/function_template.cc
@@ -4,23 +4,12 @@
#include "gin/function_template.h"
-#include "gin/per_isolate_data.h"
-
namespace gin {
-WrapperInfo internal::CallbackHolderBase::kWrapperInfo = { kEmbedderNativeGin };
+namespace internal {
-void InitFunctionTemplates(PerIsolateData* isolate_data) {
- if (!isolate_data->GetObjectTemplate(
- &internal::CallbackHolderBase::kWrapperInfo).IsEmpty()) {
- return;
- }
+WrapperInfo CallbackHolderBase::kWrapperInfo = { kEmbedderNativeGin };
- v8::Handle<v8::ObjectTemplate> templ(
- v8::ObjectTemplate::New(isolate_data->isolate()));
- templ->SetInternalFieldCount(kNumberOfInternalFields);
- isolate_data->SetObjectTemplate(&internal::CallbackHolderBase::kWrapperInfo,
- templ);
-}
+} // namespace internal
} // namespace gin
diff --git a/gin/function_template.h b/gin/function_template.h
index 14f6e78..f028f2d 100644
--- a/gin/function_template.h
+++ b/gin/function_template.h
@@ -331,11 +331,6 @@ struct Dispatcher<R(P1, P2, P3, P4)> {
} // namespace internal
-// This should be called once per-isolate to initialize the function template
-// system.
-GIN_EXPORT void InitFunctionTemplates(PerIsolateData* isolate_data);
-
-
// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
// JavaScript functions that execute a provided C++ function or base::Callback.
// JavaScript arguments are automatically converted via gin::Converter, as is
diff --git a/gin/function_template.h.pump b/gin/function_template.h.pump
index fad718f..6c1dbfa2 100644
--- a/gin/function_template.h.pump
+++ b/gin/function_template.h.pump
@@ -65,7 +65,6 @@ struct CallbackParamTraits<const T*> {
class GIN_EXPORT CallbackHolderBase : public Wrappable<CallbackHolderBase> {
public:
static WrapperInfo kWrapperInfo;
-
protected:
virtual ~CallbackHolderBase() {}
};
@@ -187,11 +186,6 @@ $for ARG [[ typename CallbackParamTraits<P$(ARG)>::LocalType a$(ARG);
} // namespace internal
-// This should be called once per-isolate to initialize the function template
-// system.
-GIN_EXPORT void InitFunctionTemplates(PerIsolateData* isolate_data);
-
-
// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
// JavaScript functions that execute a provided C++ function or base::Callback.
// JavaScript arguments are automatically converted via gin::Converter, as is
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 1929ebd..411f26a 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -73,7 +73,6 @@ void IsolateHolder::Init() {
v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope handle_scope(isolate_);
isolate_data_.reset(new PerIsolateData(isolate_));
- InitFunctionTemplates(isolate_data_.get());
}
} // namespace gin
diff --git a/gin/object_template_builder.cc b/gin/object_template_builder.cc
index 6dc6d2f..8bc2714 100644
--- a/gin/object_template_builder.cc
+++ b/gin/object_template_builder.cc
@@ -3,11 +3,13 @@
// found in the LICENSE file.
#include "gin/object_template_builder.h"
+#include "gin/public/wrapper_info.h"
namespace gin {
ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
: isolate_(isolate), template_(v8::ObjectTemplate::New(isolate)) {
+ template_->SetInternalFieldCount(kNumberOfInternalFields);
}
ObjectTemplateBuilder::~ObjectTemplateBuilder() {
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index 4a9ef0e..3446f4f 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -5,6 +5,7 @@
#include "gin/wrappable.h"
#include "base/logging.h"
+#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
namespace gin {
@@ -17,12 +18,19 @@ WrappableBase::~WrappableBase() {
}
v8::Handle<v8::Object> WrappableBase::GetWrapperImpl(
- v8::Isolate* isolate, WrapperInfo* wrapper_info) {
+ v8::Isolate* isolate,
+ WrapperInfo* wrapper_info,
+ GetObjectTemplateFunction template_getter) {
if (wrapper_.IsEmpty())
- CreateWrapper(isolate, wrapper_info);
+ CreateWrapper(isolate, wrapper_info, template_getter);
return v8::Local<v8::Object>::New(isolate, wrapper_);
}
+v8::Local<v8::ObjectTemplate> WrappableBase::GetObjectTemplate(
+ v8::Isolate* isolate) {
+ return ObjectTemplateBuilder(isolate).Build();
+}
+
void WrappableBase::WeakCallback(
const v8::WeakCallbackData<v8::Object, WrappableBase>& data) {
WrappableBase* wrappable = data.GetParameter();
@@ -30,11 +38,17 @@ void WrappableBase::WeakCallback(
delete wrappable;
}
-v8::Handle<v8::Object> WrappableBase::CreateWrapper(v8::Isolate* isolate,
- WrapperInfo* info) {
+v8::Handle<v8::Object> WrappableBase::CreateWrapper(
+ v8::Isolate* isolate,
+ WrapperInfo* info,
+ GetObjectTemplateFunction template_getter) {
PerIsolateData* data = PerIsolateData::From(isolate);
v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
- CHECK(!templ.IsEmpty()); // Don't forget to register an object template.
+ if (templ.IsEmpty()) {
+ templ = template_getter(isolate);
+ CHECK(!templ.IsEmpty());
+ data->SetObjectTemplate(info, templ);
+ }
CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount());
v8::Handle<v8::Object> wrapper = templ->NewInstance();
wrapper->SetAlignedPointerInInternalField(kWrapperInfoIndex, info);
diff --git a/gin/wrappable.h b/gin/wrappable.h
index 75570716..fccca1a 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -27,11 +27,22 @@ GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
// USAGE:
// // my_class.h
// class MyClass : Wrappable<MyClass> {
+// public:
+// static WrapperInfo kWrapperInfo;
+//
+// // Optional, only required if non-empty template should be used.
+// static v8::Local<v8::ObjectTemplate> GetObjectTemplate(
+// v8::Isolate* isolate);
// ...
// };
//
// // my_class.cc
-// INIT_WRAPABLE(MyClass);
+// WrapperInfo MyClass::kWrapperInfo = { kEmbedderNativeGin };
+//
+// v8::Local<v8::ObjectTemplate> MyClass::GetObjectTemplate(
+// v8::Isolate* isolate) {
+// return ObjectTemplateBuilder(isolate).SetValue("foobar", 42).Build();
+// }
//
// Subclasses should also typically have private constructors and expose a
// static Create function that returns a gin::Handle. Forcing creators through
@@ -46,18 +57,30 @@ class Wrappable;
// Non-template base class to share code between templates instances.
class GIN_EXPORT WrappableBase {
protected:
+ typedef v8::Local<v8::ObjectTemplate>(*GetObjectTemplateFunction)(
+ v8::Isolate*);
+
WrappableBase();
virtual ~WrappableBase();
- v8::Handle<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
- WrapperInfo* wrapper_info);
- v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate,
- WrapperInfo* wrapper_info);
- v8::Persistent<v8::Object> wrapper_; // Weak
+
+ v8::Handle<v8::Object> GetWrapperImpl(
+ v8::Isolate* isolate,
+ WrapperInfo* wrapper_info,
+ GetObjectTemplateFunction template_getter);
+
+ static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
private:
static void WeakCallback(
const v8::WeakCallbackData<v8::Object, WrappableBase>& data);
+ v8::Handle<v8::Object> CreateWrapper(
+ v8::Isolate* isolate,
+ WrapperInfo* wrapper_info,
+ GetObjectTemplateFunction template_getter);
+
+ v8::Persistent<v8::Object> wrapper_; // Weak
+
DISALLOW_COPY_AND_ASSIGN(WrappableBase);
};
@@ -69,7 +92,7 @@ class Wrappable : public WrappableBase {
// To customize the wrapper created for a subclass, override GetWrapperInfo()
// instead of overriding this function.
v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate) {
- return GetWrapperImpl(isolate, &T::kWrapperInfo);
+ return GetWrapperImpl(isolate, &T::kWrapperInfo, &T::GetObjectTemplate);
}
protected:
diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc
index 3499eed..35035ce 100644
--- a/gin/wrappable_unittest.cc
+++ b/gin/wrappable_unittest.cc
@@ -19,6 +19,8 @@ class MyObject : public Wrappable<MyObject> {
public:
static WrapperInfo kWrapperInfo;
+ static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
+
static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new MyObject());
}
@@ -44,35 +46,22 @@ class MyObjectBlink : public Wrappable<MyObjectBlink> {
};
WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin };
-WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin };
-WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin };
-
-void RegisterTemplates(v8::Isolate* isolate) {
- PerIsolateData* data = PerIsolateData::From(isolate);
- DCHECK(data->GetObjectTemplate(&MyObject::kWrapperInfo).IsEmpty());
-
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplateBuilder(isolate)
+v8::Local<v8::ObjectTemplate> MyObject::GetObjectTemplate(
+ v8::Isolate* isolate) {
+ return ObjectTemplateBuilder(isolate)
.SetProperty("value", &MyObject::value, &MyObject::set_value)
.Build();
- templ->SetInternalFieldCount(kNumberOfInternalFields);
- data->SetObjectTemplate(&MyObject::kWrapperInfo, templ);
-
- templ = v8::ObjectTemplate::New(isolate);
- templ->SetInternalFieldCount(kNumberOfInternalFields);
- data->SetObjectTemplate(&MyObject2::kWrapperInfo, templ);
-
- templ = v8::ObjectTemplate::New(isolate);
- templ->SetInternalFieldCount(kNumberOfInternalFields);
- data->SetObjectTemplate(&MyObjectBlink::kWrapperInfo, templ);
}
+WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin };
+WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin };
+
typedef V8Test WrappableTest;
TEST_F(WrappableTest, WrapAndUnwrap) {
v8::Isolate* isolate = instance_->isolate();
v8::HandleScope handle_scope(isolate);
- RegisterTemplates(isolate);
Handle<MyObject> obj = MyObject::Create(isolate);
v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, obj.get());
@@ -87,8 +76,6 @@ TEST_F(WrappableTest, UnwrapFailures) {
v8::Isolate* isolate = instance_->isolate();
v8::HandleScope handle_scope(isolate);
- RegisterTemplates(isolate);
-
// Something that isn't an object.
v8::Handle<v8::Value> thing = v8::Number::New(42);
MyObject* unwrapped = NULL;
@@ -117,7 +104,6 @@ TEST_F(WrappableTest, GetAndSetProperty) {
v8::Isolate* isolate = instance_->isolate();
v8::HandleScope handle_scope(isolate);
- RegisterTemplates(isolate);
gin::Handle<MyObject> obj = MyObject::Create(isolate);
obj->set_value(42);