OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project 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 "src/api-natives.h" | 5 #include "src/api-natives.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/isolate.h" | 8 #include "src/isolate.h" |
9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 return InstantiateFunction(isolate, | 30 return InstantiateFunction(isolate, |
31 Handle<FunctionTemplateInfo>::cast(data), name); | 31 Handle<FunctionTemplateInfo>::cast(data), name); |
32 } else if (data->IsObjectTemplateInfo()) { | 32 } else if (data->IsObjectTemplateInfo()) { |
33 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data)); | 33 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data)); |
34 } else { | 34 } else { |
35 return data; | 35 return data; |
36 } | 36 } |
37 } | 37 } |
38 | 38 |
39 | 39 |
40 MaybeHandle<Object> DefineAccessorProperty( | 40 MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate, |
41 Isolate* isolate, Handle<JSObject> object, Handle<Name> name, | 41 Handle<JSObject> object, |
42 Handle<Object> getter, Handle<Object> setter, Smi* attributes) { | 42 Handle<Name> name, |
43 DCHECK(PropertyDetails::AttributesField::is_valid( | 43 Handle<Object> getter, |
44 static_cast<PropertyAttributes>(attributes->value()))); | 44 Handle<Object> setter, |
| 45 PropertyAttributes attributes) { |
45 if (!getter->IsUndefined()) { | 46 if (!getter->IsUndefined()) { |
46 ASSIGN_RETURN_ON_EXCEPTION( | 47 ASSIGN_RETURN_ON_EXCEPTION( |
47 isolate, getter, | 48 isolate, getter, |
48 InstantiateFunction(isolate, | 49 InstantiateFunction(isolate, |
49 Handle<FunctionTemplateInfo>::cast(getter)), | 50 Handle<FunctionTemplateInfo>::cast(getter)), |
50 Object); | 51 Object); |
51 } | 52 } |
52 if (!setter->IsUndefined()) { | 53 if (!setter->IsUndefined()) { |
53 ASSIGN_RETURN_ON_EXCEPTION( | 54 ASSIGN_RETURN_ON_EXCEPTION( |
54 isolate, setter, | 55 isolate, setter, |
55 InstantiateFunction(isolate, | 56 InstantiateFunction(isolate, |
56 Handle<FunctionTemplateInfo>::cast(setter)), | 57 Handle<FunctionTemplateInfo>::cast(setter)), |
57 Object); | 58 Object); |
58 } | 59 } |
59 RETURN_ON_EXCEPTION(isolate, | 60 RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter, |
60 JSObject::DefineAccessor( | 61 setter, attributes), |
61 object, name, getter, setter, | |
62 static_cast<PropertyAttributes>(attributes->value())), | |
63 Object); | 62 Object); |
64 return object; | 63 return object; |
65 } | 64 } |
66 | 65 |
67 | 66 |
68 MaybeHandle<Object> DefineDataProperty(Isolate* isolate, | 67 MaybeHandle<Object> DefineDataProperty(Isolate* isolate, |
69 Handle<JSObject> object, | 68 Handle<JSObject> object, |
70 Handle<Name> name, | 69 Handle<Name> name, |
71 Handle<Object> prop_data, | 70 Handle<Object> prop_data, |
72 Smi* unchecked_attributes) { | 71 PropertyAttributes attributes) { |
73 DCHECK((unchecked_attributes->value() & | |
74 ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | |
75 // Compute attributes. | |
76 PropertyAttributes attributes = | |
77 static_cast<PropertyAttributes>(unchecked_attributes->value()); | |
78 | |
79 Handle<Object> value; | 72 Handle<Object> value; |
80 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, | 73 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, |
81 Instantiate(isolate, prop_data, name), Object); | 74 Instantiate(isolate, prop_data, name), Object); |
82 | 75 |
83 LookupIterator it = LookupIterator::PropertyOrElement( | 76 LookupIterator it = LookupIterator::PropertyOrElement( |
84 isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 77 isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
85 | 78 |
86 #ifdef DEBUG | 79 #ifdef DEBUG |
87 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 80 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
88 DCHECK(maybe.IsJust()); | 81 DCHECK(maybe.IsJust()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, | 136 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, |
144 Handle<TemplateInfo> data) { | 137 Handle<TemplateInfo> data) { |
145 auto property_list = handle(data->property_list(), isolate); | 138 auto property_list = handle(data->property_list(), isolate); |
146 if (property_list->IsUndefined()) return obj; | 139 if (property_list->IsUndefined()) return obj; |
147 // TODO(dcarney): just use a FixedArray here. | 140 // TODO(dcarney): just use a FixedArray here. |
148 NeanderArray properties(property_list); | 141 NeanderArray properties(property_list); |
149 if (properties.length() == 0) return obj; | 142 if (properties.length() == 0) return obj; |
150 HandleScope scope(isolate); | 143 HandleScope scope(isolate); |
151 // Disable access checks while instantiating the object. | 144 // Disable access checks while instantiating the object. |
152 AccessCheckDisableScope access_check_scope(isolate, obj); | 145 AccessCheckDisableScope access_check_scope(isolate, obj); |
153 for (int i = 0; i < properties.length();) { | 146 |
154 int length = Smi::cast(properties.get(i))->value(); | 147 int i = 0; |
155 if (length == 3) { | 148 for (int c = 0; c < data->number_of_properties(); c++) { |
156 auto name = handle(Name::cast(properties.get(i + 1)), isolate); | 149 auto name = handle(Name::cast(properties.get(i++)), isolate); |
157 auto prop_data = handle(properties.get(i + 2), isolate); | 150 PropertyDetails details(Smi::cast(properties.get(i++))); |
158 auto attributes = Smi::cast(properties.get(i + 3)); | 151 PropertyAttributes attributes = details.attributes(); |
| 152 PropertyKind kind = details.kind(); |
| 153 |
| 154 if (obj->map()->owns_descriptors() && |
| 155 obj->map()->instance_descriptors()->length() != 0 && |
| 156 obj->map()->instance_descriptors()->NumberOfSlackDescriptors() == 0 && |
| 157 TransitionArray::SearchTransition(obj->map(), kind, *name, |
| 158 attributes) == NULL) { |
| 159 Map::EnsureDescriptorSlack(handle(obj->map()), |
| 160 data->number_of_properties() - c); |
| 161 } |
| 162 |
| 163 if (kind == kData) { |
| 164 auto prop_data = handle(properties.get(i++), isolate); |
| 165 |
159 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 166 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
160 prop_data, attributes), | 167 prop_data, attributes), |
161 JSObject); | 168 JSObject); |
162 } else { | 169 } else { |
163 DCHECK(length == 4); | 170 auto getter = handle(properties.get(i++), isolate); |
164 auto name = handle(Name::cast(properties.get(i + 1)), isolate); | 171 auto setter = handle(properties.get(i++), isolate); |
165 auto getter = handle(properties.get(i + 2), isolate); | |
166 auto setter = handle(properties.get(i + 3), isolate); | |
167 auto attributes = Smi::cast(properties.get(i + 4)); | |
168 RETURN_ON_EXCEPTION(isolate, | 172 RETURN_ON_EXCEPTION(isolate, |
169 DefineAccessorProperty(isolate, obj, name, getter, | 173 DefineAccessorProperty(isolate, obj, name, getter, |
170 setter, attributes), | 174 setter, attributes), |
171 JSObject); | 175 JSObject); |
172 } | 176 } |
173 i += length + 1; | |
174 } | 177 } |
175 return obj; | 178 return obj; |
176 } | 179 } |
177 | 180 |
178 | 181 |
179 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, | 182 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, |
180 Handle<ObjectTemplateInfo> data) { | 183 Handle<ObjectTemplateInfo> data) { |
181 // Enter a new scope. Recursion could otherwise create a lot of handles. | 184 // Enter a new scope. Recursion could otherwise create a lot of handles. |
182 HandleScope scope(isolate); | 185 HandleScope scope(isolate); |
183 // Fast path. | 186 // Fast path. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 }; | 307 }; |
305 | 308 |
306 | 309 |
307 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, | 310 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, |
308 int length, Handle<Object>* data) { | 311 int length, Handle<Object>* data) { |
309 auto list = handle(templ->property_list(), isolate); | 312 auto list = handle(templ->property_list(), isolate); |
310 if (list->IsUndefined()) { | 313 if (list->IsUndefined()) { |
311 list = NeanderArray(isolate).value(); | 314 list = NeanderArray(isolate).value(); |
312 templ->set_property_list(*list); | 315 templ->set_property_list(*list); |
313 } | 316 } |
| 317 templ->set_number_of_properties(templ->number_of_properties() + 1); |
314 NeanderArray array(list); | 318 NeanderArray array(list); |
315 array.add(isolate, isolate->factory()->NewNumberFromInt(length)); | |
316 for (int i = 0; i < length; i++) { | 319 for (int i = 0; i < length; i++) { |
317 Handle<Object> value = | 320 Handle<Object> value = |
318 data[i].is_null() | 321 data[i].is_null() |
319 ? Handle<Object>::cast(isolate->factory()->undefined_value()) | 322 ? Handle<Object>::cast(isolate->factory()->undefined_value()) |
320 : data[i]; | 323 : data[i]; |
321 array.add(isolate, value); | 324 array.add(isolate, value); |
322 } | 325 } |
323 } | 326 } |
324 | 327 |
325 } // namespace | 328 } // namespace |
(...skipping 28 matching lines...) Expand all Loading... |
354 isolate, instance, instance_template), | 357 isolate, instance, instance_template), |
355 FunctionTemplateInfo); | 358 FunctionTemplateInfo); |
356 return desc; | 359 return desc; |
357 } | 360 } |
358 | 361 |
359 | 362 |
360 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, | 363 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, |
361 Handle<Name> name, Handle<Object> value, | 364 Handle<Name> name, Handle<Object> value, |
362 PropertyAttributes attributes) { | 365 PropertyAttributes attributes) { |
363 const int kSize = 3; | 366 const int kSize = 3; |
364 DCHECK(Smi::IsValid(static_cast<int>(attributes))); | 367 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
365 auto attribute_handle = | 368 auto details_handle = handle(details.AsSmi(), isolate); |
366 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); | 369 Handle<Object> data[kSize] = {name, details_handle, value}; |
367 Handle<Object> data[kSize] = {name, value, attribute_handle}; | |
368 AddPropertyToPropertyList(isolate, info, kSize, data); | 370 AddPropertyToPropertyList(isolate, info, kSize, data); |
369 } | 371 } |
370 | 372 |
371 | 373 |
372 void ApiNatives::AddAccessorProperty(Isolate* isolate, | 374 void ApiNatives::AddAccessorProperty(Isolate* isolate, |
373 Handle<TemplateInfo> info, | 375 Handle<TemplateInfo> info, |
374 Handle<Name> name, | 376 Handle<Name> name, |
375 Handle<FunctionTemplateInfo> getter, | 377 Handle<FunctionTemplateInfo> getter, |
376 Handle<FunctionTemplateInfo> setter, | 378 Handle<FunctionTemplateInfo> setter, |
377 PropertyAttributes attributes) { | 379 PropertyAttributes attributes) { |
378 const int kSize = 4; | 380 const int kSize = 4; |
379 DCHECK(Smi::IsValid(static_cast<int>(attributes))); | 381 PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); |
380 auto attribute_handle = | 382 auto details_handle = handle(details.AsSmi(), isolate); |
381 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); | 383 Handle<Object> data[kSize] = {name, details_handle, getter, setter}; |
382 Handle<Object> data[kSize] = {name, getter, setter, attribute_handle}; | |
383 AddPropertyToPropertyList(isolate, info, kSize, data); | 384 AddPropertyToPropertyList(isolate, info, kSize, data); |
384 } | 385 } |
385 | 386 |
386 | 387 |
387 void ApiNatives::AddNativeDataProperty(Isolate* isolate, | 388 void ApiNatives::AddNativeDataProperty(Isolate* isolate, |
388 Handle<TemplateInfo> info, | 389 Handle<TemplateInfo> info, |
389 Handle<AccessorInfo> property) { | 390 Handle<AccessorInfo> property) { |
390 auto list = handle(info->property_accessors(), isolate); | 391 auto list = handle(info->property_accessors(), isolate); |
391 if (list->IsUndefined()) { | 392 if (list->IsUndefined()) { |
392 list = NeanderArray(isolate).value(); | 393 list = NeanderArray(isolate).value(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); | 570 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); |
570 JSObject::SetAccessor(result, accessor).Assert(); | 571 JSObject::SetAccessor(result, accessor).Assert(); |
571 } | 572 } |
572 | 573 |
573 DCHECK(result->shared()->IsApiFunction()); | 574 DCHECK(result->shared()->IsApiFunction()); |
574 return result; | 575 return result; |
575 } | 576 } |
576 | 577 |
577 } // namespace internal | 578 } // namespace internal |
578 } // namespace v8 | 579 } // namespace v8 |
OLD | NEW |