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 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 uint32_t unshift_size) final { | 677 uint32_t unshift_size) final { |
678 return Subclass::UnshiftImpl(receiver, args, unshift_size); | 678 return Subclass::UnshiftImpl(receiver, args, unshift_size); |
679 } | 679 } |
680 | 680 |
681 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, | 681 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, |
682 uint32_t unshift_size) { | 682 uint32_t unshift_size) { |
683 UNREACHABLE(); | 683 UNREACHABLE(); |
684 return 0; | 684 return 0; |
685 } | 685 } |
686 | 686 |
687 Handle<JSArray> Slice(Handle<JSObject> receiver, uint32_t start, | 687 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
688 uint32_t end) final { | 688 uint32_t end) final { |
689 return Subclass::SliceImpl(receiver, start, end); | 689 return Subclass::SliceImpl(receiver, start, end); |
690 } | 690 } |
691 | 691 |
692 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 692 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
693 uint32_t start, uint32_t end) { | 693 uint32_t end, Handle<JSObject> result) final { |
| 694 return Subclass::SliceWithResultImpl(receiver, start, end, result); |
| 695 } |
| 696 |
| 697 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
| 698 uint32_t end) { |
694 UNREACHABLE(); | 699 UNREACHABLE(); |
695 return Handle<JSArray>(); | 700 return Handle<JSObject>(); |
| 701 } |
| 702 |
| 703 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 704 uint32_t start, uint32_t end, |
| 705 Handle<JSObject> result) { |
| 706 return Subclass::SliceImpl(receiver, start, end); |
696 } | 707 } |
697 | 708 |
698 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, | 709 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, |
699 uint32_t delete_count, Arguments* args, | 710 uint32_t delete_count, Arguments* args, |
700 uint32_t add_count) final { | 711 uint32_t add_count) final { |
701 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); | 712 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); |
702 } | 713 } |
703 | 714 |
704 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 715 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
705 uint32_t start, uint32_t delete_count, | 716 uint32_t start, uint32_t delete_count, |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2010 AT_END); | 2021 AT_END); |
2011 } | 2022 } |
2012 | 2023 |
2013 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 2024 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
2014 Arguments* args, uint32_t unshift_size) { | 2025 Arguments* args, uint32_t unshift_size) { |
2015 Handle<FixedArrayBase> backing_store(receiver->elements()); | 2026 Handle<FixedArrayBase> backing_store(receiver->elements()); |
2016 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, | 2027 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, |
2017 AT_START); | 2028 AT_START); |
2018 } | 2029 } |
2019 | 2030 |
2020 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 2031 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
2021 uint32_t start, uint32_t end) { | 2032 uint32_t end) { |
2022 Isolate* isolate = receiver->GetIsolate(); | 2033 Isolate* isolate = receiver->GetIsolate(); |
2023 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); | 2034 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); |
2024 int result_len = end < start ? 0u : end - start; | 2035 int result_len = end < start ? 0u : end - start; |
2025 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 2036 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
2026 KindTraits::Kind, result_len, result_len); | 2037 KindTraits::Kind, result_len, result_len); |
2027 DisallowHeapAllocation no_gc; | 2038 DisallowHeapAllocation no_gc; |
2028 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), | 2039 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), |
2029 KindTraits::Kind, 0, kPackedSizeNotKnown, | 2040 KindTraits::Kind, 0, kPackedSizeNotKnown, |
2030 result_len); | 2041 result_len); |
2031 Subclass::TryTransitionResultArrayToPacked(result_array); | 2042 Subclass::TryTransitionResultArrayToPacked(result_array); |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2963 | 2974 |
2964 DCHECK_LT(start_from, elements->length()); | 2975 DCHECK_LT(start_from, elements->length()); |
2965 | 2976 |
2966 uint32_t k = start_from; | 2977 uint32_t k = start_from; |
2967 do { | 2978 do { |
2968 ctype element_k = elements->get_scalar(k); | 2979 ctype element_k = elements->get_scalar(k); |
2969 if (element_k == typed_search_value) return Just<int64_t>(k); | 2980 if (element_k == typed_search_value) return Just<int64_t>(k); |
2970 } while (k-- != 0); | 2981 } while (k-- != 0); |
2971 return Just<int64_t>(-1); | 2982 return Just<int64_t>(-1); |
2972 } | 2983 } |
| 2984 |
| 2985 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 2986 uint32_t start, uint32_t end, |
| 2987 Handle<JSObject> result) { |
| 2988 Isolate* isolate = receiver->GetIsolate(); |
| 2989 DCHECK(!WasNeutered(*receiver)); |
| 2990 DCHECK(result->IsJSTypedArray()); |
| 2991 DCHECK(!WasNeutered(*result)); |
| 2992 DCHECK_LE(start, end); |
| 2993 |
| 2994 Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver); |
| 2995 Handle<JSTypedArray> result_array = Handle<JSTypedArray>::cast(result); |
| 2996 DCHECK_LE(end, array->length_value()); |
| 2997 |
| 2998 // Fast path for the same type result array |
| 2999 if (result_array->type() == array->type()) { |
| 3000 int64_t element_size = array->element_size(); |
| 3001 int64_t count = std::max<int64_t>(end - start, 0); |
| 3002 |
| 3003 DisallowHeapAllocation no_gc; |
| 3004 BackingStore* src_elements = BackingStore::cast(receiver->elements()); |
| 3005 BackingStore* result_elements = |
| 3006 BackingStore::cast(result_array->elements()); |
| 3007 |
| 3008 DCHECK_LE(count, result_elements->length()); |
| 3009 |
| 3010 uint8_t* src = static_cast<uint8_t*>(src_elements->DataPtr()); |
| 3011 uint8_t* result = static_cast<uint8_t*>(result_elements->DataPtr()); |
| 3012 std::memcpy(result, src + start * element_size, count * element_size); |
| 3013 return result_array; |
| 3014 } |
| 3015 |
| 3016 // If the types of the two typed arrays are different, properly convert |
| 3017 // elements |
| 3018 Handle<BackingStore> from(BackingStore::cast(array->elements()), isolate); |
| 3019 ElementsAccessor* result_accessor = result_array->GetElementsAccessor(); |
| 3020 for (uint32_t k = start; k < end; k++) { |
| 3021 Handle<Object> elem = AccessorClass::GetImpl(isolate, *from, k); |
| 3022 result_accessor->Set(result_array, k, *elem); |
| 3023 } |
| 3024 return result_array; |
| 3025 } |
2973 }; | 3026 }; |
2974 | 3027 |
2975 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 3028 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
2976 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ | 3029 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
2977 Fixed##Type##ElementsAccessor; | 3030 Fixed##Type##ElementsAccessor; |
2978 | 3031 |
2979 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 3032 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
2980 #undef FIXED_ELEMENTS_ACCESSOR | 3033 #undef FIXED_ELEMENTS_ACCESSOR |
2981 | 3034 |
2982 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> | 3035 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3400 FastSloppyArgumentsElementsAccessor, | 3453 FastSloppyArgumentsElementsAccessor, |
3401 FastHoleyObjectElementsAccessor, | 3454 FastHoleyObjectElementsAccessor, |
3402 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 3455 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
3403 | 3456 |
3404 static Handle<FixedArray> GetArguments(Isolate* isolate, | 3457 static Handle<FixedArray> GetArguments(Isolate* isolate, |
3405 FixedArrayBase* backing_store) { | 3458 FixedArrayBase* backing_store) { |
3406 FixedArray* parameter_map = FixedArray::cast(backing_store); | 3459 FixedArray* parameter_map = FixedArray::cast(backing_store); |
3407 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); | 3460 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); |
3408 } | 3461 } |
3409 | 3462 |
3410 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start, | 3463 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
3411 uint32_t end) { | 3464 uint32_t end) { |
3412 Isolate* isolate = receiver->GetIsolate(); | 3465 Isolate* isolate = receiver->GetIsolate(); |
3413 uint32_t result_len = end < start ? 0u : end - start; | 3466 uint32_t result_len = end < start ? 0u : end - start; |
3414 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 3467 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
3415 FAST_HOLEY_ELEMENTS, result_len, result_len); | 3468 FAST_HOLEY_ELEMENTS, result_len, result_len); |
3416 DisallowHeapAllocation no_gc; | 3469 DisallowHeapAllocation no_gc; |
3417 FixedArray* elements = FixedArray::cast(result_array->elements()); | 3470 FixedArray* elements = FixedArray::cast(result_array->elements()); |
3418 FixedArray* parameters = FixedArray::cast(receiver->elements()); | 3471 FixedArray* parameters = FixedArray::cast(receiver->elements()); |
3419 uint32_t insertion_index = 0; | 3472 uint32_t insertion_index = 0; |
3420 for (uint32_t i = start; i < end; i++) { | 3473 for (uint32_t i = start; i < end; i++) { |
3421 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, | 3474 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 insertion_index += len; | 3971 insertion_index += len; |
3919 } | 3972 } |
3920 | 3973 |
3921 DCHECK_EQ(insertion_index, result_len); | 3974 DCHECK_EQ(insertion_index, result_len); |
3922 return result_array; | 3975 return result_array; |
3923 } | 3976 } |
3924 | 3977 |
3925 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3978 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3926 } // namespace internal | 3979 } // namespace internal |
3927 } // namespace v8 | 3980 } // namespace v8 |
OLD | NEW |