[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 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 | |
| 5 | #include "gin/object_template_builder.h" |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 6 | |
avi | 90e658dd | 2015-12-21 07:16:19 | [diff] [blame] | 7 | #include <stdint.h> |
| 8 | |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 9 | #include "gin/interceptor.h" |
| 10 | #include "gin/per_isolate_data.h" |
[email protected] | cb6c2bb | 2013-12-17 21:47:04 | [diff] [blame] | 11 | #include "gin/public/wrapper_info.h" |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 12 | |
| 13 | namespace gin { |
| 14 | |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 15 | namespace { |
| 16 | |
| 17 | WrappableBase* WrappableFromV8(v8::Isolate* isolate, |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 18 | v8::Local<v8::Value> val) { |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 19 | if (!val->IsObject()) |
| 20 | return NULL; |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 21 | v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val); |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 22 | WrapperInfo* info = WrapperInfo::From(obj); |
| 23 | |
| 24 | // If this fails, the object is not managed by Gin. |
| 25 | if (!info) |
| 26 | return NULL; |
| 27 | |
| 28 | // We don't further validate the type of the object, but assume it's derived |
| 29 | // from WrappableBase. We look up the pointer in a global registry, to make |
| 30 | // sure it's actually pointed to a valid life object. |
| 31 | return static_cast<WrappableBase*>( |
| 32 | obj->GetAlignedPointerFromInternalField(kEncodedValueIndex)); |
| 33 | } |
| 34 | |
| 35 | NamedPropertyInterceptor* NamedInterceptorFromV8(v8::Isolate* isolate, |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 36 | v8::Local<v8::Value> val) { |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 37 | WrappableBase* base = WrappableFromV8(isolate, val); |
| 38 | if (!base) |
| 39 | return NULL; |
| 40 | return PerIsolateData::From(isolate)->GetNamedPropertyInterceptor(base); |
| 41 | } |
| 42 | |
| 43 | IndexedPropertyInterceptor* IndexedInterceptorFromV8( |
| 44 | v8::Isolate* isolate, |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 45 | v8::Local<v8::Value> val) { |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 46 | WrappableBase* base = WrappableFromV8(isolate, val); |
| 47 | if (!base) |
| 48 | return NULL; |
| 49 | return PerIsolateData::From(isolate)->GetIndexedPropertyInterceptor(base); |
| 50 | } |
| 51 | |
| 52 | void NamedPropertyGetter(v8::Local<v8::String> property, |
| 53 | const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 54 | v8::Isolate* isolate = info.GetIsolate(); |
| 55 | NamedPropertyInterceptor* interceptor = |
| 56 | NamedInterceptorFromV8(isolate, info.Holder()); |
| 57 | if (!interceptor) |
| 58 | return; |
| 59 | std::string name; |
| 60 | ConvertFromV8(isolate, property, &name); |
| 61 | info.GetReturnValue().Set(interceptor->GetNamedProperty(isolate, name)); |
| 62 | } |
| 63 | |
| 64 | void NamedPropertySetter(v8::Local<v8::String> property, |
| 65 | v8::Local<v8::Value> value, |
| 66 | const v8::PropertyCallbackInfo<v8::Value>& 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); |
[email protected] | d656f87 | 2014-08-13 17:12:55 | [diff] [blame] | 74 | if (interceptor->SetNamedProperty(isolate, name, value)) |
| 75 | info.GetReturnValue().Set(value); |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | void NamedPropertyQuery(v8::Local<v8::String> property, |
| 79 | const v8::PropertyCallbackInfo<v8::Integer>& info) { |
| 80 | v8::Isolate* isolate = info.GetIsolate(); |
| 81 | NamedPropertyInterceptor* interceptor = |
| 82 | NamedInterceptorFromV8(isolate, info.Holder()); |
| 83 | if (!interceptor) |
| 84 | return; |
| 85 | std::string name; |
| 86 | ConvertFromV8(isolate, property, &name); |
| 87 | if (interceptor->GetNamedProperty(isolate, name).IsEmpty()) |
| 88 | return; |
| 89 | info.GetReturnValue().Set(0); |
| 90 | } |
| 91 | |
| 92 | void NamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 93 | v8::Isolate* isolate = info.GetIsolate(); |
| 94 | NamedPropertyInterceptor* interceptor = |
| 95 | NamedInterceptorFromV8(isolate, info.Holder()); |
| 96 | if (!interceptor) |
| 97 | return; |
bashi | dbd2ef9bb | 2015-06-02 01:39:32 | [diff] [blame] | 98 | v8::Local<v8::Value> properties; |
| 99 | if (!TryConvertToV8(isolate, interceptor->EnumerateNamedProperties(isolate), |
| 100 | &properties)) |
| 101 | return; |
| 102 | info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties)); |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 103 | } |
| 104 | |
| 105 | void IndexedPropertyGetter(uint32_t index, |
| 106 | const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 107 | v8::Isolate* isolate = info.GetIsolate(); |
| 108 | IndexedPropertyInterceptor* interceptor = |
| 109 | IndexedInterceptorFromV8(isolate, info.Holder()); |
| 110 | if (!interceptor) |
| 111 | return; |
| 112 | info.GetReturnValue().Set(interceptor->GetIndexedProperty(isolate, index)); |
| 113 | } |
| 114 | |
| 115 | void IndexedPropertySetter(uint32_t index, |
| 116 | v8::Local<v8::Value> value, |
| 117 | const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 118 | v8::Isolate* isolate = info.GetIsolate(); |
| 119 | IndexedPropertyInterceptor* interceptor = |
| 120 | IndexedInterceptorFromV8(isolate, info.Holder()); |
| 121 | if (!interceptor) |
| 122 | return; |
[email protected] | d656f87 | 2014-08-13 17:12:55 | [diff] [blame] | 123 | if (interceptor->SetIndexedProperty(isolate, index, value)) |
| 124 | info.GetReturnValue().Set(value); |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | void IndexedPropertyEnumerator( |
| 128 | const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 129 | v8::Isolate* isolate = info.GetIsolate(); |
| 130 | IndexedPropertyInterceptor* interceptor = |
| 131 | IndexedInterceptorFromV8(isolate, info.Holder()); |
| 132 | if (!interceptor) |
| 133 | return; |
bashi | dbd2ef9bb | 2015-06-02 01:39:32 | [diff] [blame] | 134 | v8::Local<v8::Value> properties; |
| 135 | if (!TryConvertToV8(isolate, interceptor->EnumerateIndexedProperties(isolate), |
| 136 | &properties)) |
| 137 | return; |
| 138 | info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties)); |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 139 | } |
| 140 | |
| 141 | } // namespace |
| 142 | |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 143 | ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate) |
| 144 | : isolate_(isolate), template_(v8::ObjectTemplate::New(isolate)) { |
[email protected] | cb6c2bb | 2013-12-17 21:47:04 | [diff] [blame] | 145 | template_->SetInternalFieldCount(kNumberOfInternalFields); |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 146 | } |
| 147 | |
vmpstr | 8ed6f86 | 2016-02-25 20:25:14 | [diff] [blame] | 148 | ObjectTemplateBuilder::ObjectTemplateBuilder( |
| 149 | const ObjectTemplateBuilder& other) = default; |
| 150 | |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 151 | ObjectTemplateBuilder::~ObjectTemplateBuilder() { |
| 152 | } |
| 153 | |
[email protected] | 5c969b8 | 2014-03-12 04:59:05 | [diff] [blame] | 154 | ObjectTemplateBuilder& ObjectTemplateBuilder::AddNamedPropertyInterceptor() { |
| 155 | template_->SetNamedPropertyHandler(&NamedPropertyGetter, |
| 156 | &NamedPropertySetter, |
| 157 | &NamedPropertyQuery, |
| 158 | NULL, |
| 159 | &NamedPropertyEnumerator); |
| 160 | return *this; |
| 161 | } |
| 162 | |
| 163 | ObjectTemplateBuilder& ObjectTemplateBuilder::AddIndexedPropertyInterceptor() { |
| 164 | template_->SetIndexedPropertyHandler(&IndexedPropertyGetter, |
| 165 | &IndexedPropertySetter, |
| 166 | NULL, |
| 167 | NULL, |
| 168 | &IndexedPropertyEnumerator); |
| 169 | return *this; |
| 170 | } |
| 171 | |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 172 | ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl( |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 173 | const base::StringPiece& name, v8::Local<v8::Data> val) { |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 174 | template_->Set(StringToSymbol(isolate_, name), val); |
| 175 | return *this; |
| 176 | } |
| 177 | |
[email protected] | bf3dd3c | 2013-12-06 06:55:25 | [diff] [blame] | 178 | ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl( |
deepak.s | faaa1b6 | 2015-04-30 07:30:48 | [diff] [blame] | 179 | const base::StringPiece& name, v8::Local<v8::FunctionTemplate> getter, |
| 180 | v8::Local<v8::FunctionTemplate> setter) { |
[email protected] | bf3dd3c | 2013-12-06 06:55:25 | [diff] [blame] | 181 | template_->SetAccessorProperty(StringToSymbol(isolate_, name), getter, |
| 182 | setter); |
| 183 | return *this; |
| 184 | } |
| 185 | |
[email protected] | b520e13 | 2013-11-29 03:21:48 | [diff] [blame] | 186 | v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() { |
| 187 | v8::Local<v8::ObjectTemplate> result = template_; |
| 188 | template_.Clear(); |
| 189 | return result; |
| 190 | } |
| 191 | |
| 192 | } // namespace gin |