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