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