Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: src/objects.cc

Issue 6735001: [Arguments] Support HasElement and ReferencesObject for arguments objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2660 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); 2671 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
2672 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2672 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2673 return raw_result; 2673 return raw_result;
2674 } 2674 }
2675 2675
2676 2676
2677 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, 2677 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index,
2678 DeleteMode mode) { 2678 DeleteMode mode) {
2679 Heap* heap = GetHeap(); 2679 Heap* heap = GetHeap();
2680 ASSERT(!HasExternalArrayElements()); 2680 ASSERT(!HasExternalArrayElements());
2681 // We don't have to handle strict mode deletion of non-configurable
2682 // properties.
2683 ASSERT(mode != STRICT_DELETION);
2681 switch (GetElementsKind()) { 2684 switch (GetElementsKind()) {
2682 case FAST_ELEMENTS: { 2685 case FAST_ELEMENTS: {
2683 Object* obj; 2686 FixedArray* elements = FixedArray::cast(this->elements());
2684 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 2687 return DeleteFromElements(elements, FAST_ELEMENTS, index, mode);
2685 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2686 }
2687 uint32_t length = IsJSArray() ?
2688 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2689 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2690 if (index < length) {
2691 FixedArray::cast(elements())->set_the_hole(index);
2692 }
2693 break;
2694 } 2688 }
2695 case DICTIONARY_ELEMENTS: { 2689 case DICTIONARY_ELEMENTS: {
2696 NumberDictionary* dictionary = element_dictionary(); 2690 NumberDictionary* dictionary = element_dictionary();
2697 int entry = dictionary->FindEntry(index); 2691 int entry = dictionary->FindEntry(index);
2698 if (entry != NumberDictionary::kNotFound) { 2692 if (entry != NumberDictionary::kNotFound) {
2699 return dictionary->DeleteProperty(entry, mode); 2693 return dictionary->DeleteProperty(entry, mode);
2700 } 2694 }
2701 break; 2695 break;
2702 } 2696 }
2703 case NON_STRICT_ARGUMENTS_ELEMENTS: 2697 case NON_STRICT_ARGUMENTS_ELEMENTS:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2745 ASSERT(result->IsBoolean()); 2739 ASSERT(result->IsBoolean());
2746 return *v8::Utils::OpenHandle(*result); 2740 return *v8::Utils::OpenHandle(*result);
2747 } 2741 }
2748 MaybeObject* raw_result = 2742 MaybeObject* raw_result =
2749 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); 2743 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
2750 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2744 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2751 return raw_result; 2745 return raw_result;
2752 } 2746 }
2753 2747
2754 2748
2755 void JSObject::DeleteFromFastElements(FixedArray* elements, uint32_t index) { 2749 MaybeObject* JSObject::DeleteFromElements(FixedArray* elements,
2756 ASSERT(elements->map() != elements->GetHeap()->fixed_cow_array_map()); 2750 ElementsKind kind,
2757 int length = IsJSArray() 2751 uint32_t index,
2758 ? Smi::cast(JSArray::cast(this)->length())->value() 2752 DeleteMode mode) {
2759 : elements->length(); 2753 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
2760 if (index < static_cast<uint32_t>(length)) {
2761 elements->set_the_hole(index);
2762 }
2763 }
2764
2765
2766 MaybeObject* JSObject::DeleteFromDictionaryElements(NumberDictionary* elements,
2767 uint32_t index,
2768 DeleteMode mode) {
2769 Isolate* isolate = GetIsolate(); 2754 Isolate* isolate = GetIsolate();
2770 int entry = elements->FindEntry(index); 2755 if (kind == FAST_ELEMENTS) {
2771 if (entry != NumberDictionary::kNotFound) { 2756 Object* object;
2772 Object* result = elements->DeleteProperty(entry, mode); 2757 MaybeObject* maybe_object = EnsureWritableFastElements();
2773 if (mode == STRICT_DELETION && result == isolate->heap()->false_value()) { 2758 if (!maybe_object->ToObject(&object)) return maybe_object;
2774 // In strict mode, attempting to delete a non-configurable property 2759 int length = IsJSArray()
2775 // throws an exception. 2760 ? Smi::cast(JSArray::cast(this)->length())->value()
2776 HandleScope scope(isolate); 2761 : elements->length();
2777 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); 2762 if (index < static_cast<uint32_t>(length)) {
2778 Handle<Object> args[2] = { name, Handle<Object>(this) }; 2763 elements->set_the_hole(index);
2779 Handle<Object> error = 2764 }
2780 isolate->factory()->NewTypeError("strict_delete_property", 2765 } else {
2781 HandleVector(args, 2)); 2766 NumberDictionary* dictionary = NumberDictionary::cast(elements);
2782 return isolate->Throw(*error); 2767 int entry = dictionary->FindEntry(index);
2768 if (entry != NumberDictionary::kNotFound) {
2769 Object* result = dictionary->DeleteProperty(entry, mode);
2770 if (mode == STRICT_DELETION && result == isolate->heap()->false_value()) {
2771 // In strict mode, attempting to delete a non-configurable property
2772 // throws an exception.
2773 HandleScope scope(isolate);
2774 Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
2775 Handle<Object> args[2] = { name, Handle<Object>(this) };
2776 Handle<Object> error =
2777 isolate->factory()->NewTypeError("strict_delete_property",
2778 HandleVector(args, 2));
2779 return isolate->Throw(*error);
2780 }
2783 } 2781 }
2784 } 2782 }
2785 return isolate->heap()->true_value(); 2783 return isolate->heap()->true_value();
2786 } 2784 }
2787 2785
2788 2786
2789 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { 2787 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
2790 Isolate* isolate = GetIsolate(); 2788 Isolate* isolate = GetIsolate();
2791 // Check access rights if needed. 2789 // Check access rights if needed.
2792 if (IsAccessCheckNeeded() && 2790 if (IsAccessCheckNeeded() &&
2793 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { 2791 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
2794 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 2792 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
2795 return isolate->heap()->false_value(); 2793 return isolate->heap()->false_value();
2796 } 2794 }
2797 2795
2798 if (IsJSGlobalProxy()) { 2796 if (IsJSGlobalProxy()) {
2799 Object* proto = GetPrototype(); 2797 Object* proto = GetPrototype();
2800 if (proto->IsNull()) return isolate->heap()->false_value(); 2798 if (proto->IsNull()) return isolate->heap()->false_value();
2801 ASSERT(proto->IsJSGlobalObject()); 2799 ASSERT(proto->IsJSGlobalObject());
2802 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); 2800 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
2803 } 2801 }
2804 2802
2805 if (HasIndexedInterceptor()) { 2803 if (HasIndexedInterceptor()) {
2806 // Skip interceptor if forcing deletion. 2804 // Skip interceptor if forcing deletion.
2807 if (mode == FORCE_DELETION) { 2805 return (mode == FORCE_DELETION)
2808 return DeleteElementPostInterceptor(index, mode); 2806 ? DeleteElementPostInterceptor(index, FORCE_DELETION)
2809 } 2807 : DeleteElementWithInterceptor(index);
2810 return DeleteElementWithInterceptor(index);
2811 } 2808 }
2812 2809
2813 switch (GetElementsKind()) { 2810 ElementsKind kind = GetElementsKind();
2814 case FAST_ELEMENTS: { 2811 switch (kind) {
2815 Object* obj; 2812 case FAST_ELEMENTS:
2816 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 2813 case DICTIONARY_ELEMENTS: {
2817 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2814 FixedArray* elements = FixedArray::cast(this->elements());
2818 } 2815 return DeleteFromElements(elements, kind, index, mode);
2819 DeleteFromFastElements(FixedArray::cast(elements()), index);
2820 break;
2821 } 2816 }
2822 2817
2823 case EXTERNAL_PIXEL_ELEMENTS: 2818 case EXTERNAL_PIXEL_ELEMENTS:
2824 case EXTERNAL_BYTE_ELEMENTS: 2819 case EXTERNAL_BYTE_ELEMENTS:
2825 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2820 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2826 case EXTERNAL_SHORT_ELEMENTS: 2821 case EXTERNAL_SHORT_ELEMENTS:
2827 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2822 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2828 case EXTERNAL_INT_ELEMENTS: 2823 case EXTERNAL_INT_ELEMENTS:
2829 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2824 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2830 case EXTERNAL_FLOAT_ELEMENTS: 2825 case EXTERNAL_FLOAT_ELEMENTS:
2831 // Pixel and external array elements cannot be deleted. Just 2826 // Pixel and external array elements cannot be deleted. Just
2832 // silently ignore here. 2827 // silently ignore here.
2833 break; 2828 break;
2834 2829
2835 case DICTIONARY_ELEMENTS:
2836 return DeleteFromDictionaryElements(element_dictionary(), index, mode);
2837
2838 case NON_STRICT_ARGUMENTS_ELEMENTS: { 2830 case NON_STRICT_ARGUMENTS_ELEMENTS: {
2839 FixedArray* parameter_map = FixedArray::cast(elements()); 2831 FixedArray* parameter_map = FixedArray::cast(elements());
2840 uint32_t length = parameter_map->length(); 2832 uint32_t length = parameter_map->length();
2841 Object* probe = 2833 Object* probe =
2842 (index + 2) < length ? parameter_map->get(index + 2) : NULL; 2834 (index + 2) < length ? parameter_map->get(index + 2) : NULL;
2843 if (probe != NULL && !probe->IsTheHole()) { 2835 if (probe == NULL || probe->IsTheHole()) {
2844 // TODO(kmillikin): We could check if this was the last aliased
2845 // parameter, and revert to normal elements in that case. That
2846 // would enable GC of the context.
2847 parameter_map->set_the_hole(index + 2);
2848 } else {
2849 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2836 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
2850 if (arguments->IsDictionary()) { 2837 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
2851 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 2838 return DeleteFromElements(arguments, kind, index, mode);
2852 return DeleteFromDictionaryElements(dictionary, index, mode);
2853 } else {
2854 DeleteFromFastElements(arguments, index);
2855 }
2856 } 2839 }
2840 // TODO(kmillikin): We could check if this was the last aliased
2841 // parameter, and revert to normal elements in that case. That
2842 // would enable GC of the context.
2843 parameter_map->set_the_hole(index + 2);
2857 break; 2844 break;
2858 } 2845 }
2859 } 2846 }
2860 return isolate->heap()->true_value(); 2847 return isolate->heap()->true_value();
2861 } 2848 }
2862 2849
2863 2850
2864 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { 2851 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
2865 Isolate* isolate = GetIsolate(); 2852 Isolate* isolate = GetIsolate();
2866 // ECMA-262, 3rd, 8.6.2.5 2853 // ECMA-262, 3rd, 8.6.2.5
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 { MaybeObject* maybe_obj = 2898 { MaybeObject* maybe_obj =
2912 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2899 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2913 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2900 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2914 } 2901 }
2915 // Make sure the properties are normalized before removing the entry. 2902 // Make sure the properties are normalized before removing the entry.
2916 return DeleteNormalizedProperty(name, mode); 2903 return DeleteNormalizedProperty(name, mode);
2917 } 2904 }
2918 } 2905 }
2919 2906
2920 2907
2908 bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
2909 ElementsKind kind,
2910 Object* object) {
2911 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
2912 if (kind == FAST_ELEMENTS) {
2913 int length = IsJSArray()
2914 ? Smi::cast(JSArray::cast(this)->length())->value()
2915 : elements->length();
2916 for (int i = 0; i < length; ++i) {
2917 Object* element = elements->get(i);
2918 if (!element->IsTheHole() && element == object) return true;
2919 }
2920 } else {
2921 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
2922 if (!key->IsUndefined()) return true;
2923 }
2924 return false;
2925 }
2926
2927
2921 // Check whether this object references another object. 2928 // Check whether this object references another object.
2922 bool JSObject::ReferencesObject(Object* obj) { 2929 bool JSObject::ReferencesObject(Object* obj) {
2923 Heap* heap = GetHeap(); 2930 Heap* heap = GetHeap();
2924 AssertNoAllocation no_alloc; 2931 AssertNoAllocation no_alloc;
2925 2932
2926 // Is the object the constructor for this object? 2933 // Is the object the constructor for this object?
2927 if (map()->constructor() == obj) { 2934 if (map()->constructor() == obj) {
2928 return true; 2935 return true;
2929 } 2936 }
2930 2937
2931 // Is the object the prototype for this object? 2938 // Is the object the prototype for this object?
2932 if (map()->prototype() == obj) { 2939 if (map()->prototype() == obj) {
2933 return true; 2940 return true;
2934 } 2941 }
2935 2942
2936 // Check if the object is among the named properties. 2943 // Check if the object is among the named properties.
2937 Object* key = SlowReverseLookup(obj); 2944 Object* key = SlowReverseLookup(obj);
2938 if (!key->IsUndefined()) { 2945 if (!key->IsUndefined()) {
2939 return true; 2946 return true;
2940 } 2947 }
2941 2948
2942 // Check if the object is among the indexed properties. 2949 // Check if the object is among the indexed properties.
2943 switch (GetElementsKind()) { 2950 ElementsKind kind = GetElementsKind();
2951 switch (kind) {
2944 case EXTERNAL_PIXEL_ELEMENTS: 2952 case EXTERNAL_PIXEL_ELEMENTS:
2945 case EXTERNAL_BYTE_ELEMENTS: 2953 case EXTERNAL_BYTE_ELEMENTS:
2946 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2954 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2947 case EXTERNAL_SHORT_ELEMENTS: 2955 case EXTERNAL_SHORT_ELEMENTS:
2948 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2956 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2949 case EXTERNAL_INT_ELEMENTS: 2957 case EXTERNAL_INT_ELEMENTS:
2950 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2958 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2951 case EXTERNAL_FLOAT_ELEMENTS: 2959 case EXTERNAL_FLOAT_ELEMENTS:
2952 // Raw pixels and external arrays do not reference other 2960 // Raw pixels and external arrays do not reference other
2953 // objects. 2961 // objects.
2954 break; 2962 break;
2955 case FAST_ELEMENTS: { 2963 case FAST_ELEMENTS:
2956 int length = IsJSArray() ?
2957 Smi::cast(JSArray::cast(this)->length())->value() :
2958 FixedArray::cast(elements())->length();
2959 for (int i = 0; i < length; i++) {
2960 Object* element = FixedArray::cast(elements())->get(i);
2961 if (!element->IsTheHole() && element == obj) {
2962 return true;
2963 }
2964 }
2965 break;
2966 }
2967 case DICTIONARY_ELEMENTS: { 2964 case DICTIONARY_ELEMENTS: {
2968 key = element_dictionary()->SlowReverseLookup(obj); 2965 FixedArray* elements = FixedArray::cast(this->elements());
2969 if (!key->IsUndefined()) { 2966 if (ReferencesObjectFromElements(elements, kind, obj)) return true;
2970 return true;
2971 }
2972 break; 2967 break;
2973 } 2968 }
2974 case NON_STRICT_ARGUMENTS_ELEMENTS: { 2969 case NON_STRICT_ARGUMENTS_ELEMENTS: {
2975 FixedArray* parameter_map = FixedArray::cast(elements()); 2970 FixedArray* parameter_map = FixedArray::cast(elements());
2976 // Check the mapped parameters. 2971 // Check the mapped parameters.
2977 int length = parameter_map->length(); 2972 int length = parameter_map->length();
2978 for (int i = 2; i < length; ++i) { 2973 for (int i = 2; i < length; ++i) {
2979 Object* value = parameter_map->get(i); 2974 Object* value = parameter_map->get(i);
2980 if (!value->IsTheHole() && value == obj) return true; 2975 if (!value->IsTheHole() && value == obj) return true;
2981 } 2976 }
2982 // Check the arguments. 2977 // Check the arguments.
2983 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2978 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
2984 if (arguments->IsDictionary()) { 2979 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
2985 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 2980 if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
2986 key = dictionary->SlowReverseLookup(obj);
2987 if (key != heap->undefined_value()) return true;
2988 } else {
2989 int count = arguments->length();
2990 for (int i = 0; i < count; ++i) {
2991 Object* value = arguments->get(i);
2992 if (!value->IsTheHole() && value == obj) return true;
2993 }
2994 }
2995 break; 2981 break;
2996 } 2982 }
2997 } 2983 }
2998 2984
2999 // For functions check the context. 2985 // For functions check the context.
3000 if (IsJSFunction()) { 2986 if (IsJSFunction()) {
3001 // Get the constructor function for arguments array. 2987 // Get the constructor function for arguments array.
3002 JSObject* arguments_boilerplate = 2988 JSObject* arguments_boilerplate =
3003 heap->isolate()->context()->global_context()-> 2989 heap->isolate()->context()->global_context()->
3004 arguments_boilerplate(); 2990 arguments_boilerplate();
(...skipping 4127 matching lines...) Expand 10 before | Expand all | Expand 10 after
7132 } 7118 }
7133 case NON_STRICT_ARGUMENTS_ELEMENTS: 7119 case NON_STRICT_ARGUMENTS_ELEMENTS:
7134 UNIMPLEMENTED(); 7120 UNIMPLEMENTED();
7135 break; 7121 break;
7136 } 7122 }
7137 7123
7138 return UNDEFINED_ELEMENT; 7124 return UNDEFINED_ELEMENT;
7139 } 7125 }
7140 7126
7141 7127
7128 bool JSObject::HasElementInElements(FixedArray* elements,
7129 ElementsKind kind,
7130 uint32_t index) {
7131 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
7132 if (kind == FAST_ELEMENTS) {
7133 int length = IsJSArray()
7134 ? Smi::cast(JSArray::cast(this)->length())->value()
7135 : elements->length();
7136 if (index < static_cast<uint32_t>(length) &&
7137 !elements->get(index)->IsTheHole()) {
7138 return true;
7139 }
7140 } else {
7141 if (NumberDictionary::cast(elements)->FindEntry(index) !=
7142 NumberDictionary::kNotFound) {
7143 return true;
7144 }
7145 }
7146 return false;
7147 }
7148
7149
7142 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { 7150 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
7143 Heap* heap = GetHeap(); 7151 Heap* heap = GetHeap();
7144 7152
7145 // Check access rights if needed. 7153 // Check access rights if needed.
7146 if (IsAccessCheckNeeded() && 7154 if (IsAccessCheckNeeded() &&
7147 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 7155 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
7148 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 7156 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
7149 return false; 7157 return false;
7150 } 7158 }
7151 7159
7152 // Check for lookup interceptor 7160 // Check for lookup interceptor
7153 if (HasIndexedInterceptor()) { 7161 if (HasIndexedInterceptor()) {
7154 return HasElementWithInterceptor(receiver, index); 7162 return HasElementWithInterceptor(receiver, index);
7155 } 7163 }
7156 7164
7157 switch (GetElementsKind()) { 7165 ElementsKind kind = GetElementsKind();
7158 case FAST_ELEMENTS: { 7166 switch (kind) {
7159 uint32_t length = IsJSArray() ? 7167 case FAST_ELEMENTS:
7160 static_cast<uint32_t> 7168 case DICTIONARY_ELEMENTS: {
7161 (Smi::cast(JSArray::cast(this)->length())->value()) : 7169 FixedArray* elements = FixedArray::cast(this->elements());
7162 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 7170 if (HasElementInElements(elements, kind, index)) return true;
7163 if ((index < length) &&
7164 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
7165 break; 7171 break;
7166 } 7172 }
7167 case EXTERNAL_PIXEL_ELEMENTS: { 7173 case EXTERNAL_PIXEL_ELEMENTS: {
7168 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 7174 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
7169 if (index < static_cast<uint32_t>(pixels->length())) { 7175 if (index < static_cast<uint32_t>(pixels->length())) {
7170 return true; 7176 return true;
7171 } 7177 }
7172 break; 7178 break;
7173 } 7179 }
7174 case EXTERNAL_BYTE_ELEMENTS: 7180 case EXTERNAL_BYTE_ELEMENTS:
7175 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7181 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7176 case EXTERNAL_SHORT_ELEMENTS: 7182 case EXTERNAL_SHORT_ELEMENTS:
7177 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7183 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7178 case EXTERNAL_INT_ELEMENTS: 7184 case EXTERNAL_INT_ELEMENTS:
7179 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7185 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7180 case EXTERNAL_FLOAT_ELEMENTS: { 7186 case EXTERNAL_FLOAT_ELEMENTS: {
7181 ExternalArray* array = ExternalArray::cast(elements()); 7187 ExternalArray* array = ExternalArray::cast(elements());
7182 if (index < static_cast<uint32_t>(array->length())) { 7188 if (index < static_cast<uint32_t>(array->length())) {
7183 return true; 7189 return true;
7184 } 7190 }
7185 break; 7191 break;
7186 } 7192 }
7187 case DICTIONARY_ELEMENTS: {
7188 if (element_dictionary()->FindEntry(index)
7189 != NumberDictionary::kNotFound) {
7190 return true;
7191 }
7192 break;
7193 }
7194 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7193 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7195 FixedArray* parameter_map = FixedArray::cast(elements()); 7194 FixedArray* parameter_map = FixedArray::cast(elements());
7196 uint32_t length = parameter_map->length(); 7195 uint32_t length = parameter_map->length();
7197 Object* probe = 7196 Object* probe =
7198 (index + 2 < length) ? parameter_map->get(index + 2) : NULL; 7197 (index + 2 < length) ? parameter_map->get(index + 2) : NULL;
7199 if (probe != NULL && !probe->IsTheHole()) return true; 7198 if (probe != NULL && !probe->IsTheHole()) return true;
7200 7199
7201 // Not a mapped parameter, check the arguments. 7200 // Not a mapped parameter, check the arguments.
7202 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 7201 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7203 if (arguments->IsDictionary()) { 7202 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
7204 if (NumberDictionary::cast(arguments)->FindEntry(index) != 7203 if (HasElementInElements(arguments, kind, index)) return true;
7205 NumberDictionary::kNotFound) {
7206 return true;
7207 }
7208 } else if (index < static_cast<uint32_t>(arguments->length()) &&
7209 !arguments->get(index)->IsTheHole()) {
7210 return true;
7211 }
7212 break; 7204 break;
7213 } 7205 }
7214 } 7206 }
7215 7207
7216 // Handle [] on String objects. 7208 // Handle [] on String objects.
7217 if (this->IsStringObjectWithCharacterAt(index)) return true; 7209 if (this->IsStringObjectWithCharacterAt(index)) return true;
7218 7210
7219 Object* pt = GetPrototype(); 7211 Object* pt = GetPrototype();
7220 if (pt->IsNull()) return false; 7212 if (pt->IsNull()) return false;
7221 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 7213 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
(...skipping 3211 matching lines...) Expand 10 before | Expand all | Expand 10 after
10433 if (break_point_objects()->IsUndefined()) return 0; 10425 if (break_point_objects()->IsUndefined()) return 0;
10434 // Single beak point. 10426 // Single beak point.
10435 if (!break_point_objects()->IsFixedArray()) return 1; 10427 if (!break_point_objects()->IsFixedArray()) return 1;
10436 // Multiple break points. 10428 // Multiple break points.
10437 return FixedArray::cast(break_point_objects())->length(); 10429 return FixedArray::cast(break_point_objects())->length();
10438 } 10430 }
10439 #endif 10431 #endif
10440 10432
10441 10433
10442 } } // namespace v8::internal 10434 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698