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 <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "v8.h" | 8 #include "v8.h" |
9 | 9 |
10 #include "accessors.h" | 10 #include "accessors.h" |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
955 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | 955 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
956 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | 956 CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
957 CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2); | 957 CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2); |
958 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3); | 958 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3); |
959 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4); | 959 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4); |
960 | 960 |
961 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && | 961 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && |
962 arrayId <= Runtime::ARRAY_ID_LAST); | 962 arrayId <= Runtime::ARRAY_ID_LAST); |
963 RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer()); | 963 RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer()); |
964 | 964 |
965 ASSERT(holder->GetInternalFieldCount() == | |
966 v8::ArrayBufferView::kInternalFieldCount); | |
967 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | |
968 holder->SetInternalField(i, Smi::FromInt(0)); | |
969 } | |
970 | |
971 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | 965 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
972 size_t element_size = 1; // Bogus initialization. | 966 size_t element_size = 1; // Bogus initialization. |
973 ElementsKind external_elements_kind = | 967 ElementsKind external_elements_kind = |
974 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. | 968 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. |
975 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 969 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
976 Runtime::ArrayIdToTypeAndSize(arrayId, | 970 Runtime::ArrayIdToTypeAndSize(arrayId, |
977 &array_type, | 971 &array_type, |
978 &external_elements_kind, | 972 &external_elements_kind, |
979 &fixed_elements_kind, | 973 &fixed_elements_kind, |
980 &element_size); | 974 &element_size); |
981 | |
982 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 975 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
983 | 976 |
984 size_t byte_offset = 0; | 977 size_t byte_offset = 0; |
985 size_t byte_length = 0; | 978 size_t byte_length = 0; |
986 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); | 979 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); |
987 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); | 980 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); |
988 | 981 |
989 holder->set_byte_offset(*byte_offset_object); | |
990 holder->set_byte_length(*byte_length_object); | |
991 | |
992 RUNTIME_ASSERT(byte_length % element_size == 0); | 982 RUNTIME_ASSERT(byte_length % element_size == 0); |
993 size_t length = byte_length / element_size; | 983 size_t length = byte_length / element_size; |
994 | 984 |
995 if (length > static_cast<unsigned>(Smi::kMaxValue)) { | 985 if (length > static_cast<unsigned>(Smi::kMaxValue)) { |
996 return isolate->Throw( | 986 return isolate->Throw( |
997 *isolate->factory()->NewRangeError("invalid_typed_array_length", | 987 *isolate->factory()->NewRangeError("invalid_typed_array_length", |
998 HandleVector<Object>(NULL, 0))); | 988 HandleVector<Object>(NULL, 0))); |
999 } | 989 } |
1000 | 990 |
1001 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | |
1002 holder->set_length(*length_obj); | |
1003 if (!maybe_buffer->IsNull()) { | 991 if (!maybe_buffer->IsNull()) { |
1004 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(*maybe_buffer)); | 992 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(*maybe_buffer)); |
1005 | 993 |
1006 size_t array_buffer_byte_length = | 994 size_t array_buffer_byte_length = |
1007 NumberToSize(isolate, buffer->byte_length()); | 995 NumberToSize(isolate, buffer->byte_length()); |
1008 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); | 996 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); |
1009 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); | 997 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); |
1010 | 998 |
1011 holder->set_buffer(*buffer); | 999 holder->set_buffer(*buffer); |
1012 holder->set_weak_next(buffer->weak_first_view()); | 1000 holder->set_weak_next(buffer->weak_first_view()); |
1013 buffer->set_weak_first_view(*holder); | 1001 buffer->set_weak_first_view(*holder); |
1014 | 1002 |
1015 Handle<ExternalArray> elements = | 1003 Handle<ExternalArray> elements = |
1016 isolate->factory()->NewExternalArray( | 1004 isolate->factory()->NewExternalArray( |
1017 static_cast<int>(length), array_type, | 1005 static_cast<int>(length), array_type, |
1018 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | 1006 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
1019 Handle<Map> map = | 1007 Handle<Map> map = |
1020 JSObject::GetElementsTransitionMap(holder, external_elements_kind); | 1008 JSObject::GetElementsTransitionMap(holder, external_elements_kind); |
1021 JSObject::SetMapAndElements(holder, map, elements); | 1009 JSObject::SetMapAndElements(holder, map, elements); |
1022 ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind())); | 1010 ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind())); |
1023 } else { | 1011 } else { |
1024 holder->set_buffer(Smi::FromInt(0)); | 1012 holder->set_buffer(Smi::FromInt(0)); |
1025 holder->set_weak_next(isolate->heap()->undefined_value()); | 1013 holder->set_weak_next(isolate->heap()->undefined_value()); |
1026 Handle<FixedTypedArrayBase> elements = | 1014 Handle<FixedTypedArrayBase> elements = |
1027 isolate->factory()->NewFixedTypedArray( | 1015 isolate->factory()->NewFixedTypedArray( |
1028 static_cast<int>(length), array_type); | 1016 static_cast<int>(length), array_type); |
1029 holder->set_elements(*elements); | 1017 holder->set_elements(*elements); |
1030 } | 1018 } |
1019 | |
1020 ASSERT(holder->GetInternalFieldCount() == | |
Dmitry Lomov (no reviews)
2014/05/21 11:02:46
Nit: could you move this whole initialization bloc
| |
1021 v8::ArrayBufferView::kInternalFieldCount); | |
1022 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | |
1023 holder->SetInternalField(i, Smi::FromInt(0)); | |
1024 } | |
1025 | |
1026 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | |
1027 holder->set_length(*length_obj); | |
1028 holder->set_byte_offset(*byte_offset_object); | |
1029 holder->set_byte_length(*byte_length_object); | |
1030 | |
1031 return isolate->heap()->undefined_value(); | 1031 return isolate->heap()->undefined_value(); |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
1035 // Initializes a typed array from an array-like object. | 1035 // Initializes a typed array from an array-like object. |
1036 // If an array-like object happens to be a typed array of the same type, | 1036 // If an array-like object happens to be a typed array of the same type, |
1037 // initializes backing store using memove. | 1037 // initializes backing store using memove. |
1038 // | 1038 // |
1039 // Returns true if backing store was initialized or false otherwise. | 1039 // Returns true if backing store was initialized or false otherwise. |
1040 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { | 1040 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { |
1041 HandleScope scope(isolate); | 1041 HandleScope scope(isolate); |
1042 ASSERT(args.length() == 4); | 1042 ASSERT(args.length() == 4); |
1043 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | 1043 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
1044 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | 1044 CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
1045 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); | 1045 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); |
1046 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); | 1046 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); |
1047 | 1047 |
1048 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && | 1048 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && |
1049 arrayId <= Runtime::ARRAY_ID_LAST); | 1049 arrayId <= Runtime::ARRAY_ID_LAST); |
1050 | 1050 |
1051 ASSERT(holder->GetInternalFieldCount() == | |
1052 v8::ArrayBufferView::kInternalFieldCount); | |
1053 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | |
1054 holder->SetInternalField(i, Smi::FromInt(0)); | |
1055 } | |
1056 | |
1057 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | 1051 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
1058 size_t element_size = 1; // Bogus initialization. | 1052 size_t element_size = 1; // Bogus initialization. |
1059 ElementsKind external_elements_kind = | 1053 ElementsKind external_elements_kind = |
1060 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. | 1054 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. |
1061 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 1055 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
1062 Runtime::ArrayIdToTypeAndSize(arrayId, | 1056 Runtime::ArrayIdToTypeAndSize(arrayId, |
1063 &array_type, | 1057 &array_type, |
1064 &external_elements_kind, | 1058 &external_elements_kind, |
1065 &fixed_elements_kind, | 1059 &fixed_elements_kind, |
1066 &element_size); | 1060 &element_size); |
1067 | 1061 |
1068 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 1062 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
1069 | 1063 |
1070 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 1064 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
1071 if (source->IsJSTypedArray() && | 1065 if (source->IsJSTypedArray() && |
1072 JSTypedArray::cast(*source)->type() == array_type) { | 1066 JSTypedArray::cast(*source)->type() == array_type) { |
1073 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); | 1067 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); |
1074 } | 1068 } |
1075 size_t length = 0; | 1069 size_t length = 0; |
1076 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); | 1070 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); |
1077 | 1071 |
1078 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || | 1072 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || |
1079 (length > (kMaxInt / element_size))) { | 1073 (length > (kMaxInt / element_size))) { |
1080 return isolate->Throw(*isolate->factory()-> | 1074 return isolate->Throw(*isolate->factory()-> |
1081 NewRangeError("invalid_typed_array_length", | 1075 NewRangeError("invalid_typed_array_length", |
1082 HandleVector<Object>(NULL, 0))); | 1076 HandleVector<Object>(NULL, 0))); |
1083 } | 1077 } |
1084 size_t byte_length = length * element_size; | 1078 size_t byte_length = length * element_size; |
1085 | 1079 |
1080 ASSERT(holder->GetInternalFieldCount() == | |
1081 v8::ArrayBufferView::kInternalFieldCount); | |
1082 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | |
1083 holder->SetInternalField(i, Smi::FromInt(0)); | |
1084 } | |
1085 | |
1086 // NOTE: not initializing backing store. | 1086 // NOTE: not initializing backing store. |
1087 // We assume that the caller of this function will initialize holder | 1087 // We assume that the caller of this function will initialize holder |
1088 // with the loop | 1088 // with the loop |
1089 // for(i = 0; i < length; i++) { holder[i] = source[i]; } | 1089 // for(i = 0; i < length; i++) { holder[i] = source[i]; } |
1090 // We assume that the caller of this function is always a typed array | 1090 // We assume that the caller of this function is always a typed array |
1091 // constructor. | 1091 // constructor. |
1092 // If source is a typed array, this loop will always run to completion, | 1092 // If source is a typed array, this loop will always run to completion, |
1093 // so we are sure that the backing store will be initialized. | 1093 // so we are sure that the backing store will be initialized. |
1094 // Otherwise, the indexing operation might throw, so the loop will not | 1094 // Otherwise, the indexing operation might throw, so the loop will not |
1095 // run to completion and the typed array might remain partly initialized. | 1095 // run to completion and the typed array might remain partly initialized. |
(...skipping 14105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15201 } | 15201 } |
15202 return NULL; | 15202 return NULL; |
15203 } | 15203 } |
15204 | 15204 |
15205 | 15205 |
15206 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15206 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15207 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15207 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15208 } | 15208 } |
15209 | 15209 |
15210 } } // namespace v8::internal | 15210 } } // namespace v8::internal |
OLD | NEW |