| 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-inl.h" | 8 #include "src/isolate-inl.h" |
| 9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 Handle<TemplateInfoT> data, | 177 Handle<TemplateInfoT> data, |
| 178 bool is_hidden_prototype) { | 178 bool is_hidden_prototype) { |
| 179 HandleScope scope(isolate); | 179 HandleScope scope(isolate); |
| 180 // Disable access checks while instantiating the object. | 180 // Disable access checks while instantiating the object. |
| 181 AccessCheckDisableScope access_check_scope(isolate, obj); | 181 AccessCheckDisableScope access_check_scope(isolate, obj); |
| 182 | 182 |
| 183 // Walk the inheritance chain and copy all accessors to current object. | 183 // Walk the inheritance chain and copy all accessors to current object. |
| 184 int max_number_of_properties = 0; | 184 int max_number_of_properties = 0; |
| 185 TemplateInfoT* info = *data; | 185 TemplateInfoT* info = *data; |
| 186 while (info != nullptr) { | 186 while (info != nullptr) { |
| 187 if (!info->property_accessors()->IsUndefined(isolate)) { | 187 Object* props = info->property_accessors(); |
| 188 Object* props = info->property_accessors(); | 188 if (!props->IsUndefined(isolate)) { |
| 189 if (!props->IsUndefined(isolate)) { | 189 max_number_of_properties += TemplateList::cast(props)->length(); |
| 190 Handle<Object> props_handle(props, isolate); | |
| 191 NeanderArray props_array(props_handle); | |
| 192 max_number_of_properties += props_array.length(); | |
| 193 } | |
| 194 } | 190 } |
| 195 info = info->GetParent(isolate); | 191 info = info->GetParent(isolate); |
| 196 } | 192 } |
| 197 | 193 |
| 198 if (max_number_of_properties > 0) { | 194 if (max_number_of_properties > 0) { |
| 199 int valid_descriptors = 0; | 195 int valid_descriptors = 0; |
| 200 // Use a temporary FixedArray to accumulate unique accessors. | 196 // Use a temporary FixedArray to accumulate unique accessors. |
| 201 Handle<FixedArray> array = | 197 Handle<FixedArray> array = |
| 202 isolate->factory()->NewFixedArray(max_number_of_properties); | 198 isolate->factory()->NewFixedArray(max_number_of_properties); |
| 203 | 199 |
| 204 info = *data; | 200 info = *data; |
| 205 while (info != nullptr) { | 201 while (info != nullptr) { |
| 206 // Accumulate accessors. | 202 // Accumulate accessors. |
| 207 if (!info->property_accessors()->IsUndefined(isolate)) { | 203 Object* maybe_properties = info->property_accessors(); |
| 208 Handle<Object> props(info->property_accessors(), isolate); | 204 if (!maybe_properties->IsUndefined(isolate)) { |
| 209 valid_descriptors = | 205 valid_descriptors = AccessorInfo::AppendUnique( |
| 210 AccessorInfo::AppendUnique(props, array, valid_descriptors); | 206 handle(maybe_properties, isolate), array, valid_descriptors); |
| 211 } | 207 } |
| 212 info = info->GetParent(isolate); | 208 info = info->GetParent(isolate); |
| 213 } | 209 } |
| 214 | 210 |
| 215 // Install accumulated accessors. | 211 // Install accumulated accessors. |
| 216 for (int i = 0; i < valid_descriptors; i++) { | 212 for (int i = 0; i < valid_descriptors; i++) { |
| 217 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); | 213 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); |
| 218 JSObject::SetAccessor(obj, accessor).Assert(); | 214 JSObject::SetAccessor(obj, accessor).Assert(); |
| 219 } | 215 } |
| 220 } | 216 } |
| 221 | 217 |
| 222 auto property_list = handle(data->property_list(), isolate); | 218 Object* maybe_property_list = data->property_list(); |
| 223 if (property_list->IsUndefined(isolate)) return obj; | 219 if (maybe_property_list->IsUndefined(isolate)) return obj; |
| 224 // TODO(dcarney): just use a FixedArray here. | 220 Handle<TemplateList> properties(TemplateList::cast(maybe_property_list), |
| 225 NeanderArray properties(property_list); | 221 isolate); |
| 226 if (properties.length() == 0) return obj; | 222 if (properties->length() == 0) return obj; |
| 227 | 223 |
| 228 int i = 0; | 224 int i = 0; |
| 229 for (int c = 0; c < data->number_of_properties(); c++) { | 225 for (int c = 0; c < data->number_of_properties(); c++) { |
| 230 auto name = handle(Name::cast(properties.get(i++)), isolate); | 226 auto name = handle(Name::cast(properties->get(i++)), isolate); |
| 231 Object* bit = properties.get(i++); | 227 Object* bit = properties->get(i++); |
| 232 if (bit->IsSmi()) { | 228 if (bit->IsSmi()) { |
| 233 PropertyDetails details(Smi::cast(bit)); | 229 PropertyDetails details(Smi::cast(bit)); |
| 234 PropertyAttributes attributes = details.attributes(); | 230 PropertyAttributes attributes = details.attributes(); |
| 235 PropertyKind kind = details.kind(); | 231 PropertyKind kind = details.kind(); |
| 236 | 232 |
| 237 if (kind == kData) { | 233 if (kind == kData) { |
| 238 auto prop_data = handle(properties.get(i++), isolate); | 234 auto prop_data = handle(properties->get(i++), isolate); |
| 239 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 235 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
| 240 prop_data, attributes), | 236 prop_data, attributes), |
| 241 JSObject); | 237 JSObject); |
| 242 } else { | 238 } else { |
| 243 auto getter = handle(properties.get(i++), isolate); | 239 auto getter = handle(properties->get(i++), isolate); |
| 244 auto setter = handle(properties.get(i++), isolate); | 240 auto setter = handle(properties->get(i++), isolate); |
| 245 RETURN_ON_EXCEPTION( | 241 RETURN_ON_EXCEPTION( |
| 246 isolate, DefineAccessorProperty(isolate, obj, name, getter, setter, | 242 isolate, DefineAccessorProperty(isolate, obj, name, getter, setter, |
| 247 attributes, is_hidden_prototype), | 243 attributes, is_hidden_prototype), |
| 248 JSObject); | 244 JSObject); |
| 249 } | 245 } |
| 250 } else { | 246 } else { |
| 251 // Intrinsic data property --- Get appropriate value from the current | 247 // Intrinsic data property --- Get appropriate value from the current |
| 252 // context. | 248 // context. |
| 253 PropertyDetails details(Smi::cast(properties.get(i++))); | 249 PropertyDetails details(Smi::cast(properties->get(i++))); |
| 254 PropertyAttributes attributes = details.attributes(); | 250 PropertyAttributes attributes = details.attributes(); |
| 255 DCHECK_EQ(kData, details.kind()); | 251 DCHECK_EQ(kData, details.kind()); |
| 256 | 252 |
| 257 v8::Intrinsic intrinsic = | 253 v8::Intrinsic intrinsic = |
| 258 static_cast<v8::Intrinsic>(Smi::cast(properties.get(i++))->value()); | 254 static_cast<v8::Intrinsic>(Smi::cast(properties->get(i++))->value()); |
| 259 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); | 255 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); |
| 260 | 256 |
| 261 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 257 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
| 262 prop_data, attributes), | 258 prop_data, attributes), |
| 263 JSObject); | 259 JSObject); |
| 264 } | 260 } |
| 265 } | 261 } |
| 266 return obj; | 262 return obj; |
| 267 } | 263 } |
| 268 | 264 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 UncacheTemplateInstantiation(isolate, serial_number); | 462 UncacheTemplateInstantiation(isolate, serial_number); |
| 467 } | 463 } |
| 468 return MaybeHandle<JSFunction>(); | 464 return MaybeHandle<JSFunction>(); |
| 469 } | 465 } |
| 470 return function; | 466 return function; |
| 471 } | 467 } |
| 472 | 468 |
| 473 | 469 |
| 474 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, | 470 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, |
| 475 int length, Handle<Object>* data) { | 471 int length, Handle<Object>* data) { |
| 476 auto list = handle(templ->property_list(), isolate); | 472 Object* maybe_list = templ->property_list(); |
| 477 if (list->IsUndefined(isolate)) { | 473 Handle<TemplateList> list; |
| 478 list = NeanderArray(isolate).value(); | 474 if (maybe_list->IsUndefined(isolate)) { |
| 479 templ->set_property_list(*list); | 475 list = TemplateList::New(isolate, length); |
| 476 } else { |
| 477 list = handle(TemplateList::cast(maybe_list), isolate); |
| 480 } | 478 } |
| 481 templ->set_number_of_properties(templ->number_of_properties() + 1); | 479 templ->set_number_of_properties(templ->number_of_properties() + 1); |
| 482 NeanderArray array(list); | |
| 483 for (int i = 0; i < length; i++) { | 480 for (int i = 0; i < length; i++) { |
| 484 Handle<Object> value = | 481 Handle<Object> value = |
| 485 data[i].is_null() | 482 data[i].is_null() |
| 486 ? Handle<Object>::cast(isolate->factory()->undefined_value()) | 483 ? Handle<Object>::cast(isolate->factory()->undefined_value()) |
| 487 : data[i]; | 484 : data[i]; |
| 488 array.add(isolate, value); | 485 list = TemplateList::Add(isolate, list, value); |
| 489 } | 486 } |
| 487 templ->set_property_list(*list); |
| 490 } | 488 } |
| 491 | 489 |
| 492 } // namespace | 490 } // namespace |
| 493 | 491 |
| 494 | 492 |
| 495 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction( | 493 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction( |
| 496 Handle<FunctionTemplateInfo> data) { | 494 Handle<FunctionTemplateInfo> data) { |
| 497 Isolate* isolate = data->GetIsolate(); | 495 Isolate* isolate = data->GetIsolate(); |
| 498 InvokeScope invoke_scope(isolate); | 496 InvokeScope invoke_scope(isolate); |
| 499 return ::v8::internal::InstantiateFunction(isolate, data); | 497 return ::v8::internal::InstantiateFunction(isolate, data); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); | 568 PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); |
| 571 auto details_handle = handle(details.AsSmi(), isolate); | 569 auto details_handle = handle(details.AsSmi(), isolate); |
| 572 Handle<Object> data[kSize] = {name, details_handle, getter, setter}; | 570 Handle<Object> data[kSize] = {name, details_handle, getter, setter}; |
| 573 AddPropertyToPropertyList(isolate, info, kSize, data); | 571 AddPropertyToPropertyList(isolate, info, kSize, data); |
| 574 } | 572 } |
| 575 | 573 |
| 576 | 574 |
| 577 void ApiNatives::AddNativeDataProperty(Isolate* isolate, | 575 void ApiNatives::AddNativeDataProperty(Isolate* isolate, |
| 578 Handle<TemplateInfo> info, | 576 Handle<TemplateInfo> info, |
| 579 Handle<AccessorInfo> property) { | 577 Handle<AccessorInfo> property) { |
| 580 auto list = handle(info->property_accessors(), isolate); | 578 Object* maybe_list = info->property_accessors(); |
| 581 if (list->IsUndefined(isolate)) { | 579 Handle<TemplateList> list; |
| 582 list = NeanderArray(isolate).value(); | 580 if (maybe_list->IsUndefined(isolate)) { |
| 583 info->set_property_accessors(*list); | 581 list = TemplateList::New(isolate, 1); |
| 582 } else { |
| 583 list = handle(TemplateList::cast(maybe_list), isolate); |
| 584 } | 584 } |
| 585 NeanderArray array(list); | 585 list = TemplateList::Add(isolate, list, property); |
| 586 array.add(isolate, property); | 586 info->set_property_accessors(*list); |
| 587 } | 587 } |
| 588 | 588 |
| 589 | 589 |
| 590 Handle<JSFunction> ApiNatives::CreateApiFunction( | 590 Handle<JSFunction> ApiNatives::CreateApiFunction( |
| 591 Isolate* isolate, Handle<FunctionTemplateInfo> obj, | 591 Isolate* isolate, Handle<FunctionTemplateInfo> obj, |
| 592 Handle<Object> prototype, ApiInstanceType instance_type) { | 592 Handle<Object> prototype, ApiInstanceType instance_type) { |
| 593 Handle<SharedFunctionInfo> shared = | 593 Handle<SharedFunctionInfo> shared = |
| 594 FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); | 594 FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); |
| 595 Handle<JSFunction> result = | 595 Handle<JSFunction> result = |
| 596 isolate->factory()->NewFunctionFromSharedFunctionInfo( | 596 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 if (!obj->instance_call_handler()->IsUndefined(isolate)) { | 683 if (!obj->instance_call_handler()->IsUndefined(isolate)) { |
| 684 map->set_is_callable(); | 684 map->set_is_callable(); |
| 685 map->set_is_constructor(true); | 685 map->set_is_constructor(true); |
| 686 } | 686 } |
| 687 | 687 |
| 688 return result; | 688 return result; |
| 689 } | 689 } |
| 690 | 690 |
| 691 } // namespace internal | 691 } // namespace internal |
| 692 } // namespace v8 | 692 } // namespace v8 |
| OLD | NEW |