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.
5 #include "gin/object_template_builder.h"
7 #include "gin/interceptor.h"
8 #include "gin/per_isolate_data.h"
9 #include "gin/public/wrapper_info.h"
15 WrappableBase
* WrappableFromV8(v8::Isolate
* isolate
,
16 v8::Local
<v8::Value
> val
) {
19 v8::Local
<v8::Object
> obj
= v8::Local
<v8::Object
>::Cast(val
);
20 WrapperInfo
* info
= WrapperInfo::From(obj
);
22 // If this fails, the object is not managed by Gin.
26 // We don't further validate the type of the object, but assume it's derived
27 // from WrappableBase. We look up the pointer in a global registry, to make
28 // sure it's actually pointed to a valid life object.
29 return static_cast<WrappableBase
*>(
30 obj
->GetAlignedPointerFromInternalField(kEncodedValueIndex
));
33 NamedPropertyInterceptor
* NamedInterceptorFromV8(v8::Isolate
* isolate
,
34 v8::Local
<v8::Value
> val
) {
35 WrappableBase
* base
= WrappableFromV8(isolate
, val
);
38 return PerIsolateData::From(isolate
)->GetNamedPropertyInterceptor(base
);
41 IndexedPropertyInterceptor
* IndexedInterceptorFromV8(
43 v8::Local
<v8::Value
> val
) {
44 WrappableBase
* base
= WrappableFromV8(isolate
, val
);
47 return PerIsolateData::From(isolate
)->GetIndexedPropertyInterceptor(base
);
50 void NamedPropertyGetter(v8::Local
<v8::String
> property
,
51 const v8::PropertyCallbackInfo
<v8::Value
>& info
) {
52 v8::Isolate
* isolate
= info
.GetIsolate();
53 NamedPropertyInterceptor
* interceptor
=
54 NamedInterceptorFromV8(isolate
, info
.Holder());
58 ConvertFromV8(isolate
, property
, &name
);
59 info
.GetReturnValue().Set(interceptor
->GetNamedProperty(isolate
, name
));
62 void NamedPropertySetter(v8::Local
<v8::String
> property
,
63 v8::Local
<v8::Value
> value
,
64 const v8::PropertyCallbackInfo
<v8::Value
>& info
) {
65 v8::Isolate
* isolate
= info
.GetIsolate();
66 NamedPropertyInterceptor
* interceptor
=
67 NamedInterceptorFromV8(isolate
, info
.Holder());
71 ConvertFromV8(isolate
, property
, &name
);
72 if (interceptor
->SetNamedProperty(isolate
, name
, value
))
73 info
.GetReturnValue().Set(value
);
76 void NamedPropertyQuery(v8::Local
<v8::String
> property
,
77 const v8::PropertyCallbackInfo
<v8::Integer
>& info
) {
78 v8::Isolate
* isolate
= info
.GetIsolate();
79 NamedPropertyInterceptor
* interceptor
=
80 NamedInterceptorFromV8(isolate
, info
.Holder());
84 ConvertFromV8(isolate
, property
, &name
);
85 if (interceptor
->GetNamedProperty(isolate
, name
).IsEmpty())
87 info
.GetReturnValue().Set(0);
90 void NamedPropertyEnumerator(const v8::PropertyCallbackInfo
<v8::Array
>& info
) {
91 v8::Isolate
* isolate
= info
.GetIsolate();
92 NamedPropertyInterceptor
* interceptor
=
93 NamedInterceptorFromV8(isolate
, info
.Holder());
96 v8::Local
<v8::Value
> properties
;
97 if (!TryConvertToV8(isolate
, interceptor
->EnumerateNamedProperties(isolate
),
100 info
.GetReturnValue().Set(v8::Local
<v8::Array
>::Cast(properties
));
103 void IndexedPropertyGetter(uint32_t index
,
104 const v8::PropertyCallbackInfo
<v8::Value
>& info
) {
105 v8::Isolate
* isolate
= info
.GetIsolate();
106 IndexedPropertyInterceptor
* interceptor
=
107 IndexedInterceptorFromV8(isolate
, info
.Holder());
110 info
.GetReturnValue().Set(interceptor
->GetIndexedProperty(isolate
, index
));
113 void IndexedPropertySetter(uint32_t index
,
114 v8::Local
<v8::Value
> value
,
115 const v8::PropertyCallbackInfo
<v8::Value
>& info
) {
116 v8::Isolate
* isolate
= info
.GetIsolate();
117 IndexedPropertyInterceptor
* interceptor
=
118 IndexedInterceptorFromV8(isolate
, info
.Holder());
121 if (interceptor
->SetIndexedProperty(isolate
, index
, value
))
122 info
.GetReturnValue().Set(value
);
125 void IndexedPropertyEnumerator(
126 const v8::PropertyCallbackInfo
<v8::Array
>& info
) {
127 v8::Isolate
* isolate
= info
.GetIsolate();
128 IndexedPropertyInterceptor
* interceptor
=
129 IndexedInterceptorFromV8(isolate
, info
.Holder());
132 v8::Local
<v8::Value
> properties
;
133 if (!TryConvertToV8(isolate
, interceptor
->EnumerateIndexedProperties(isolate
),
136 info
.GetReturnValue().Set(v8::Local
<v8::Array
>::Cast(properties
));
141 ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate
* isolate
)
142 : isolate_(isolate
), template_(v8::ObjectTemplate::New(isolate
)) {
143 template_
->SetInternalFieldCount(kNumberOfInternalFields
);
146 ObjectTemplateBuilder::~ObjectTemplateBuilder() {
149 ObjectTemplateBuilder
& ObjectTemplateBuilder::AddNamedPropertyInterceptor() {
150 template_
->SetNamedPropertyHandler(&NamedPropertyGetter
,
151 &NamedPropertySetter
,
154 &NamedPropertyEnumerator
);
158 ObjectTemplateBuilder
& ObjectTemplateBuilder::AddIndexedPropertyInterceptor() {
159 template_
->SetIndexedPropertyHandler(&IndexedPropertyGetter
,
160 &IndexedPropertySetter
,
163 &IndexedPropertyEnumerator
);
167 ObjectTemplateBuilder
& ObjectTemplateBuilder::SetImpl(
168 const base::StringPiece
& name
, v8::Local
<v8::Data
> val
) {
169 template_
->Set(StringToSymbol(isolate_
, name
), val
);
173 ObjectTemplateBuilder
& ObjectTemplateBuilder::SetPropertyImpl(
174 const base::StringPiece
& name
, v8::Local
<v8::FunctionTemplate
> getter
,
175 v8::Local
<v8::FunctionTemplate
> setter
) {
176 template_
->SetAccessorProperty(StringToSymbol(isolate_
, name
), getter
,
181 v8::Local
<v8::ObjectTemplate
> ObjectTemplateBuilder::Build() {
182 v8::Local
<v8::ObjectTemplate
> result
= template_
;