| 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 |