OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 uint32_t unshift_size) final { | 693 uint32_t unshift_size) final { |
694 return Subclass::UnshiftImpl(receiver, args, unshift_size); | 694 return Subclass::UnshiftImpl(receiver, args, unshift_size); |
695 } | 695 } |
696 | 696 |
697 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, | 697 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, |
698 uint32_t unshift_size) { | 698 uint32_t unshift_size) { |
699 UNREACHABLE(); | 699 UNREACHABLE(); |
700 return 0; | 700 return 0; |
701 } | 701 } |
702 | 702 |
703 Handle<JSArray> Slice(Handle<JSObject> receiver, uint32_t start, | 703 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
704 uint32_t end) final { | 704 uint32_t end) final { |
705 return Subclass::SliceImpl(receiver, start, end); | 705 return Subclass::SliceImpl(receiver, start, end); |
706 } | 706 } |
707 | 707 |
708 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 708 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
709 uint32_t start, uint32_t end) { | 709 uint32_t end, Handle<JSObject> result) final { |
| 710 return Subclass::SliceWithResultImpl(receiver, start, end, result); |
| 711 } |
| 712 |
| 713 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
| 714 uint32_t end) { |
710 UNREACHABLE(); | 715 UNREACHABLE(); |
711 return Handle<JSArray>(); | 716 return Handle<JSObject>(); |
| 717 } |
| 718 |
| 719 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 720 uint32_t start, uint32_t end, |
| 721 Handle<JSObject> result) { |
| 722 UNREACHABLE(); |
| 723 return Handle<JSObject>(); |
712 } | 724 } |
713 | 725 |
714 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, | 726 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, |
715 uint32_t delete_count, Arguments* args, | 727 uint32_t delete_count, Arguments* args, |
716 uint32_t add_count) final { | 728 uint32_t add_count) final { |
717 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); | 729 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); |
718 } | 730 } |
719 | 731 |
720 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 732 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
721 uint32_t start, uint32_t delete_count, | 733 uint32_t start, uint32_t delete_count, |
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 AT_END); | 2054 AT_END); |
2043 } | 2055 } |
2044 | 2056 |
2045 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 2057 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
2046 Arguments* args, uint32_t unshift_size) { | 2058 Arguments* args, uint32_t unshift_size) { |
2047 Handle<FixedArrayBase> backing_store(receiver->elements()); | 2059 Handle<FixedArrayBase> backing_store(receiver->elements()); |
2048 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, | 2060 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, |
2049 AT_START); | 2061 AT_START); |
2050 } | 2062 } |
2051 | 2063 |
2052 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 2064 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
2053 uint32_t start, uint32_t end) { | 2065 uint32_t end) { |
2054 Isolate* isolate = receiver->GetIsolate(); | 2066 Isolate* isolate = receiver->GetIsolate(); |
2055 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); | 2067 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); |
2056 int result_len = end < start ? 0u : end - start; | 2068 int result_len = end < start ? 0u : end - start; |
2057 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 2069 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
2058 KindTraits::Kind, result_len, result_len); | 2070 KindTraits::Kind, result_len, result_len); |
2059 DisallowHeapAllocation no_gc; | 2071 DisallowHeapAllocation no_gc; |
2060 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), | 2072 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), |
2061 KindTraits::Kind, 0, kPackedSizeNotKnown, | 2073 KindTraits::Kind, 0, kPackedSizeNotKnown, |
2062 result_len); | 2074 result_len); |
2063 Subclass::TryTransitionResultArrayToPacked(result_array); | 2075 Subclass::TryTransitionResultArrayToPacked(result_array); |
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 DCHECK(!WasNeutered(receiver)); | 3057 DCHECK(!WasNeutered(receiver)); |
3046 | 3058 |
3047 BackingStore* elements = BackingStore::cast(receiver->elements()); | 3059 BackingStore* elements = BackingStore::cast(receiver->elements()); |
3048 | 3060 |
3049 uint32_t len = elements->length(); | 3061 uint32_t len = elements->length(); |
3050 if (len == 0) return; | 3062 if (len == 0) return; |
3051 | 3063 |
3052 ctype* data = static_cast<ctype*>(elements->DataPtr()); | 3064 ctype* data = static_cast<ctype*>(elements->DataPtr()); |
3053 std::reverse(data, data + len); | 3065 std::reverse(data, data + len); |
3054 } | 3066 } |
| 3067 |
| 3068 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 3069 uint32_t start, uint32_t end, |
| 3070 Handle<JSObject> result) { |
| 3071 Isolate* isolate = receiver->GetIsolate(); |
| 3072 DCHECK(!WasNeutered(*receiver)); |
| 3073 DCHECK(result->IsJSTypedArray()); |
| 3074 DCHECK(!WasNeutered(*result)); |
| 3075 DCHECK_LE(start, end); |
| 3076 |
| 3077 Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver); |
| 3078 Handle<JSTypedArray> result_array = Handle<JSTypedArray>::cast(result); |
| 3079 DCHECK_LE(end, array->length_value()); |
| 3080 |
| 3081 // Fast path for the same type result array |
| 3082 if (result_array->type() == array->type()) { |
| 3083 int64_t element_size = array->element_size(); |
| 3084 int64_t count = end - start; |
| 3085 |
| 3086 DisallowHeapAllocation no_gc; |
| 3087 BackingStore* src_elements = BackingStore::cast(receiver->elements()); |
| 3088 BackingStore* result_elements = |
| 3089 BackingStore::cast(result_array->elements()); |
| 3090 |
| 3091 DCHECK_LE(count, result_elements->length()); |
| 3092 |
| 3093 uint8_t* src = static_cast<uint8_t*>(src_elements->DataPtr()); |
| 3094 uint8_t* result = static_cast<uint8_t*>(result_elements->DataPtr()); |
| 3095 std::memcpy(result, src + start * element_size, count * element_size); |
| 3096 return result_array; |
| 3097 } |
| 3098 |
| 3099 // If the types of the two typed arrays are different, properly convert |
| 3100 // elements |
| 3101 Handle<BackingStore> from(BackingStore::cast(array->elements()), isolate); |
| 3102 ElementsAccessor* result_accessor = result_array->GetElementsAccessor(); |
| 3103 for (uint32_t i = start; i < end; i++) { |
| 3104 Handle<Object> elem = AccessorClass::GetImpl(isolate, *from, i); |
| 3105 result_accessor->Set(result_array, i, *elem); |
| 3106 } |
| 3107 return result_array; |
| 3108 } |
3055 }; | 3109 }; |
3056 | 3110 |
3057 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 3111 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
3058 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ | 3112 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
3059 Fixed##Type##ElementsAccessor; | 3113 Fixed##Type##ElementsAccessor; |
3060 | 3114 |
3061 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 3115 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
3062 #undef FIXED_ELEMENTS_ACCESSOR | 3116 #undef FIXED_ELEMENTS_ACCESSOR |
3063 | 3117 |
3064 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> | 3118 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3482 FastSloppyArgumentsElementsAccessor, | 3536 FastSloppyArgumentsElementsAccessor, |
3483 FastHoleyObjectElementsAccessor, | 3537 FastHoleyObjectElementsAccessor, |
3484 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 3538 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
3485 | 3539 |
3486 static Handle<FixedArray> GetArguments(Isolate* isolate, | 3540 static Handle<FixedArray> GetArguments(Isolate* isolate, |
3487 FixedArrayBase* backing_store) { | 3541 FixedArrayBase* backing_store) { |
3488 FixedArray* parameter_map = FixedArray::cast(backing_store); | 3542 FixedArray* parameter_map = FixedArray::cast(backing_store); |
3489 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); | 3543 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); |
3490 } | 3544 } |
3491 | 3545 |
3492 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start, | 3546 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
3493 uint32_t end) { | 3547 uint32_t end) { |
3494 Isolate* isolate = receiver->GetIsolate(); | 3548 Isolate* isolate = receiver->GetIsolate(); |
3495 uint32_t result_len = end < start ? 0u : end - start; | 3549 uint32_t result_len = end < start ? 0u : end - start; |
3496 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 3550 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
3497 FAST_HOLEY_ELEMENTS, result_len, result_len); | 3551 FAST_HOLEY_ELEMENTS, result_len, result_len); |
3498 DisallowHeapAllocation no_gc; | 3552 DisallowHeapAllocation no_gc; |
3499 FixedArray* elements = FixedArray::cast(result_array->elements()); | 3553 FixedArray* elements = FixedArray::cast(result_array->elements()); |
3500 FixedArray* parameters = FixedArray::cast(receiver->elements()); | 3554 FixedArray* parameters = FixedArray::cast(receiver->elements()); |
3501 uint32_t insertion_index = 0; | 3555 uint32_t insertion_index = 0; |
3502 for (uint32_t i = start; i < end; i++) { | 3556 for (uint32_t i = start; i < end; i++) { |
3503 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, | 3557 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4000 insertion_index += len; | 4054 insertion_index += len; |
4001 } | 4055 } |
4002 | 4056 |
4003 DCHECK_EQ(insertion_index, result_len); | 4057 DCHECK_EQ(insertion_index, result_len); |
4004 return result_array; | 4058 return result_array; |
4005 } | 4059 } |
4006 | 4060 |
4007 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 4061 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
4008 } // namespace internal | 4062 } // namespace internal |
4009 } // namespace v8 | 4063 } // namespace v8 |
OLD | NEW |