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 |