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 |
147 int i = 0; | |
148 for (int c = 0; c < data->number_of_properties(); c++) { | |
154 int length = Smi::cast(properties.get(i))->value(); | 149 int length = Smi::cast(properties.get(i))->value(); |
155 if (length == 3) { | 150 PropertyKind kind = length == 3 ? kData : kAccessor; |
Igor Sheludko
2015/07/03 13:56:40
Instead of writing a length we could pack kind and
| |
156 auto name = handle(Name::cast(properties.get(i + 1)), isolate); | 151 auto name = handle(Name::cast(properties.get(i + 1)), isolate); |
157 auto prop_data = handle(properties.get(i + 2), isolate); | 152 auto unchecked_attributes = Smi::cast(properties.get(i + 2)); |
158 auto attributes = Smi::cast(properties.get(i + 3)); | 153 PropertyAttributes attributes = |
154 static_cast<PropertyAttributes>(unchecked_attributes->value()); | |
155 DCHECK(PropertyDetails::AttributesField::is_valid(attributes)); | |
156 | |
157 if (TransitionArray::SearchTransition(obj->map(), kind, *name, | |
Igor Sheludko
2015/07/03 13:56:40
Put this call after all the simple checks.
| |
158 attributes) == NULL && | |
159 obj->map()->owns_descriptors() && | |
160 obj->map()->instance_descriptors()->length() != 0 && | |
161 obj->map()->instance_descriptors()->NumberOfSlackDescriptors() == 0) { | |
162 Map::EnsureDescriptorSlack(handle(obj->map()), | |
163 data->number_of_properties() - c); | |
164 } | |
165 | |
166 if (kind == kData) { | |
167 auto prop_data = handle(properties.get(i + 3), isolate); | |
168 | |
159 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 169 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
160 prop_data, attributes), | 170 prop_data, attributes), |
161 JSObject); | 171 JSObject); |
162 } else { | 172 } else { |
163 DCHECK(length == 4); | 173 DCHECK_EQ(4, length); |
164 auto name = handle(Name::cast(properties.get(i + 1)), isolate); | 174 auto getter = handle(properties.get(i + 3), isolate); |
165 auto getter = handle(properties.get(i + 2), isolate); | 175 auto setter = handle(properties.get(i + 4), isolate); |
166 auto setter = handle(properties.get(i + 3), isolate); | |
167 auto attributes = Smi::cast(properties.get(i + 4)); | |
168 RETURN_ON_EXCEPTION(isolate, | 176 RETURN_ON_EXCEPTION(isolate, |
169 DefineAccessorProperty(isolate, obj, name, getter, | 177 DefineAccessorProperty(isolate, obj, name, getter, |
170 setter, attributes), | 178 setter, attributes), |
171 JSObject); | 179 JSObject); |
172 } | 180 } |
173 i += length + 1; | 181 i += length + 1; |
174 } | 182 } |
175 return obj; | 183 return obj; |
176 } | 184 } |
177 | 185 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 }; | 312 }; |
305 | 313 |
306 | 314 |
307 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, | 315 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, |
308 int length, Handle<Object>* data) { | 316 int length, Handle<Object>* data) { |
309 auto list = handle(templ->property_list(), isolate); | 317 auto list = handle(templ->property_list(), isolate); |
310 if (list->IsUndefined()) { | 318 if (list->IsUndefined()) { |
311 list = NeanderArray(isolate).value(); | 319 list = NeanderArray(isolate).value(); |
312 templ->set_property_list(*list); | 320 templ->set_property_list(*list); |
313 } | 321 } |
322 templ->set_number_of_properties(templ->number_of_properties() + 1); | |
314 NeanderArray array(list); | 323 NeanderArray array(list); |
315 array.add(isolate, isolate->factory()->NewNumberFromInt(length)); | 324 array.add(isolate, isolate->factory()->NewNumberFromInt(length)); |
316 for (int i = 0; i < length; i++) { | 325 for (int i = 0; i < length; i++) { |
317 Handle<Object> value = | 326 Handle<Object> value = |
318 data[i].is_null() | 327 data[i].is_null() |
319 ? Handle<Object>::cast(isolate->factory()->undefined_value()) | 328 ? Handle<Object>::cast(isolate->factory()->undefined_value()) |
320 : data[i]; | 329 : data[i]; |
321 array.add(isolate, value); | 330 array.add(isolate, value); |
322 } | 331 } |
323 } | 332 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 } | 366 } |
358 | 367 |
359 | 368 |
360 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, | 369 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, |
361 Handle<Name> name, Handle<Object> value, | 370 Handle<Name> name, Handle<Object> value, |
362 PropertyAttributes attributes) { | 371 PropertyAttributes attributes) { |
363 const int kSize = 3; | 372 const int kSize = 3; |
364 DCHECK(Smi::IsValid(static_cast<int>(attributes))); | 373 DCHECK(Smi::IsValid(static_cast<int>(attributes))); |
365 auto attribute_handle = | 374 auto attribute_handle = |
366 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); | 375 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); |
367 Handle<Object> data[kSize] = {name, value, attribute_handle}; | 376 Handle<Object> data[kSize] = {name, attribute_handle, value}; |
368 AddPropertyToPropertyList(isolate, info, kSize, data); | 377 AddPropertyToPropertyList(isolate, info, kSize, data); |
369 } | 378 } |
370 | 379 |
371 | 380 |
372 void ApiNatives::AddAccessorProperty(Isolate* isolate, | 381 void ApiNatives::AddAccessorProperty(Isolate* isolate, |
373 Handle<TemplateInfo> info, | 382 Handle<TemplateInfo> info, |
374 Handle<Name> name, | 383 Handle<Name> name, |
375 Handle<FunctionTemplateInfo> getter, | 384 Handle<FunctionTemplateInfo> getter, |
376 Handle<FunctionTemplateInfo> setter, | 385 Handle<FunctionTemplateInfo> setter, |
377 PropertyAttributes attributes) { | 386 PropertyAttributes attributes) { |
378 const int kSize = 4; | 387 const int kSize = 4; |
379 DCHECK(Smi::IsValid(static_cast<int>(attributes))); | 388 DCHECK(Smi::IsValid(static_cast<int>(attributes))); |
380 auto attribute_handle = | 389 auto attribute_handle = |
381 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); | 390 handle(Smi::FromInt(static_cast<int>(attributes)), isolate); |
382 Handle<Object> data[kSize] = {name, getter, setter, attribute_handle}; | 391 Handle<Object> data[kSize] = {name, attribute_handle, getter, setter}; |
383 AddPropertyToPropertyList(isolate, info, kSize, data); | 392 AddPropertyToPropertyList(isolate, info, kSize, data); |
384 } | 393 } |
385 | 394 |
386 | 395 |
387 void ApiNatives::AddNativeDataProperty(Isolate* isolate, | 396 void ApiNatives::AddNativeDataProperty(Isolate* isolate, |
388 Handle<TemplateInfo> info, | 397 Handle<TemplateInfo> info, |
389 Handle<AccessorInfo> property) { | 398 Handle<AccessorInfo> property) { |
390 auto list = handle(info->property_accessors(), isolate); | 399 auto list = handle(info->property_accessors(), isolate); |
391 if (list->IsUndefined()) { | 400 if (list->IsUndefined()) { |
392 list = NeanderArray(isolate).value(); | 401 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))); | 578 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); |
570 JSObject::SetAccessor(result, accessor).Assert(); | 579 JSObject::SetAccessor(result, accessor).Assert(); |
571 } | 580 } |
572 | 581 |
573 DCHECK(result->shared()->IsApiFunction()); | 582 DCHECK(result->shared()->IsApiFunction()); |
574 return result; | 583 return result; |
575 } | 584 } |
576 | 585 |
577 } // namespace internal | 586 } // namespace internal |
578 } // namespace v8 | 587 } // namespace v8 |
OLD | NEW |