object_template_builder.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "gin/object_template_builder.h"
  5. #include <stdint.h>
  6. #include "gin/interceptor.h"
  7. #include "gin/per_isolate_data.h"
  8. #include "gin/public/wrapper_info.h"
  9. namespace gin {
  10. namespace {
  11. WrappableBase* WrappableFromV8(v8::Isolate* isolate,
  12. v8::Local<v8::Value> val) {
  13. if (!val->IsObject())
  14. return NULL;
  15. v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
  16. WrapperInfo* info = WrapperInfo::From(obj);
  17. // If this fails, the object is not managed by Gin.
  18. if (!info)
  19. return NULL;
  20. // We don't further validate the type of the object, but assume it's derived
  21. // from WrappableBase. We look up the pointer in a global registry, to make
  22. // sure it's actually pointed to a valid life object.
  23. return static_cast<WrappableBase*>(
  24. obj->GetAlignedPointerFromInternalField(kEncodedValueIndex));
  25. }
  26. NamedPropertyInterceptor* NamedInterceptorFromV8(v8::Isolate* isolate,
  27. v8::Local<v8::Value> val) {
  28. WrappableBase* base = WrappableFromV8(isolate, val);
  29. if (!base)
  30. return NULL;
  31. return PerIsolateData::From(isolate)->GetNamedPropertyInterceptor(base);
  32. }
  33. IndexedPropertyInterceptor* IndexedInterceptorFromV8(
  34. v8::Isolate* isolate,
  35. v8::Local<v8::Value> val) {
  36. WrappableBase* base = WrappableFromV8(isolate, val);
  37. if (!base)
  38. return NULL;
  39. return PerIsolateData::From(isolate)->GetIndexedPropertyInterceptor(base);
  40. }
  41. void NamedPropertyGetter(v8::Local<v8::Name> property,
  42. const v8::PropertyCallbackInfo<v8::Value>& info) {
  43. v8::Isolate* isolate = info.GetIsolate();
  44. NamedPropertyInterceptor* interceptor =
  45. NamedInterceptorFromV8(isolate, info.Holder());
  46. if (!interceptor)
  47. return;
  48. std::string name;
  49. ConvertFromV8(isolate, property, &name);
  50. info.GetReturnValue().Set(interceptor->GetNamedProperty(isolate, name));
  51. }
  52. void NamedPropertySetter(v8::Local<v8::Name> property,
  53. v8::Local<v8::Value> value,
  54. const v8::PropertyCallbackInfo<v8::Value>& info) {
  55. v8::Isolate* isolate = info.GetIsolate();
  56. NamedPropertyInterceptor* interceptor =
  57. NamedInterceptorFromV8(isolate, info.Holder());
  58. if (!interceptor)
  59. return;
  60. std::string name;
  61. ConvertFromV8(isolate, property, &name);
  62. if (interceptor->SetNamedProperty(isolate, name, value))
  63. info.GetReturnValue().Set(value);
  64. }
  65. void NamedPropertyQuery(v8::Local<v8::Name> property,
  66. const v8::PropertyCallbackInfo<v8::Integer>& info) {
  67. v8::Isolate* isolate = info.GetIsolate();
  68. NamedPropertyInterceptor* interceptor =
  69. NamedInterceptorFromV8(isolate, info.Holder());
  70. if (!interceptor)
  71. return;
  72. std::string name;
  73. ConvertFromV8(isolate, property, &name);
  74. if (interceptor->GetNamedProperty(isolate, name).IsEmpty())
  75. return;
  76. info.GetReturnValue().Set(0);
  77. }
  78. void NamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
  79. v8::Isolate* isolate = info.GetIsolate();
  80. NamedPropertyInterceptor* interceptor =
  81. NamedInterceptorFromV8(isolate, info.Holder());
  82. if (!interceptor)
  83. return;
  84. v8::Local<v8::Value> properties;
  85. if (!TryConvertToV8(isolate, interceptor->EnumerateNamedProperties(isolate),
  86. &properties))
  87. return;
  88. info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties));
  89. }
  90. void IndexedPropertyGetter(uint32_t index,
  91. const v8::PropertyCallbackInfo<v8::Value>& info) {
  92. v8::Isolate* isolate = info.GetIsolate();
  93. IndexedPropertyInterceptor* interceptor =
  94. IndexedInterceptorFromV8(isolate, info.Holder());
  95. if (!interceptor)
  96. return;
  97. info.GetReturnValue().Set(interceptor->GetIndexedProperty(isolate, index));
  98. }
  99. void IndexedPropertySetter(uint32_t index,
  100. v8::Local<v8::Value> value,
  101. const v8::PropertyCallbackInfo<v8::Value>& info) {
  102. v8::Isolate* isolate = info.GetIsolate();
  103. IndexedPropertyInterceptor* interceptor =
  104. IndexedInterceptorFromV8(isolate, info.Holder());
  105. if (!interceptor)
  106. return;
  107. if (interceptor->SetIndexedProperty(isolate, index, value))
  108. info.GetReturnValue().Set(value);
  109. }
  110. void IndexedPropertyEnumerator(
  111. const v8::PropertyCallbackInfo<v8::Array>& info) {
  112. v8::Isolate* isolate = info.GetIsolate();
  113. IndexedPropertyInterceptor* interceptor =
  114. IndexedInterceptorFromV8(isolate, info.Holder());
  115. if (!interceptor)
  116. return;
  117. v8::Local<v8::Value> properties;
  118. if (!TryConvertToV8(isolate, interceptor->EnumerateIndexedProperties(isolate),
  119. &properties))
  120. return;
  121. info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties));
  122. }
  123. } // namespace
  124. ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
  125. : ObjectTemplateBuilder(isolate, nullptr) {}
  126. ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate,
  127. const char* type_name)
  128. : ObjectTemplateBuilder(isolate,
  129. type_name,
  130. v8::ObjectTemplate::New(isolate)) {}
  131. ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate,
  132. const char* type_name,
  133. v8::Local<v8::ObjectTemplate> tmpl)
  134. : isolate_(isolate), type_name_(type_name), template_(tmpl) {
  135. template_->SetInternalFieldCount(kNumberOfInternalFields);
  136. }
  137. ObjectTemplateBuilder::ObjectTemplateBuilder(
  138. const ObjectTemplateBuilder& other) = default;
  139. ObjectTemplateBuilder::~ObjectTemplateBuilder() = default;
  140. ObjectTemplateBuilder& ObjectTemplateBuilder::AddNamedPropertyInterceptor() {
  141. template_->SetHandler(v8::NamedPropertyHandlerConfiguration(
  142. &NamedPropertyGetter, &NamedPropertySetter, &NamedPropertyQuery, nullptr,
  143. &NamedPropertyEnumerator, v8::Local<v8::Value>(),
  144. v8::PropertyHandlerFlags::kOnlyInterceptStrings));
  145. return *this;
  146. }
  147. ObjectTemplateBuilder& ObjectTemplateBuilder::AddIndexedPropertyInterceptor() {
  148. template_->SetIndexedPropertyHandler(&IndexedPropertyGetter,
  149. &IndexedPropertySetter,
  150. NULL,
  151. NULL,
  152. &IndexedPropertyEnumerator);
  153. return *this;
  154. }
  155. ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(
  156. const base::StringPiece& name, v8::Local<v8::Data> val) {
  157. template_->Set(StringToSymbol(isolate_, name), val);
  158. return *this;
  159. }
  160. ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(v8::Local<v8::Name> name,
  161. v8::Local<v8::Data> val) {
  162. template_->Set(name, val);
  163. return *this;
  164. }
  165. ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
  166. const base::StringPiece& name, v8::Local<v8::FunctionTemplate> getter,
  167. v8::Local<v8::FunctionTemplate> setter) {
  168. template_->SetAccessorProperty(StringToSymbol(isolate_, name), getter,
  169. setter);
  170. return *this;
  171. }
  172. ObjectTemplateBuilder& ObjectTemplateBuilder::SetLazyDataPropertyImpl(
  173. const base::StringPiece& name,
  174. v8::AccessorNameGetterCallback callback,
  175. v8::Local<v8::Value> data) {
  176. template_->SetLazyDataProperty(StringToSymbol(isolate_, name), callback,
  177. data);
  178. return *this;
  179. }
  180. v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
  181. v8::Local<v8::ObjectTemplate> result = template_;
  182. template_.Clear();
  183. return result;
  184. }
  185. } // namespace gin