Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2693 break; | 2693 break; |
| 2694 } | 2694 } |
| 2695 case DICTIONARY_ELEMENTS: { | 2695 case DICTIONARY_ELEMENTS: { |
| 2696 NumberDictionary* dictionary = element_dictionary(); | 2696 NumberDictionary* dictionary = element_dictionary(); |
| 2697 int entry = dictionary->FindEntry(index); | 2697 int entry = dictionary->FindEntry(index); |
| 2698 if (entry != NumberDictionary::kNotFound) { | 2698 if (entry != NumberDictionary::kNotFound) { |
| 2699 return dictionary->DeleteProperty(entry, mode); | 2699 return dictionary->DeleteProperty(entry, mode); |
| 2700 } | 2700 } |
| 2701 break; | 2701 break; |
| 2702 } | 2702 } |
| 2703 default: | 2703 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 2704 UNIMPLEMENTED(); | |
|
Kevin Millikin (Chromium)
2011/03/23 16:07:20
I'm pretty sure some of these UNIMPLEMENTEDs are a
| |
| 2705 break; | |
| 2706 case EXTERNAL_BYTE_ELEMENTS: | |
| 2707 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 2708 case EXTERNAL_SHORT_ELEMENTS: | |
|
Kevin Millikin (Chromium)
2011/03/23 16:07:20
I changed all these switches over the elements kin
Mads Ager (chromium)
2011/03/24 08:04:04
Thanks. Good idea.
| |
| 2709 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 2710 case EXTERNAL_INT_ELEMENTS: | |
| 2711 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 2712 case EXTERNAL_FLOAT_ELEMENTS: | |
| 2713 case EXTERNAL_PIXEL_ELEMENTS: | |
| 2704 UNREACHABLE(); | 2714 UNREACHABLE(); |
| 2705 break; | 2715 break; |
| 2706 } | 2716 } |
| 2707 return heap->true_value(); | 2717 return heap->true_value(); |
| 2708 } | 2718 } |
| 2709 | 2719 |
| 2710 | 2720 |
| 2711 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2721 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2712 Isolate* isolate = GetIsolate(); | 2722 Isolate* isolate = GetIsolate(); |
| 2713 Heap* heap = isolate->heap(); | 2723 Heap* heap = isolate->heap(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2773 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2783 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2774 } | 2784 } |
| 2775 uint32_t length = IsJSArray() ? | 2785 uint32_t length = IsJSArray() ? |
| 2776 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2786 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2777 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2787 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2778 if (index < length) { | 2788 if (index < length) { |
| 2779 FixedArray::cast(elements())->set_the_hole(index); | 2789 FixedArray::cast(elements())->set_the_hole(index); |
| 2780 } | 2790 } |
| 2781 break; | 2791 break; |
| 2782 } | 2792 } |
| 2793 | |
| 2783 case EXTERNAL_PIXEL_ELEMENTS: | 2794 case EXTERNAL_PIXEL_ELEMENTS: |
| 2784 case EXTERNAL_BYTE_ELEMENTS: | 2795 case EXTERNAL_BYTE_ELEMENTS: |
| 2785 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2796 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2786 case EXTERNAL_SHORT_ELEMENTS: | 2797 case EXTERNAL_SHORT_ELEMENTS: |
| 2787 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2798 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2788 case EXTERNAL_INT_ELEMENTS: | 2799 case EXTERNAL_INT_ELEMENTS: |
| 2789 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2800 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2790 case EXTERNAL_FLOAT_ELEMENTS: | 2801 case EXTERNAL_FLOAT_ELEMENTS: |
| 2791 // Pixel and external array elements cannot be deleted. Just | 2802 // Pixel and external array elements cannot be deleted. Just |
| 2792 // silently ignore here. | 2803 // silently ignore here. |
| 2793 break; | 2804 break; |
| 2805 | |
| 2794 case DICTIONARY_ELEMENTS: { | 2806 case DICTIONARY_ELEMENTS: { |
| 2795 NumberDictionary* dictionary = element_dictionary(); | 2807 NumberDictionary* dictionary = element_dictionary(); |
| 2796 int entry = dictionary->FindEntry(index); | 2808 int entry = dictionary->FindEntry(index); |
| 2797 if (entry != NumberDictionary::kNotFound) { | 2809 if (entry != NumberDictionary::kNotFound) { |
| 2798 Object* result = dictionary->DeleteProperty(entry, mode); | 2810 Object* result = dictionary->DeleteProperty(entry, mode); |
| 2799 if (mode == STRICT_DELETION && result == | 2811 if (mode == STRICT_DELETION && result == |
| 2800 isolate->heap()->false_value()) { | 2812 isolate->heap()->false_value()) { |
| 2801 // In strict mode, deleting a non-configurable property throws | 2813 // In strict mode, deleting a non-configurable property throws |
| 2802 // exception. dictionary->DeleteProperty will return false_value() | 2814 // exception. dictionary->DeleteProperty will return false_value() |
| 2803 // if a non-configurable property is being deleted. | 2815 // if a non-configurable property is being deleted. |
| 2804 HandleScope scope; | 2816 HandleScope scope; |
| 2805 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); | 2817 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); |
| 2806 Handle<Object> args[2] = { i, Handle<Object>(this) }; | 2818 Handle<Object> args[2] = { i, Handle<Object>(this) }; |
| 2807 return isolate->Throw(*isolate->factory()->NewTypeError( | 2819 return isolate->Throw(*isolate->factory()->NewTypeError( |
| 2808 "strict_delete_property", HandleVector(args, 2))); | 2820 "strict_delete_property", HandleVector(args, 2))); |
| 2809 } | 2821 } |
| 2810 } | 2822 } |
| 2811 break; | 2823 break; |
| 2812 } | 2824 } |
| 2813 default: | 2825 |
| 2814 UNREACHABLE(); | 2826 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 2827 UNIMPLEMENTED(); | |
| 2815 break; | 2828 break; |
| 2816 } | 2829 } |
| 2817 return isolate->heap()->true_value(); | 2830 return isolate->heap()->true_value(); |
| 2818 } | 2831 } |
| 2819 | 2832 |
| 2820 | 2833 |
| 2821 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2834 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 2822 Isolate* isolate = GetIsolate(); | 2835 Isolate* isolate = GetIsolate(); |
| 2823 // ECMA-262, 3rd, 8.6.2.5 | 2836 // ECMA-262, 3rd, 8.6.2.5 |
| 2824 ASSERT(name->IsString()); | 2837 ASSERT(name->IsString()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2921 } | 2934 } |
| 2922 break; | 2935 break; |
| 2923 } | 2936 } |
| 2924 case DICTIONARY_ELEMENTS: { | 2937 case DICTIONARY_ELEMENTS: { |
| 2925 key = element_dictionary()->SlowReverseLookup(obj); | 2938 key = element_dictionary()->SlowReverseLookup(obj); |
| 2926 if (!key->IsUndefined()) { | 2939 if (!key->IsUndefined()) { |
| 2927 return true; | 2940 return true; |
| 2928 } | 2941 } |
| 2929 break; | 2942 break; |
| 2930 } | 2943 } |
| 2931 default: | 2944 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 2932 UNREACHABLE(); | 2945 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 2946 // Check the mapped parameters. | |
| 2947 int length = parameter_map->length(); | |
| 2948 for (int i = 2; i < length; ++i) { | |
| 2949 Object* value = parameter_map->get(i); | |
| 2950 if (!value->IsTheHole() && value == obj) return true; | |
| 2951 } | |
| 2952 // Check the arguments. | |
| 2953 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 2954 if (arguments->IsDictionary()) { | |
| 2955 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | |
| 2956 key = dictionary->SlowReverseLookup(obj); | |
| 2957 if (key != heap->undefined_value()) return true; | |
| 2958 } else { | |
| 2959 int count = arguments->length(); | |
| 2960 for (int i = 0; i < count; ++i) { | |
| 2961 Object* value = arguments->get(i); | |
| 2962 if (!value->IsTheHole() && value == obj) return true; | |
| 2963 } | |
| 2964 } | |
| 2933 break; | 2965 break; |
| 2966 } | |
| 2934 } | 2967 } |
| 2935 | 2968 |
| 2936 // For functions check the context. | 2969 // For functions check the context. |
| 2937 if (IsJSFunction()) { | 2970 if (IsJSFunction()) { |
| 2938 // Get the constructor function for arguments array. | 2971 // Get the constructor function for arguments array. |
| 2939 JSObject* arguments_boilerplate = | 2972 JSObject* arguments_boilerplate = |
| 2940 heap->isolate()->context()->global_context()-> | 2973 heap->isolate()->context()->global_context()-> |
| 2941 arguments_boilerplate(); | 2974 arguments_boilerplate(); |
| 2942 JSFunction* arguments_function = | 2975 JSFunction* arguments_function = |
| 2943 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 2976 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3190 if (details.IsReadOnly()) return heap->undefined_value(); | 3223 if (details.IsReadOnly()) return heap->undefined_value(); |
| 3191 if (details.type() == CALLBACKS) { | 3224 if (details.type() == CALLBACKS) { |
| 3192 if (result->IsFixedArray()) { | 3225 if (result->IsFixedArray()) { |
| 3193 return result; | 3226 return result; |
| 3194 } | 3227 } |
| 3195 // Otherwise allow to override it. | 3228 // Otherwise allow to override it. |
| 3196 } | 3229 } |
| 3197 } | 3230 } |
| 3198 break; | 3231 break; |
| 3199 } | 3232 } |
| 3200 default: | 3233 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 3201 UNREACHABLE(); | 3234 UNIMPLEMENTED(); |
| 3202 break; | 3235 break; |
| 3203 } | 3236 } |
| 3204 } else { | 3237 } else { |
| 3205 // Lookup the name. | 3238 // Lookup the name. |
| 3206 LookupResult result; | 3239 LookupResult result; |
| 3207 LocalLookup(name, &result); | 3240 LocalLookup(name, &result); |
| 3208 if (result.IsProperty()) { | 3241 if (result.IsProperty()) { |
| 3209 if (result.IsReadOnly()) return heap->undefined_value(); | 3242 if (result.IsReadOnly()) return heap->undefined_value(); |
| 3210 if (result.type() == CALLBACKS) { | 3243 if (result.type() == CALLBACKS) { |
| 3211 Object* obj = result.GetCallbackObject(); | 3244 Object* obj = result.GetCallbackObject(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3401 case EXTERNAL_SHORT_ELEMENTS: | 3434 case EXTERNAL_SHORT_ELEMENTS: |
| 3402 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3435 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3403 case EXTERNAL_INT_ELEMENTS: | 3436 case EXTERNAL_INT_ELEMENTS: |
| 3404 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3437 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3405 case EXTERNAL_FLOAT_ELEMENTS: | 3438 case EXTERNAL_FLOAT_ELEMENTS: |
| 3406 // Ignore getters and setters on pixel and external array | 3439 // Ignore getters and setters on pixel and external array |
| 3407 // elements. | 3440 // elements. |
| 3408 return isolate->heap()->undefined_value(); | 3441 return isolate->heap()->undefined_value(); |
| 3409 case DICTIONARY_ELEMENTS: | 3442 case DICTIONARY_ELEMENTS: |
| 3410 break; | 3443 break; |
| 3411 default: | 3444 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 3412 UNREACHABLE(); | 3445 UNIMPLEMENTED(); |
| 3413 break; | 3446 break; |
| 3414 } | 3447 } |
| 3415 | 3448 |
| 3416 Object* ok; | 3449 Object* ok; |
| 3417 { MaybeObject* maybe_ok = | 3450 { MaybeObject* maybe_ok = |
| 3418 SetElementCallback(index, info, info->property_attributes()); | 3451 SetElementCallback(index, info, info->property_attributes()); |
| 3419 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3452 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3420 } | 3453 } |
| 3421 } else { | 3454 } else { |
| 3422 // Lookup the name. | 3455 // Lookup the name. |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4004 int pos = 0; | 4037 int pos = 0; |
| 4005 // Copy the elements from the JSArray to the temporary fixed array. | 4038 // Copy the elements from the JSArray to the temporary fixed array. |
| 4006 for (int i = 0; i < capacity; i++) { | 4039 for (int i = 0; i < capacity; i++) { |
| 4007 if (dict->IsKey(dict->KeyAt(i))) { | 4040 if (dict->IsKey(dict->KeyAt(i))) { |
| 4008 key_array->set(pos++, dict->ValueAt(i)); | 4041 key_array->set(pos++, dict->ValueAt(i)); |
| 4009 } | 4042 } |
| 4010 } | 4043 } |
| 4011 // Compute the union of this and the temporary fixed array. | 4044 // Compute the union of this and the temporary fixed array. |
| 4012 return UnionOfKeys(key_array); | 4045 return UnionOfKeys(key_array); |
| 4013 } | 4046 } |
| 4014 default: | 4047 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: |
| 4015 UNREACHABLE(); | 4048 UNIMPLEMENTED(); |
| 4049 break; | |
| 4050 case JSObject::EXTERNAL_BYTE_ELEMENTS: | |
| 4051 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 4052 case JSObject::EXTERNAL_SHORT_ELEMENTS: | |
| 4053 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 4054 case JSObject::EXTERNAL_INT_ELEMENTS: | |
| 4055 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 4056 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | |
| 4057 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | |
| 4058 break; | |
| 4016 } | 4059 } |
| 4017 UNREACHABLE(); | 4060 UNREACHABLE(); |
| 4018 return heap->null_value(); // Failure case needs to "return" a value. | 4061 return heap->null_value(); // Failure case needs to "return" a value. |
| 4019 } | 4062 } |
| 4020 | 4063 |
| 4021 | 4064 |
| 4022 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 4065 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 4023 Heap* heap = GetHeap(); | 4066 Heap* heap = GetHeap(); |
| 4024 int len0 = length(); | 4067 int len0 = length(); |
| 4025 #ifdef DEBUG | 4068 #ifdef DEBUG |
| (...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6629 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 6672 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
| 6630 for (int i = 0; i < dictionary->Capacity(); i++) { | 6673 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 6631 Object* key = dictionary->KeyAt(i); | 6674 Object* key = dictionary->KeyAt(i); |
| 6632 if (key->IsNumber()) { | 6675 if (key->IsNumber()) { |
| 6633 uint32_t entry = static_cast<uint32_t>(key->Number()); | 6676 uint32_t entry = static_cast<uint32_t>(key->Number()); |
| 6634 elems->set(entry, dictionary->ValueAt(i), mode); | 6677 elems->set(entry, dictionary->ValueAt(i), mode); |
| 6635 } | 6678 } |
| 6636 } | 6679 } |
| 6637 break; | 6680 break; |
| 6638 } | 6681 } |
| 6639 default: | 6682 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 6683 UNIMPLEMENTED(); | |
| 6684 break; | |
| 6685 case EXTERNAL_BYTE_ELEMENTS: | |
| 6686 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 6687 case EXTERNAL_SHORT_ELEMENTS: | |
| 6688 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 6689 case EXTERNAL_INT_ELEMENTS: | |
| 6690 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 6691 case EXTERNAL_FLOAT_ELEMENTS: | |
| 6692 case EXTERNAL_PIXEL_ELEMENTS: | |
| 6640 UNREACHABLE(); | 6693 UNREACHABLE(); |
| 6641 break; | 6694 break; |
| 6642 } | 6695 } |
| 6643 | 6696 |
| 6644 set_map(new_map); | 6697 set_map(new_map); |
| 6645 set_elements(elems); | 6698 set_elements(elems); |
| 6646 | 6699 |
| 6647 if (IsJSArray()) { | 6700 if (IsJSArray()) { |
| 6648 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 6701 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| 6649 } | 6702 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 6674 } | 6727 } |
| 6675 case DICTIONARY_ELEMENTS: { | 6728 case DICTIONARY_ELEMENTS: { |
| 6676 if (IsJSArray()) { | 6729 if (IsJSArray()) { |
| 6677 uint32_t old_length = | 6730 uint32_t old_length = |
| 6678 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 6731 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
| 6679 element_dictionary()->RemoveNumberEntries(new_length, old_length), | 6732 element_dictionary()->RemoveNumberEntries(new_length, old_length), |
| 6680 JSArray::cast(this)->set_length(len); | 6733 JSArray::cast(this)->set_length(len); |
| 6681 } | 6734 } |
| 6682 break; | 6735 break; |
| 6683 } | 6736 } |
| 6684 default: | 6737 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 6738 UNIMPLEMENTED(); | |
| 6739 break; | |
| 6740 case EXTERNAL_BYTE_ELEMENTS: | |
| 6741 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 6742 case EXTERNAL_SHORT_ELEMENTS: | |
| 6743 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 6744 case EXTERNAL_INT_ELEMENTS: | |
| 6745 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 6746 case EXTERNAL_FLOAT_ELEMENTS: | |
| 6747 case EXTERNAL_PIXEL_ELEMENTS: | |
| 6685 UNREACHABLE(); | 6748 UNREACHABLE(); |
| 6686 break; | 6749 break; |
| 6687 } | 6750 } |
| 6688 return this; | 6751 return this; |
| 6689 } | 6752 } |
| 6690 | 6753 |
| 6691 | 6754 |
| 6692 MaybeObject* JSArray::Initialize(int capacity) { | 6755 MaybeObject* JSArray::Initialize(int capacity) { |
| 6693 Heap* heap = GetHeap(); | 6756 Heap* heap = GetHeap(); |
| 6694 ASSERT(capacity >= 0); | 6757 ASSERT(capacity >= 0); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6784 } else { | 6847 } else { |
| 6785 // Remove deleted elements. | 6848 // Remove deleted elements. |
| 6786 uint32_t old_length = | 6849 uint32_t old_length = |
| 6787 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 6850 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
| 6788 element_dictionary()->RemoveNumberEntries(value, old_length); | 6851 element_dictionary()->RemoveNumberEntries(value, old_length); |
| 6789 } | 6852 } |
| 6790 JSArray::cast(this)->set_length(Smi::cast(smi_length)); | 6853 JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
| 6791 } | 6854 } |
| 6792 return this; | 6855 return this; |
| 6793 } | 6856 } |
| 6794 default: | 6857 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 6858 UNIMPLEMENTED(); | |
| 6859 break; | |
| 6860 case EXTERNAL_BYTE_ELEMENTS: | |
| 6861 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 6862 case EXTERNAL_SHORT_ELEMENTS: | |
| 6863 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 6864 case EXTERNAL_INT_ELEMENTS: | |
| 6865 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 6866 case EXTERNAL_FLOAT_ELEMENTS: | |
| 6867 case EXTERNAL_PIXEL_ELEMENTS: | |
| 6795 UNREACHABLE(); | 6868 UNREACHABLE(); |
| 6796 break; | 6869 break; |
| 6797 } | 6870 } |
| 6798 } | 6871 } |
| 6799 | 6872 |
| 6800 // General slow case. | 6873 // General slow case. |
| 6801 if (len->IsNumber()) { | 6874 if (len->IsNumber()) { |
| 6802 uint32_t length; | 6875 uint32_t length; |
| 6803 if (len->ToArrayIndex(&length)) { | 6876 if (len->ToArrayIndex(&length)) { |
| 6804 return SetSlowElements(len); | 6877 return SetSlowElements(len); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6900 } | 6973 } |
| 6901 break; | 6974 break; |
| 6902 } | 6975 } |
| 6903 case DICTIONARY_ELEMENTS: { | 6976 case DICTIONARY_ELEMENTS: { |
| 6904 if (element_dictionary()->FindEntry(index) | 6977 if (element_dictionary()->FindEntry(index) |
| 6905 != NumberDictionary::kNotFound) { | 6978 != NumberDictionary::kNotFound) { |
| 6906 return true; | 6979 return true; |
| 6907 } | 6980 } |
| 6908 break; | 6981 break; |
| 6909 } | 6982 } |
| 6910 default: | 6983 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 6911 UNREACHABLE(); | 6984 UNIMPLEMENTED(); |
| 6912 break; | 6985 break; |
| 6913 } | 6986 } |
| 6914 | 6987 |
| 6915 // Handle [] on String objects. | 6988 // Handle [] on String objects. |
| 6916 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6989 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 6917 | 6990 |
| 6918 Object* pt = GetPrototype(); | 6991 Object* pt = GetPrototype(); |
| 6919 if (pt->IsNull()) return false; | 6992 if (pt->IsNull()) return false; |
| 6920 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6993 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 6921 } | 6994 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7020 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; | 7093 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; |
| 7021 break; | 7094 break; |
| 7022 } | 7095 } |
| 7023 case DICTIONARY_ELEMENTS: { | 7096 case DICTIONARY_ELEMENTS: { |
| 7024 if (element_dictionary()->FindEntry(index) != | 7097 if (element_dictionary()->FindEntry(index) != |
| 7025 NumberDictionary::kNotFound) { | 7098 NumberDictionary::kNotFound) { |
| 7026 return DICTIONARY_ELEMENT; | 7099 return DICTIONARY_ELEMENT; |
| 7027 } | 7100 } |
| 7028 break; | 7101 break; |
| 7029 } | 7102 } |
| 7030 default: | 7103 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 7031 UNREACHABLE(); | 7104 UNIMPLEMENTED(); |
| 7032 break; | 7105 break; |
| 7033 } | 7106 } |
| 7034 | 7107 |
| 7035 return UNDEFINED_ELEMENT; | 7108 return UNDEFINED_ELEMENT; |
| 7036 } | 7109 } |
| 7037 | 7110 |
| 7038 | 7111 |
| 7039 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 7112 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 7040 Heap* heap = GetHeap(); | 7113 Heap* heap = GetHeap(); |
| 7041 | 7114 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7081 } | 7154 } |
| 7082 break; | 7155 break; |
| 7083 } | 7156 } |
| 7084 case DICTIONARY_ELEMENTS: { | 7157 case DICTIONARY_ELEMENTS: { |
| 7085 if (element_dictionary()->FindEntry(index) | 7158 if (element_dictionary()->FindEntry(index) |
| 7086 != NumberDictionary::kNotFound) { | 7159 != NumberDictionary::kNotFound) { |
| 7087 return true; | 7160 return true; |
| 7088 } | 7161 } |
| 7089 break; | 7162 break; |
| 7090 } | 7163 } |
| 7091 default: | 7164 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 7092 UNREACHABLE(); | 7165 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 7166 uint32_t length = parameter_map->length(); | |
| 7167 Object* probe = | |
| 7168 (index + 2 < length) ? parameter_map->get(index + 2) : NULL; | |
| 7169 if (probe != NULL && !probe->IsTheHole()) return true; | |
| 7170 | |
| 7171 // Not a mapped parameter, check the arguments. | |
| 7172 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 7173 if (arguments->IsDictionary()) { | |
| 7174 if (NumberDictionary::cast(arguments)->FindEntry(index) != | |
| 7175 NumberDictionary::kNotFound) { | |
| 7176 return true; | |
| 7177 } | |
| 7178 } else if (index < static_cast<uint32_t>(arguments->length()) && | |
| 7179 !arguments->get(index)->IsTheHole()) { | |
| 7180 return true; | |
| 7181 } | |
| 7093 break; | 7182 break; |
| 7183 } | |
| 7094 } | 7184 } |
| 7095 | 7185 |
| 7096 // Handle [] on String objects. | 7186 // Handle [] on String objects. |
| 7097 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7187 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 7098 | 7188 |
| 7099 Object* pt = GetPrototype(); | 7189 Object* pt = GetPrototype(); |
| 7100 if (pt->IsNull()) return false; | 7190 if (pt->IsNull()) return false; |
| 7101 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 7191 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 7102 } | 7192 } |
| 7103 | 7193 |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7472 SetFastElementsCapacityAndLength(new_length, new_length); | 7562 SetFastElementsCapacityAndLength(new_length, new_length); |
| 7473 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7563 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7474 } | 7564 } |
| 7475 #ifdef DEBUG | 7565 #ifdef DEBUG |
| 7476 if (FLAG_trace_normalization) { | 7566 if (FLAG_trace_normalization) { |
| 7477 PrintF("Object elements are fast case again:\n"); | 7567 PrintF("Object elements are fast case again:\n"); |
| 7478 Print(); | 7568 Print(); |
| 7479 } | 7569 } |
| 7480 #endif | 7570 #endif |
| 7481 } | 7571 } |
| 7482 | |
| 7483 return value; | 7572 return value; |
| 7484 } | 7573 } |
| 7485 default: | 7574 |
| 7486 UNREACHABLE(); | 7575 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 7576 FixedArray* parameter_map = FixedArray::cast(elements()); | |
| 7577 uint32_t length = parameter_map->length(); | |
| 7578 Object* probe = | |
| 7579 (index + 2 < length) ? parameter_map->get(index + 2) : NULL; | |
| 7580 if (probe != NULL && !probe->IsTheHole()) { | |
| 7581 Context* context = Context::cast(parameter_map->get(0)); | |
| 7582 int context_index = Smi::cast(probe)->value(); | |
| 7583 ASSERT(!context->get(context_index)->IsTheHole()); | |
| 7584 context->set(context_index, value); | |
| 7585 return value; | |
| 7586 } else { | |
| 7587 // Object is not mapped, defer to the arguments. | |
| 7588 UNIMPLEMENTED(); | |
|
Kevin Millikin (Chromium)
2011/03/23 16:07:20
This is the point where I really want to use the e
| |
| 7589 } | |
| 7487 break; | 7590 break; |
| 7591 } | |
| 7488 } | 7592 } |
| 7489 // All possible cases have been handled above. Add a return to avoid the | 7593 // All possible cases have been handled above. Add a return to avoid the |
| 7490 // complaints from the compiler. | 7594 // complaints from the compiler. |
| 7491 UNREACHABLE(); | 7595 UNREACHABLE(); |
| 7492 return isolate->heap()->null_value(); | 7596 return isolate->heap()->null_value(); |
| 7493 } | 7597 } |
| 7494 | 7598 |
| 7495 | 7599 |
| 7496 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 7600 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
| 7497 Object* value) { | 7601 Object* value) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7548 if (details.type() == CALLBACKS) { | 7652 if (details.type() == CALLBACKS) { |
| 7549 return GetElementWithCallback(receiver, | 7653 return GetElementWithCallback(receiver, |
| 7550 element, | 7654 element, |
| 7551 index, | 7655 index, |
| 7552 this); | 7656 this); |
| 7553 } | 7657 } |
| 7554 return element; | 7658 return element; |
| 7555 } | 7659 } |
| 7556 break; | 7660 break; |
| 7557 } | 7661 } |
| 7558 default: | 7662 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 7559 UNREACHABLE(); | 7663 UNIMPLEMENTED(); |
| 7560 break; | 7664 break; |
| 7561 } | 7665 } |
| 7562 | 7666 |
| 7563 // Continue searching via the prototype chain. | 7667 // Continue searching via the prototype chain. |
| 7564 Object* pt = GetPrototype(); | 7668 Object* pt = GetPrototype(); |
| 7565 if (pt->IsNull()) return heap->undefined_value(); | 7669 if (pt->IsNull()) return heap->undefined_value(); |
| 7566 return pt->GetElementWithReceiver(receiver, index); | 7670 return pt->GetElementWithReceiver(receiver, index); |
| 7567 } | 7671 } |
| 7568 | 7672 |
| 7569 | 7673 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7650 if (details.type() == CALLBACKS) { | 7754 if (details.type() == CALLBACKS) { |
| 7651 return GetElementWithCallback(receiver, | 7755 return GetElementWithCallback(receiver, |
| 7652 element, | 7756 element, |
| 7653 index, | 7757 index, |
| 7654 this); | 7758 this); |
| 7655 } | 7759 } |
| 7656 return element; | 7760 return element; |
| 7657 } | 7761 } |
| 7658 break; | 7762 break; |
| 7659 } | 7763 } |
| 7764 case NON_STRICT_ARGUMENTS_ELEMENTS: { | |
| 7765 FixedArray* parameter_map = FixedArray::cast(elements()); | |
| 7766 uint32_t length = parameter_map->length(); | |
| 7767 Object* probe = | |
| 7768 (index + 2 < length) ? parameter_map->get(index + 2) : NULL; | |
| 7769 if (probe != NULL && !probe->IsTheHole()) { | |
| 7770 Context* context = Context::cast(parameter_map->get(0)); | |
| 7771 int context_index = Smi::cast(probe)->value(); | |
| 7772 ASSERT(!context->get(context_index)->IsTheHole()); | |
| 7773 return context->get(context_index); | |
| 7774 } else { | |
| 7775 // Object is not mapped, defer to the arguments. | |
| 7776 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 7777 if (arguments->IsDictionary()) { | |
| 7778 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | |
| 7779 int entry = dictionary->FindEntry(index); | |
| 7780 if (entry != NumberDictionary::kNotFound) { | |
| 7781 Object* element = dictionary->ValueAt(entry); | |
| 7782 PropertyDetails details = dictionary->DetailsAt(entry); | |
| 7783 if (details.type() != CALLBACKS) return element; | |
| 7784 UNIMPLEMENTED(); // CALLBACKS not yet implemented. | |
| 7785 } | |
| 7786 } else if (index < static_cast<uint32_t>(arguments->length())) { | |
| 7787 Object* value = arguments->get(index); | |
| 7788 if (!value->IsTheHole()) return value; | |
| 7789 } | |
| 7790 } | |
| 7791 break; | |
| 7792 } | |
| 7660 } | 7793 } |
| 7661 | 7794 |
| 7662 Object* pt = GetPrototype(); | 7795 Object* pt = GetPrototype(); |
| 7663 if (pt == heap->null_value()) return heap->undefined_value(); | 7796 if (pt == heap->null_value()) return heap->undefined_value(); |
| 7664 return pt->GetElementWithReceiver(receiver, index); | 7797 return pt->GetElementWithReceiver(receiver, index); |
| 7665 } | 7798 } |
| 7666 | 7799 |
| 7667 | 7800 |
| 7668 MaybeObject* JSObject::GetExternalElement(uint32_t index) { | 7801 MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
| 7669 // Get element works for both JSObject and JSArray since | 7802 // Get element works for both JSObject and JSArray since |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7733 if (index < static_cast<uint32_t>(array->length())) { | 7866 if (index < static_cast<uint32_t>(array->length())) { |
| 7734 float value = array->get(index); | 7867 float value = array->get(index); |
| 7735 return GetHeap()->AllocateHeapNumber(value); | 7868 return GetHeap()->AllocateHeapNumber(value); |
| 7736 } | 7869 } |
| 7737 break; | 7870 break; |
| 7738 } | 7871 } |
| 7739 case FAST_ELEMENTS: | 7872 case FAST_ELEMENTS: |
| 7740 case DICTIONARY_ELEMENTS: | 7873 case DICTIONARY_ELEMENTS: |
| 7741 UNREACHABLE(); | 7874 UNREACHABLE(); |
| 7742 break; | 7875 break; |
| 7876 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 7877 UNIMPLEMENTED(); | |
| 7878 break; | |
| 7743 } | 7879 } |
| 7744 return GetHeap()->undefined_value(); | 7880 return GetHeap()->undefined_value(); |
| 7745 } | 7881 } |
| 7746 | 7882 |
| 7747 | 7883 |
| 7748 bool JSObject::HasDenseElements() { | 7884 bool JSObject::HasDenseElements() { |
| 7749 int capacity = 0; | 7885 int capacity = 0; |
| 7750 int number_of_elements = 0; | 7886 int number_of_elements = 0; |
| 7751 | 7887 |
| 7752 switch (GetElementsKind()) { | 7888 switch (GetElementsKind()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 7767 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7903 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7768 case EXTERNAL_FLOAT_ELEMENTS: { | 7904 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7769 return true; | 7905 return true; |
| 7770 } | 7906 } |
| 7771 case DICTIONARY_ELEMENTS: { | 7907 case DICTIONARY_ELEMENTS: { |
| 7772 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 7908 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
| 7773 capacity = dictionary->Capacity(); | 7909 capacity = dictionary->Capacity(); |
| 7774 number_of_elements = dictionary->NumberOfElements(); | 7910 number_of_elements = dictionary->NumberOfElements(); |
| 7775 break; | 7911 break; |
| 7776 } | 7912 } |
| 7777 default: | 7913 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 7778 UNREACHABLE(); | 7914 UNIMPLEMENTED(); |
| 7779 break; | 7915 break; |
| 7780 } | 7916 } |
| 7781 | 7917 |
| 7782 if (capacity == 0) return true; | 7918 if (capacity == 0) return true; |
| 7783 return (number_of_elements > (capacity / 2)); | 7919 return (number_of_elements > (capacity / 2)); |
| 7784 } | 7920 } |
| 7785 | 7921 |
| 7786 | 7922 |
| 7787 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { | 7923 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { |
| 7788 ASSERT(HasFastElements()); | 7924 ASSERT(HasFastElements()); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8003 case EXTERNAL_INT_ELEMENTS: | 8139 case EXTERNAL_INT_ELEMENTS: |
| 8004 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8140 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 8005 case EXTERNAL_FLOAT_ELEMENTS: { | 8141 case EXTERNAL_FLOAT_ELEMENTS: { |
| 8006 ExternalArray* array = ExternalArray::cast(elements()); | 8142 ExternalArray* array = ExternalArray::cast(elements()); |
| 8007 return index < static_cast<uint32_t>(array->length()); | 8143 return index < static_cast<uint32_t>(array->length()); |
| 8008 } | 8144 } |
| 8009 case DICTIONARY_ELEMENTS: { | 8145 case DICTIONARY_ELEMENTS: { |
| 8010 return element_dictionary()->FindEntry(index) | 8146 return element_dictionary()->FindEntry(index) |
| 8011 != NumberDictionary::kNotFound; | 8147 != NumberDictionary::kNotFound; |
| 8012 } | 8148 } |
| 8013 default: | 8149 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 8014 UNREACHABLE(); | 8150 UNIMPLEMENTED(); |
| 8015 break; | 8151 break; |
| 8016 } | 8152 } |
| 8017 // All possibilities have been handled above already. | 8153 // All possibilities have been handled above already. |
| 8018 UNREACHABLE(); | 8154 UNREACHABLE(); |
| 8019 return heap->null_value(); | 8155 return heap->null_value(); |
| 8020 } | 8156 } |
| 8021 | 8157 |
| 8022 | 8158 |
| 8023 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 8159 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 8024 Heap* heap = GetHeap(); | 8160 Heap* heap = GetHeap(); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8250 } | 8386 } |
| 8251 counter++; | 8387 counter++; |
| 8252 } | 8388 } |
| 8253 ASSERT(!storage || storage->length() >= counter); | 8389 ASSERT(!storage || storage->length() >= counter); |
| 8254 break; | 8390 break; |
| 8255 } | 8391 } |
| 8256 case DICTIONARY_ELEMENTS: { | 8392 case DICTIONARY_ELEMENTS: { |
| 8257 if (storage != NULL) { | 8393 if (storage != NULL) { |
| 8258 element_dictionary()->CopyKeysTo(storage, filter); | 8394 element_dictionary()->CopyKeysTo(storage, filter); |
| 8259 } | 8395 } |
| 8260 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter); | 8396 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 8261 break; | 8397 break; |
| 8262 } | 8398 } |
| 8263 default: | 8399 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8264 UNREACHABLE(); | 8400 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 8401 int length = parameter_map->length(); | |
| 8402 for (int i = 2; i < length; ++i) { | |
| 8403 if (!parameter_map->get(i)->IsTheHole()) { | |
| 8404 if (storage != NULL) storage->set(i - 2, Smi::FromInt(i - 2)); | |
| 8405 ++counter; | |
| 8406 } | |
| 8407 } | |
| 8408 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 8409 if (arguments->IsDictionary()) { | |
| 8410 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | |
| 8411 if (storage != NULL) dictionary->CopyKeysTo(storage, filter); | |
| 8412 counter += dictionary->NumberOfElementsFilterAttributes(filter); | |
| 8413 } else { | |
| 8414 int length = arguments->length(); | |
| 8415 for (int i = 0; i < length; ++i) { | |
| 8416 if (!arguments->get(i)->IsTheHole()) { | |
| 8417 if (storage != NULL) storage->set(i, Smi::FromInt(i)); | |
| 8418 ++counter; | |
| 8419 } | |
| 8420 } | |
| 8421 } | |
| 8265 break; | 8422 break; |
| 8423 } | |
| 8266 } | 8424 } |
| 8267 | 8425 |
| 8268 if (this->IsJSValue()) { | 8426 if (this->IsJSValue()) { |
| 8269 Object* val = JSValue::cast(this)->value(); | 8427 Object* val = JSValue::cast(this)->value(); |
| 8270 if (val->IsString()) { | 8428 if (val->IsString()) { |
| 8271 String* str = String::cast(val); | 8429 String* str = String::cast(val); |
| 8272 if (storage) { | 8430 if (storage) { |
| 8273 for (int i = 0; i < str->length(); i++) { | 8431 for (int i = 0; i < str->length(); i++) { |
| 8274 storage->set(counter + i, Smi::FromInt(i)); | 8432 storage->set(counter + i, Smi::FromInt(i)); |
| 8275 } | 8433 } |
| (...skipping 1969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10245 if (break_point_objects()->IsUndefined()) return 0; | 10403 if (break_point_objects()->IsUndefined()) return 0; |
| 10246 // Single beak point. | 10404 // Single beak point. |
| 10247 if (!break_point_objects()->IsFixedArray()) return 1; | 10405 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10248 // Multiple break points. | 10406 // Multiple break points. |
| 10249 return FixedArray::cast(break_point_objects())->length(); | 10407 return FixedArray::cast(break_point_objects())->length(); |
| 10250 } | 10408 } |
| 10251 #endif | 10409 #endif |
| 10252 | 10410 |
| 10253 | 10411 |
| 10254 } } // namespace v8::internal | 10412 } } // namespace v8::internal |
| OLD | NEW |