Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 HandleScope scope; | 637 HandleScope scope; |
| 638 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); | 638 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); |
| 639 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); | 639 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); |
| 640 LookupResult result; | 640 LookupResult result; |
| 641 CONVERT_CHECKED(JSObject, obj, args[0]); | 641 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 642 CONVERT_CHECKED(String, name, args[1]); | 642 CONVERT_CHECKED(String, name, args[1]); |
| 643 | 643 |
| 644 // This could be an element. | 644 // This could be an element. |
| 645 uint32_t index; | 645 uint32_t index; |
| 646 if (name->AsArrayIndex(&index)) { | 646 if (name->AsArrayIndex(&index)) { |
| 647 if (!obj->HasLocalElement(index)) { | 647 switch (obj->HasLocalElement(index)) { |
| 648 return Heap::undefined_value(); | 648 case JSObject::UNDEFINED_ELEMENT: |
| 649 } | 649 return Heap::undefined_value(); |
| 650 | 650 |
| 651 // Special handling of string objects according to ECMAScript 5 15.5.5.2. | 651 case JSObject::STRING_CHARACTER_ELEMENT: { |
| 652 // Note that this might be a string object with elements other than the | 652 // Special handling of string objects according to ECMAScript 5 |
| 653 // actual string value. This is covered by the subsequent cases. | 653 // 15.5.5.2. Note that this might be a string object with elements |
| 654 if (obj->IsStringObjectWithCharacterAt(index)) { | 654 // other than the actual string value. This is covered by the |
| 655 JSValue* js_value = JSValue::cast(obj); | 655 // subsequent cases. |
| 656 String* str = String::cast(js_value->value()); | 656 JSValue* js_value = JSValue::cast(obj); |
| 657 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 657 String* str = String::cast(js_value->value()); |
| 658 elms->set(VALUE_INDEX, str->SubString(index, index+1)); | 658 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 659 elms->set(WRITABLE_INDEX, Heap::false_value()); | 659 elms->set(VALUE_INDEX, str->SubString(index, index+1)); |
| 660 elms->set(ENUMERABLE_INDEX, Heap::false_value()); | 660 elms->set(WRITABLE_INDEX, Heap::false_value()); |
| 661 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); | 661 elms->set(ENUMERABLE_INDEX, Heap::false_value()); |
| 662 return *desc; | 662 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); |
| 663 } | 663 return *desc; |
| 664 } | |
| 664 | 665 |
| 665 // This can potentially be an element in the elements dictionary or | 666 case JSObject::INTERCEPTED_ELEMENT: |
| 666 // a fast element. | 667 case JSObject::FAST_ELEMENT: |
| 667 if (obj->HasDictionaryElements()) { | 668 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 668 NumberDictionary* dictionary = obj->element_dictionary(); | 669 elms->set(VALUE_INDEX, obj->GetElement(index)); |
| 669 int entry = dictionary->FindEntry(index); | 670 elms->set(WRITABLE_INDEX, Heap::true_value()); |
| 670 PropertyDetails details = dictionary->DetailsAt(entry); | 671 elms->set(ENUMERABLE_INDEX, Heap::true_value()); |
|
antonm
2010/09/22 13:26:38
I am not sure all intercepted elements are enumera
| |
| 671 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 672 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); |
| 672 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); | 673 return *desc; |
| 673 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); | 674 |
| 674 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); | 675 case JSObject::DICTIONARY_ELEMENT: { |
| 675 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); | 676 NumberDictionary* dictionary = obj->element_dictionary(); |
| 676 return *desc; | 677 int entry = dictionary->FindEntry(index); |
| 677 } else { | 678 ASSERT(entry != NumberDictionary::kNotFound); |
| 678 // Elements that are stored as array elements always has: | 679 PropertyDetails details = dictionary->DetailsAt(entry); |
| 679 // writable: true, configurable: true, enumerable: true. | 680 if (details.type() == CALLBACKS) { |
| 680 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 681 FixedArray* callbacks = FixedArray::cast(dictionary->ValueAt(entry)); |
| 681 elms->set(VALUE_INDEX, obj->GetElement(index)); | 682 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
| 682 elms->set(WRITABLE_INDEX, Heap::true_value()); | 683 elms->set(GETTER_INDEX, callbacks->get(0)); |
| 683 elms->set(ENUMERABLE_INDEX, Heap::true_value()); | 684 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 684 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); | 685 } else { |
|
Rico
2010/09/22 15:23:56
Add comment on why we would go in here
| |
| 685 return *desc; | 686 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 687 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); | |
| 688 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); | |
| 689 } | |
| 690 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); | |
| 691 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); | |
| 692 return *desc; | |
| 693 } | |
| 686 } | 694 } |
| 687 } | 695 } |
| 688 | 696 |
| 689 // Use recursive implementation to also traverse hidden prototypes | 697 // Use recursive implementation to also traverse hidden prototypes |
| 690 GetOwnPropertyImplementation(obj, name, &result); | 698 GetOwnPropertyImplementation(obj, name, &result); |
| 691 | 699 |
| 692 if (!result.IsProperty()) { | 700 if (!result.IsProperty()) { |
| 693 return Heap::undefined_value(); | 701 return Heap::undefined_value(); |
| 694 } | 702 } |
| 695 if (result.type() == CALLBACKS) { | 703 if (result.type() == CALLBACKS) { |
| (...skipping 9467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10163 } else { | 10171 } else { |
| 10164 // Handle last resort GC and make sure to allow future allocations | 10172 // Handle last resort GC and make sure to allow future allocations |
| 10165 // to grow the heap without causing GCs (if possible). | 10173 // to grow the heap without causing GCs (if possible). |
| 10166 Counters::gc_last_resort_from_js.Increment(); | 10174 Counters::gc_last_resort_from_js.Increment(); |
| 10167 Heap::CollectAllGarbage(false); | 10175 Heap::CollectAllGarbage(false); |
| 10168 } | 10176 } |
| 10169 } | 10177 } |
| 10170 | 10178 |
| 10171 | 10179 |
| 10172 } } // namespace v8::internal | 10180 } } // namespace v8::internal |
| OLD | NEW |