| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2618 PropertyDetails details = descriptors->GetDetails(i); | 2618 PropertyDetails details = descriptors->GetDetails(i); |
| 2619 PropertyDetails target_details = | 2619 PropertyDetails target_details = |
| 2620 current->instance_descriptors()->GetDetails(i); | 2620 current->instance_descriptors()->GetDetails(i); |
| 2621 if (details.attributes() != target_details.attributes()) return NULL; | 2621 if (details.attributes() != target_details.attributes()) return NULL; |
| 2622 if (details.type() == CALLBACKS) { | 2622 if (details.type() == CALLBACKS) { |
| 2623 if (target_details.type() != CALLBACKS) return NULL; | 2623 if (target_details.type() != CALLBACKS) return NULL; |
| 2624 if (descriptors->GetValue(i) != | 2624 if (descriptors->GetValue(i) != |
| 2625 current->instance_descriptors()->GetValue(i)) { | 2625 current->instance_descriptors()->GetValue(i)) { |
| 2626 return NULL; | 2626 return NULL; |
| 2627 } | 2627 } |
| 2628 } else if (target_details.type() == CALLBACKS) { |
| 2629 return NULL; |
| 2628 } | 2630 } |
| 2629 } | 2631 } |
| 2630 | 2632 |
| 2631 return current; | 2633 return current; |
| 2632 } | 2634 } |
| 2633 | 2635 |
| 2634 | 2636 |
| 2635 Map* Map::FindLastMatchMap(int verbatim, | 2637 Map* Map::FindLastMatchMap(int verbatim, |
| 2636 int length, | 2638 int length, |
| 2637 DescriptorArray* descriptors) { | 2639 DescriptorArray* descriptors) { |
| (...skipping 3268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5906 // - No prototype has enumerable properties/elements. | 5908 // - No prototype has enumerable properties/elements. |
| 5907 bool JSReceiver::IsSimpleEnum() { | 5909 bool JSReceiver::IsSimpleEnum() { |
| 5908 Heap* heap = GetHeap(); | 5910 Heap* heap = GetHeap(); |
| 5909 for (Object* o = this; | 5911 for (Object* o = this; |
| 5910 o != heap->null_value(); | 5912 o != heap->null_value(); |
| 5911 o = JSObject::cast(o)->GetPrototype()) { | 5913 o = JSObject::cast(o)->GetPrototype()) { |
| 5912 if (!o->IsJSObject()) return false; | 5914 if (!o->IsJSObject()) return false; |
| 5913 JSObject* curr = JSObject::cast(o); | 5915 JSObject* curr = JSObject::cast(o); |
| 5914 int enum_length = curr->map()->EnumLength(); | 5916 int enum_length = curr->map()->EnumLength(); |
| 5915 if (enum_length == kInvalidEnumCacheSentinel) return false; | 5917 if (enum_length == kInvalidEnumCacheSentinel) return false; |
| 5918 if (curr->IsAccessCheckNeeded()) return false; |
| 5916 ASSERT(!curr->HasNamedInterceptor()); | 5919 ASSERT(!curr->HasNamedInterceptor()); |
| 5917 ASSERT(!curr->HasIndexedInterceptor()); | 5920 ASSERT(!curr->HasIndexedInterceptor()); |
| 5918 ASSERT(!curr->IsAccessCheckNeeded()); | |
| 5919 if (curr->NumberOfEnumElements() > 0) return false; | 5921 if (curr->NumberOfEnumElements() > 0) return false; |
| 5920 if (curr != this && enum_length != 0) return false; | 5922 if (curr != this && enum_length != 0) return false; |
| 5921 } | 5923 } |
| 5922 return true; | 5924 return true; |
| 5923 } | 5925 } |
| 5924 | 5926 |
| 5925 | 5927 |
| 5926 static bool FilterKey(Object* key, PropertyAttributes filter) { | 5928 static bool FilterKey(Object* key, PropertyAttributes filter) { |
| 5927 if ((filter & SYMBOLIC) && key->IsSymbol()) { | 5929 if ((filter & SYMBOLIC) && key->IsSymbol()) { |
| 5928 return true; | 5930 return true; |
| (...skipping 9595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15524 if ((attr & filter) == 0) result++; | 15526 if ((attr & filter) == 0) result++; |
| 15525 } | 15527 } |
| 15526 } | 15528 } |
| 15527 return result; | 15529 return result; |
| 15528 } | 15530 } |
| 15529 | 15531 |
| 15530 | 15532 |
| 15531 template<typename Shape, typename Key> | 15533 template<typename Shape, typename Key> |
| 15532 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 15534 int Dictionary<Shape, Key>::NumberOfEnumElements() { |
| 15533 return NumberOfElementsFilterAttributes( | 15535 return NumberOfElementsFilterAttributes( |
| 15534 static_cast<PropertyAttributes>(DONT_ENUM)); | 15536 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
| 15535 } | 15537 } |
| 15536 | 15538 |
| 15537 | 15539 |
| 15538 template<typename Shape, typename Key> | 15540 template<typename Shape, typename Key> |
| 15539 void Dictionary<Shape, Key>::CopyKeysTo( | 15541 void Dictionary<Shape, Key>::CopyKeysTo( |
| 15540 FixedArray* storage, | 15542 FixedArray* storage, |
| 15541 PropertyAttributes filter, | 15543 PropertyAttributes filter, |
| 15542 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15544 typename Dictionary<Shape, Key>::SortMode sort_mode) { |
| 15543 ASSERT(storage->length() >= NumberOfEnumElements()); | 15545 ASSERT(storage->length() >= NumberOfEnumElements()); |
| 15544 int capacity = HashTable<Shape, Key>::Capacity(); | 15546 int capacity = HashTable<Shape, Key>::Capacity(); |
| 15545 int index = 0; | 15547 int index = 0; |
| 15546 for (int i = 0; i < capacity; i++) { | 15548 for (int i = 0; i < capacity; i++) { |
| 15547 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15549 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 15548 if (HashTable<Shape, Key>::IsKey(k)) { | 15550 if (HashTable<Shape, Key>::IsKey(k)) { |
| 15549 PropertyDetails details = DetailsAt(i); | 15551 PropertyDetails details = DetailsAt(i); |
| 15550 if (details.IsDeleted()) continue; | 15552 if (details.IsDeleted()) continue; |
| 15551 PropertyAttributes attr = details.attributes(); | 15553 PropertyAttributes attr = details.attributes(); |
| 15552 if ((attr & filter) == 0) storage->set(index++, k); | 15554 if ((attr & filter) == 0) storage->set(index++, k); |
| 15553 } | 15555 } |
| 15554 } | 15556 } |
| 15555 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15557 if (sort_mode == Dictionary<Shape, Key>::SORTED) { |
| 15556 storage->SortPairs(storage, index); | 15558 storage->SortPairs(storage, index); |
| 15557 } | 15559 } |
| 15558 ASSERT(storage->length() >= index); | 15560 ASSERT(storage->length() >= index); |
| 15559 } | 15561 } |
| 15560 | 15562 |
| 15561 | 15563 |
| 15562 FixedArray* NameDictionary::CopyEnumKeysTo(FixedArray* storage) { | 15564 struct EnumIndexComparator { |
| 15565 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
| 15566 bool operator() (Smi* a, Smi* b) { |
| 15567 PropertyDetails da(dict->DetailsAt(a->value())); |
| 15568 PropertyDetails db(dict->DetailsAt(b->value())); |
| 15569 return da.dictionary_index() < db.dictionary_index(); |
| 15570 } |
| 15571 NameDictionary* dict; |
| 15572 }; |
| 15573 |
| 15574 |
| 15575 void NameDictionary::CopyEnumKeysTo(FixedArray* storage) { |
| 15563 int length = storage->length(); | 15576 int length = storage->length(); |
| 15564 ASSERT(length >= NumberOfEnumElements()); | |
| 15565 Heap* heap = GetHeap(); | |
| 15566 Object* undefined_value = heap->undefined_value(); | |
| 15567 int capacity = Capacity(); | 15577 int capacity = Capacity(); |
| 15568 int properties = 0; | 15578 int properties = 0; |
| 15569 | |
| 15570 // Fill in the enumeration array by assigning enumerable keys at their | |
| 15571 // enumeration index. This will leave holes in the array if there are keys | |
| 15572 // that are deleted or not enumerable. | |
| 15573 for (int i = 0; i < capacity; i++) { | 15579 for (int i = 0; i < capacity; i++) { |
| 15574 Object* k = KeyAt(i); | 15580 Object* k = KeyAt(i); |
| 15575 if (IsKey(k) && !k->IsSymbol()) { | 15581 if (IsKey(k) && !k->IsSymbol()) { |
| 15576 PropertyDetails details = DetailsAt(i); | 15582 PropertyDetails details = DetailsAt(i); |
| 15577 if (details.IsDeleted() || details.IsDontEnum()) continue; | 15583 if (details.IsDeleted() || details.IsDontEnum()) continue; |
| 15584 storage->set(properties, Smi::FromInt(i)); |
| 15578 properties++; | 15585 properties++; |
| 15579 storage->set(details.dictionary_index() - 1, k); | |
| 15580 if (properties == length) break; | 15586 if (properties == length) break; |
| 15581 } | 15587 } |
| 15582 } | 15588 } |
| 15583 | 15589 EnumIndexComparator cmp(this); |
| 15584 // There are holes in the enumeration array if less properties were assigned | 15590 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 15585 // than the length of the array. If so, crunch all the existing properties | 15591 std::sort(start, start + length, cmp); |
| 15586 // together by shifting them to the left (maintaining the enumeration order), | 15592 for (int i = 0; i < length; i++) { |
| 15587 // and trimming of the right side of the array. | 15593 int index = Smi::cast(storage->get(i))->value(); |
| 15588 if (properties < length) { | 15594 storage->set(i, KeyAt(index)); |
| 15589 if (properties == 0) return heap->empty_fixed_array(); | |
| 15590 properties = 0; | |
| 15591 for (int i = 0; i < length; ++i) { | |
| 15592 Object* value = storage->get(i); | |
| 15593 if (value != undefined_value) { | |
| 15594 storage->set(properties, value); | |
| 15595 ++properties; | |
| 15596 } | |
| 15597 } | |
| 15598 RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties); | |
| 15599 } | 15595 } |
| 15600 return storage; | |
| 15601 } | 15596 } |
| 15602 | 15597 |
| 15603 | 15598 |
| 15604 template<typename Shape, typename Key> | 15599 template<typename Shape, typename Key> |
| 15605 void Dictionary<Shape, Key>::CopyKeysTo( | 15600 void Dictionary<Shape, Key>::CopyKeysTo( |
| 15606 FixedArray* storage, | 15601 FixedArray* storage, |
| 15607 int index, | 15602 int index, |
| 15608 PropertyAttributes filter, | 15603 PropertyAttributes filter, |
| 15609 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15604 typename Dictionary<Shape, Key>::SortMode sort_mode) { |
| 15610 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( | 15605 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16506 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16501 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16507 static const char* error_messages_[] = { | 16502 static const char* error_messages_[] = { |
| 16508 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16503 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16509 }; | 16504 }; |
| 16510 #undef ERROR_MESSAGES_TEXTS | 16505 #undef ERROR_MESSAGES_TEXTS |
| 16511 return error_messages_[reason]; | 16506 return error_messages_[reason]; |
| 16512 } | 16507 } |
| 16513 | 16508 |
| 16514 | 16509 |
| 16515 } } // namespace v8::internal | 16510 } } // namespace v8::internal |
| OLD | NEW |