| 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 2734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2745 ASSERT(result->IsBoolean()); | 2745 ASSERT(result->IsBoolean()); |
| 2746 return *v8::Utils::OpenHandle(*result); | 2746 return *v8::Utils::OpenHandle(*result); |
| 2747 } | 2747 } |
| 2748 MaybeObject* raw_result = | 2748 MaybeObject* raw_result = |
| 2749 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); | 2749 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); |
| 2750 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2750 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2751 return raw_result; | 2751 return raw_result; |
| 2752 } | 2752 } |
| 2753 | 2753 |
| 2754 | 2754 |
| 2755 void JSObject::DeleteFromFastElements(FixedArray* elements, uint32_t index) { |
| 2756 ASSERT(elements->map() != elements->GetHeap()->fixed_cow_array_map()); |
| 2757 int length = IsJSArray() |
| 2758 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 2759 : elements->length(); |
| 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(); |
| 2770 int entry = elements->FindEntry(index); |
| 2771 if (entry != NumberDictionary::kNotFound) { |
| 2772 Object* result = elements->DeleteProperty(entry, mode); |
| 2773 if (mode == STRICT_DELETION && result == isolate->heap()->false_value()) { |
| 2774 // In strict mode, attempting to delete a non-configurable property |
| 2775 // throws an exception. |
| 2776 HandleScope scope(isolate); |
| 2777 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); |
| 2778 Handle<Object> args[2] = { name, Handle<Object>(this) }; |
| 2779 Handle<Object> error = |
| 2780 isolate->factory()->NewTypeError("strict_delete_property", |
| 2781 HandleVector(args, 2)); |
| 2782 return isolate->Throw(*error); |
| 2783 } |
| 2784 } |
| 2785 return isolate->heap()->true_value(); |
| 2786 } |
| 2787 |
| 2788 |
| 2755 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 2789 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 2756 Isolate* isolate = GetIsolate(); | 2790 Isolate* isolate = GetIsolate(); |
| 2757 // Check access rights if needed. | 2791 // Check access rights if needed. |
| 2758 if (IsAccessCheckNeeded() && | 2792 if (IsAccessCheckNeeded() && |
| 2759 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 2793 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
| 2760 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2794 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 2761 return isolate->heap()->false_value(); | 2795 return isolate->heap()->false_value(); |
| 2762 } | 2796 } |
| 2763 | 2797 |
| 2764 if (IsJSGlobalProxy()) { | 2798 if (IsJSGlobalProxy()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2775 } | 2809 } |
| 2776 return DeleteElementWithInterceptor(index); | 2810 return DeleteElementWithInterceptor(index); |
| 2777 } | 2811 } |
| 2778 | 2812 |
| 2779 switch (GetElementsKind()) { | 2813 switch (GetElementsKind()) { |
| 2780 case FAST_ELEMENTS: { | 2814 case FAST_ELEMENTS: { |
| 2781 Object* obj; | 2815 Object* obj; |
| 2782 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 2816 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 2783 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2817 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2784 } | 2818 } |
| 2785 uint32_t length = IsJSArray() ? | 2819 DeleteFromFastElements(FixedArray::cast(elements()), index); |
| 2786 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | |
| 2787 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | |
| 2788 if (index < length) { | |
| 2789 FixedArray::cast(elements())->set_the_hole(index); | |
| 2790 } | |
| 2791 break; | 2820 break; |
| 2792 } | 2821 } |
| 2793 | 2822 |
| 2794 case EXTERNAL_PIXEL_ELEMENTS: | 2823 case EXTERNAL_PIXEL_ELEMENTS: |
| 2795 case EXTERNAL_BYTE_ELEMENTS: | 2824 case EXTERNAL_BYTE_ELEMENTS: |
| 2796 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2825 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2797 case EXTERNAL_SHORT_ELEMENTS: | 2826 case EXTERNAL_SHORT_ELEMENTS: |
| 2798 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2827 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2799 case EXTERNAL_INT_ELEMENTS: | 2828 case EXTERNAL_INT_ELEMENTS: |
| 2800 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2829 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2801 case EXTERNAL_FLOAT_ELEMENTS: | 2830 case EXTERNAL_FLOAT_ELEMENTS: |
| 2802 // Pixel and external array elements cannot be deleted. Just | 2831 // Pixel and external array elements cannot be deleted. Just |
| 2803 // silently ignore here. | 2832 // silently ignore here. |
| 2804 break; | 2833 break; |
| 2805 | 2834 |
| 2806 case DICTIONARY_ELEMENTS: { | 2835 case DICTIONARY_ELEMENTS: |
| 2807 NumberDictionary* dictionary = element_dictionary(); | 2836 return DeleteFromDictionaryElements(element_dictionary(), index, mode); |
| 2808 int entry = dictionary->FindEntry(index); | 2837 |
| 2809 if (entry != NumberDictionary::kNotFound) { | 2838 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 2810 Object* result = dictionary->DeleteProperty(entry, mode); | 2839 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 2811 if (mode == STRICT_DELETION && result == | 2840 uint32_t length = parameter_map->length(); |
| 2812 isolate->heap()->false_value()) { | 2841 Object* probe = |
| 2813 // In strict mode, deleting a non-configurable property throws | 2842 (index + 2) < length ? parameter_map->get(index + 2) : NULL; |
| 2814 // exception. dictionary->DeleteProperty will return false_value() | 2843 if (probe != NULL && !probe->IsTheHole()) { |
| 2815 // if a non-configurable property is being deleted. | 2844 // TODO(kmillikin): We could check if this was the last aliased |
| 2816 HandleScope scope; | 2845 // parameter, and revert to normal elements in that case. That |
| 2817 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); | 2846 // would enable GC of the context. |
| 2818 Handle<Object> args[2] = { i, Handle<Object>(this) }; | 2847 parameter_map->set_the_hole(index + 2); |
| 2819 return isolate->Throw(*isolate->factory()->NewTypeError( | 2848 } else { |
| 2820 "strict_delete_property", HandleVector(args, 2))); | 2849 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 2850 if (arguments->IsDictionary()) { |
| 2851 NumberDictionary* dictionary = NumberDictionary::cast(arguments); |
| 2852 return DeleteFromDictionaryElements(dictionary, index, mode); |
| 2853 } else { |
| 2854 DeleteFromFastElements(arguments, index); |
| 2821 } | 2855 } |
| 2822 } | 2856 } |
| 2823 break; | 2857 break; |
| 2824 } | 2858 } |
| 2825 | |
| 2826 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 2827 UNIMPLEMENTED(); | |
| 2828 break; | |
| 2829 } | 2859 } |
| 2830 return isolate->heap()->true_value(); | 2860 return isolate->heap()->true_value(); |
| 2831 } | 2861 } |
| 2832 | 2862 |
| 2833 | 2863 |
| 2834 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2864 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 2835 Isolate* isolate = GetIsolate(); | 2865 Isolate* isolate = GetIsolate(); |
| 2836 // ECMA-262, 3rd, 8.6.2.5 | 2866 // ECMA-262, 3rd, 8.6.2.5 |
| 2837 ASSERT(name->IsString()); | 2867 ASSERT(name->IsString()); |
| 2838 | 2868 |
| (...skipping 7564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10403 if (break_point_objects()->IsUndefined()) return 0; | 10433 if (break_point_objects()->IsUndefined()) return 0; |
| 10404 // Single beak point. | 10434 // Single beak point. |
| 10405 if (!break_point_objects()->IsFixedArray()) return 1; | 10435 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10406 // Multiple break points. | 10436 // Multiple break points. |
| 10407 return FixedArray::cast(break_point_objects())->length(); | 10437 return FixedArray::cast(break_point_objects())->length(); |
| 10408 } | 10438 } |
| 10409 #endif | 10439 #endif |
| 10410 | 10440 |
| 10411 | 10441 |
| 10412 } } // namespace v8::internal | 10442 } } // namespace v8::internal |
| OLD | NEW |