OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/lookup.h" | 5 #include "src/lookup.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/elements.h" | 9 #include "src/elements.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 if (!isolate()->IsInternallyUsedPropertyName(name()) && | 238 if (!isolate()->IsInternallyUsedPropertyName(name()) && |
239 !receiver->map()->is_extensible()) { | 239 !receiver->map()->is_extensible()) { |
240 return; | 240 return; |
241 } | 241 } |
242 | 242 |
243 auto transition = Map::TransitionToDataProperty( | 243 auto transition = Map::TransitionToDataProperty( |
244 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); | 244 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); |
245 state_ = TRANSITION; | 245 state_ = TRANSITION; |
246 transition_ = transition; | 246 transition_ = transition; |
247 | 247 |
248 if (receiver->IsGlobalObject()) { | 248 if (receiver->IsJSGlobalObject()) { |
249 // Install a property cell. | 249 // Install a property cell. |
250 InternalizeName(); | 250 InternalizeName(); |
251 auto cell = GlobalObject::EnsurePropertyCell( | 251 auto cell = JSGlobalObject::EnsurePropertyCell( |
252 Handle<GlobalObject>::cast(receiver), name()); | 252 Handle<JSGlobalObject>::cast(receiver), name()); |
253 DCHECK(cell->value()->IsTheHole()); | 253 DCHECK(cell->value()->IsTheHole()); |
254 transition_ = cell; | 254 transition_ = cell; |
255 } else if (!transition->is_dictionary_map()) { | 255 } else if (!transition->is_dictionary_map()) { |
256 property_details_ = transition->GetLastDescriptorDetails(); | 256 property_details_ = transition->GetLastDescriptorDetails(); |
257 has_property_ = true; | 257 has_property_ = true; |
258 } | 258 } |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 void LookupIterator::ApplyTransitionToDataProperty() { | 262 void LookupIterator::ApplyTransitionToDataProperty() { |
263 DCHECK_EQ(TRANSITION, state_); | 263 DCHECK_EQ(TRANSITION, state_); |
264 | 264 |
265 Handle<JSObject> receiver = GetStoreTarget(); | 265 Handle<JSObject> receiver = GetStoreTarget(); |
266 if (receiver->IsGlobalObject()) return; | 266 if (receiver->IsJSGlobalObject()) return; |
267 holder_ = receiver; | 267 holder_ = receiver; |
268 holder_map_ = transition_map(); | 268 holder_map_ = transition_map(); |
269 JSObject::MigrateToMap(receiver, holder_map_); | 269 JSObject::MigrateToMap(receiver, holder_map_); |
270 ReloadPropertyInformation(); | 270 ReloadPropertyInformation(); |
271 } | 271 } |
272 | 272 |
273 | 273 |
274 void LookupIterator::Delete() { | 274 void LookupIterator::Delete() { |
275 Handle<JSObject> holder = Handle<JSObject>::cast(holder_); | 275 Handle<JSObject> holder = Handle<JSObject>::cast(holder_); |
276 if (IsElement()) { | 276 if (IsElement()) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 // TODO(verwaest): Optimize. | 420 // TODO(verwaest): Optimize. |
421 if (holder->IsStringObjectWithCharacterAt(index_)) { | 421 if (holder->IsStringObjectWithCharacterAt(index_)) { |
422 Handle<JSValue> js_value = Handle<JSValue>::cast(holder); | 422 Handle<JSValue> js_value = Handle<JSValue>::cast(holder); |
423 Handle<String> string(String::cast(js_value->value())); | 423 Handle<String> string(String::cast(js_value->value())); |
424 return factory()->LookupSingleCharacterStringFromCode( | 424 return factory()->LookupSingleCharacterStringFromCode( |
425 String::Flatten(string)->Get(index_)); | 425 String::Flatten(string)->Get(index_)); |
426 } | 426 } |
427 | 427 |
428 ElementsAccessor* accessor = holder->GetElementsAccessor(); | 428 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
429 return accessor->Get(handle(holder->elements()), number_); | 429 return accessor->Get(handle(holder->elements()), number_); |
430 } else if (holder_map_->IsGlobalObjectMap()) { | 430 } else if (holder_map_->IsJSGlobalObjectMap()) { |
431 result = holder->global_dictionary()->ValueAt(number_); | 431 result = holder->global_dictionary()->ValueAt(number_); |
432 DCHECK(result->IsPropertyCell()); | 432 DCHECK(result->IsPropertyCell()); |
433 result = PropertyCell::cast(result)->value(); | 433 result = PropertyCell::cast(result)->value(); |
434 } else if (holder_map_->is_dictionary_map()) { | 434 } else if (holder_map_->is_dictionary_map()) { |
435 result = holder->property_dictionary()->ValueAt(number_); | 435 result = holder->property_dictionary()->ValueAt(number_); |
436 } else if (property_details_.type() == v8::internal::DATA) { | 436 } else if (property_details_.type() == v8::internal::DATA) { |
437 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); | 437 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); |
438 return JSObject::FastPropertyAt(holder, property_details_.representation(), | 438 return JSObject::FastPropertyAt(holder, property_details_.representation(), |
439 field_index); | 439 field_index); |
440 } else { | 440 } else { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 DCHECK_EQ(v8::internal::DATA, property_details_.type()); | 479 DCHECK_EQ(v8::internal::DATA, property_details_.type()); |
480 return handle( | 480 return handle( |
481 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), | 481 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), |
482 isolate_); | 482 isolate_); |
483 } | 483 } |
484 | 484 |
485 | 485 |
486 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { | 486 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
487 DCHECK(!IsElement()); | 487 DCHECK(!IsElement()); |
488 Handle<JSObject> holder = GetHolder<JSObject>(); | 488 Handle<JSObject> holder = GetHolder<JSObject>(); |
489 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 489 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); |
490 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); | 490 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); |
491 DCHECK(value->IsPropertyCell()); | 491 DCHECK(value->IsPropertyCell()); |
492 return handle(PropertyCell::cast(value)); | 492 return handle(PropertyCell::cast(value)); |
493 } | 493 } |
494 | 494 |
495 | 495 |
496 Handle<Object> LookupIterator::GetAccessors() const { | 496 Handle<Object> LookupIterator::GetAccessors() const { |
497 DCHECK_EQ(ACCESSOR, state_); | 497 DCHECK_EQ(ACCESSOR, state_); |
498 return FetchValue(); | 498 return FetchValue(); |
499 } | 499 } |
500 | 500 |
501 | 501 |
502 Handle<Object> LookupIterator::GetDataValue() const { | 502 Handle<Object> LookupIterator::GetDataValue() const { |
503 DCHECK_EQ(DATA, state_); | 503 DCHECK_EQ(DATA, state_); |
504 Handle<Object> value = FetchValue(); | 504 Handle<Object> value = FetchValue(); |
505 return value; | 505 return value; |
506 } | 506 } |
507 | 507 |
508 | 508 |
509 void LookupIterator::WriteDataValue(Handle<Object> value) { | 509 void LookupIterator::WriteDataValue(Handle<Object> value) { |
510 DCHECK_EQ(DATA, state_); | 510 DCHECK_EQ(DATA, state_); |
511 Handle<JSObject> holder = GetHolder<JSObject>(); | 511 Handle<JSObject> holder = GetHolder<JSObject>(); |
512 if (IsElement()) { | 512 if (IsElement()) { |
513 ElementsAccessor* accessor = holder->GetElementsAccessor(); | 513 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
514 accessor->Set(holder->elements(), number_, *value); | 514 accessor->Set(holder->elements(), number_, *value); |
515 } else if (holder->IsGlobalObject()) { | 515 } else if (holder->IsJSGlobalObject()) { |
516 Handle<GlobalDictionary> property_dictionary = | 516 Handle<GlobalDictionary> property_dictionary = |
517 handle(holder->global_dictionary()); | 517 handle(holder->global_dictionary()); |
518 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, | 518 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, |
519 property_details_); | 519 property_details_); |
520 } else if (holder_map_->is_dictionary_map()) { | 520 } else if (holder_map_->is_dictionary_map()) { |
521 NameDictionary* property_dictionary = holder->property_dictionary(); | 521 NameDictionary* property_dictionary = holder->property_dictionary(); |
522 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 522 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
523 } else if (property_details_.type() == v8::internal::DATA) { | 523 } else if (property_details_.type() == v8::internal::DATA) { |
524 holder->WriteToField(descriptor_number(), *value); | 524 holder->WriteToField(descriptor_number(), *value); |
525 } else { | 525 } else { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 } | 594 } |
595 return interceptor_state_ == InterceptorState::kProcessNonMasking; | 595 return interceptor_state_ == InterceptorState::kProcessNonMasking; |
596 } | 596 } |
597 | 597 |
598 | 598 |
599 JSReceiver* LookupIterator::NextHolder(Map* map) { | 599 JSReceiver* LookupIterator::NextHolder(Map* map) { |
600 DisallowHeapAllocation no_gc; | 600 DisallowHeapAllocation no_gc; |
601 if (!map->prototype()->IsJSReceiver()) return NULL; | 601 if (!map->prototype()->IsJSReceiver()) return NULL; |
602 | 602 |
603 JSReceiver* next = JSReceiver::cast(map->prototype()); | 603 JSReceiver* next = JSReceiver::cast(map->prototype()); |
604 DCHECK(!next->map()->IsGlobalObjectMap() || | 604 DCHECK(!next->map()->IsJSGlobalObjectMap() || |
605 next->map()->is_hidden_prototype()); | 605 next->map()->is_hidden_prototype()); |
606 | 606 |
607 if (!check_prototype_chain() && | 607 if (!check_prototype_chain() && |
608 !(check_hidden() && next->map()->is_hidden_prototype()) && | 608 !(check_hidden() && next->map()->is_hidden_prototype()) && |
609 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even | 609 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even |
610 // when not checking other hidden prototypes. | 610 // when not checking other hidden prototypes. |
611 !map->IsJSGlobalProxyMap()) { | 611 !map->IsJSGlobalProxyMap()) { |
612 return NULL; | 612 return NULL; |
613 } | 613 } |
614 | 614 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 accessor->GetEntryForIndex(js_object, backing_store, index_); | 661 accessor->GetEntryForIndex(js_object, backing_store, index_); |
662 if (number_ == kMaxUInt32) return NOT_FOUND; | 662 if (number_ == kMaxUInt32) return NOT_FOUND; |
663 property_details_ = accessor->GetDetails(backing_store, number_); | 663 property_details_ = accessor->GetDetails(backing_store, number_); |
664 } | 664 } |
665 } else if (!map->is_dictionary_map()) { | 665 } else if (!map->is_dictionary_map()) { |
666 DescriptorArray* descriptors = map->instance_descriptors(); | 666 DescriptorArray* descriptors = map->instance_descriptors(); |
667 int number = descriptors->SearchWithCache(*name_, map); | 667 int number = descriptors->SearchWithCache(*name_, map); |
668 if (number == DescriptorArray::kNotFound) return NOT_FOUND; | 668 if (number == DescriptorArray::kNotFound) return NOT_FOUND; |
669 number_ = static_cast<uint32_t>(number); | 669 number_ = static_cast<uint32_t>(number); |
670 property_details_ = descriptors->GetDetails(number_); | 670 property_details_ = descriptors->GetDetails(number_); |
671 } else if (map->IsGlobalObjectMap()) { | 671 } else if (map->IsJSGlobalObjectMap()) { |
672 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); | 672 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); |
673 int number = dict->FindEntry(name_); | 673 int number = dict->FindEntry(name_); |
674 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; | 674 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; |
675 number_ = static_cast<uint32_t>(number); | 675 number_ = static_cast<uint32_t>(number); |
676 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); | 676 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); |
677 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); | 677 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); |
678 if (cell->value()->IsTheHole()) return NOT_FOUND; | 678 if (cell->value()->IsTheHole()) return NOT_FOUND; |
679 property_details_ = cell->property_details(); | 679 property_details_ = cell->property_details(); |
680 } else { | 680 } else { |
681 NameDictionary* dict = JSObject::cast(holder)->property_dictionary(); | 681 NameDictionary* dict = JSObject::cast(holder)->property_dictionary(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 // Fall through. | 715 // Fall through. |
716 default: | 716 default: |
717 return NOT_FOUND; | 717 return NOT_FOUND; |
718 } | 718 } |
719 UNREACHABLE(); | 719 UNREACHABLE(); |
720 return state_; | 720 return state_; |
721 } | 721 } |
722 | 722 |
723 } // namespace internal | 723 } // namespace internal |
724 } // namespace v8 | 724 } // namespace v8 |
OLD | NEW |