Chromium Code Reviews| 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 |