diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-17 21:47:04 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-17 21:47:04 +0000 |
commit | cb6c2bb25fa9cb9aaa7713fb829f77d660899b39 (patch) | |
tree | ee85fec3be3152fcb7ad8c8caa8dac19072a37e8 /gin | |
parent | 22c17bcb2e798ed74c25cd366b40d8483c7eaf24 (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | gin/function_template.h | 5 | ||||
-rw-r--r-- | gin/function_template.h.pump | 6 | ||||
-rw-r--r-- | gin/isolate_holder.cc | 1 | ||||
-rw-r--r-- | gin/object_template_builder.cc | 2 | ||||
-rw-r--r-- | gin/wrappable.cc | 24 | ||||
-rw-r--r-- | gin/wrappable.h | 37 | ||||
-rw-r--r-- | gin/wrappable_unittest.cc | 30 |
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); |