| 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 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 HandleScope scope(isolate); | 953 HandleScope scope(isolate); |
| 954 ASSERT(args.length() == 5); | 954 ASSERT(args.length() == 5); |
| 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()); | |
| 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 | 963 |
| 971 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | 964 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
| 972 size_t element_size = 1; // Bogus initialization. | 965 size_t element_size = 1; // Bogus initialization. |
| 973 ElementsKind external_elements_kind = | 966 ElementsKind external_elements_kind = |
| 974 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. | 967 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. |
| 975 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 968 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
| 976 Runtime::ArrayIdToTypeAndSize(arrayId, | 969 Runtime::ArrayIdToTypeAndSize(arrayId, |
| 977 &array_type, | 970 &array_type, |
| 978 &external_elements_kind, | 971 &external_elements_kind, |
| 979 &fixed_elements_kind, | 972 &fixed_elements_kind, |
| 980 &element_size); | 973 &element_size); |
| 981 | |
| 982 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 974 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
| 983 | 975 |
| 984 size_t byte_offset = 0; | 976 size_t byte_offset = 0; |
| 985 size_t byte_length = 0; | 977 size_t byte_length = 0; |
| 986 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); | 978 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); |
| 987 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); | 979 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); |
| 988 | 980 |
| 989 holder->set_byte_offset(*byte_offset_object); | 981 if (maybe_buffer->IsJSArrayBuffer()) { |
| 990 holder->set_byte_length(*byte_length_object); | 982 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
| 983 size_t array_buffer_byte_length = |
| 984 NumberToSize(isolate, buffer->byte_length()); |
| 985 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); |
| 986 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); |
| 987 } else { |
| 988 RUNTIME_ASSERT(maybe_buffer->IsNull()); |
| 989 } |
| 991 | 990 |
| 992 RUNTIME_ASSERT(byte_length % element_size == 0); | 991 RUNTIME_ASSERT(byte_length % element_size == 0); |
| 993 size_t length = byte_length / element_size; | 992 size_t length = byte_length / element_size; |
| 994 | 993 |
| 995 if (length > static_cast<unsigned>(Smi::kMaxValue)) { | 994 if (length > static_cast<unsigned>(Smi::kMaxValue)) { |
| 996 return isolate->Throw( | 995 return isolate->Throw( |
| 997 *isolate->factory()->NewRangeError("invalid_typed_array_length", | 996 *isolate->factory()->NewRangeError("invalid_typed_array_length", |
| 998 HandleVector<Object>(NULL, 0))); | 997 HandleVector<Object>(NULL, 0))); |
| 999 } | 998 } |
| 1000 | 999 |
| 1000 // All checks are done, now we can modify objects. |
| 1001 |
| 1002 ASSERT(holder->GetInternalFieldCount() == |
| 1003 v8::ArrayBufferView::kInternalFieldCount); |
| 1004 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| 1005 holder->SetInternalField(i, Smi::FromInt(0)); |
| 1006 } |
| 1001 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | 1007 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); |
| 1002 holder->set_length(*length_obj); | 1008 holder->set_length(*length_obj); |
| 1009 holder->set_byte_offset(*byte_offset_object); |
| 1010 holder->set_byte_length(*byte_length_object); |
| 1011 |
| 1003 if (!maybe_buffer->IsNull()) { | 1012 if (!maybe_buffer->IsNull()) { |
| 1004 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(*maybe_buffer)); | 1013 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
| 1005 | |
| 1006 size_t array_buffer_byte_length = | |
| 1007 NumberToSize(isolate, buffer->byte_length()); | |
| 1008 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); | |
| 1009 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); | |
| 1010 | |
| 1011 holder->set_buffer(*buffer); | 1014 holder->set_buffer(*buffer); |
| 1012 holder->set_weak_next(buffer->weak_first_view()); | 1015 holder->set_weak_next(buffer->weak_first_view()); |
| 1013 buffer->set_weak_first_view(*holder); | 1016 buffer->set_weak_first_view(*holder); |
| 1014 | 1017 |
| 1015 Handle<ExternalArray> elements = | 1018 Handle<ExternalArray> elements = |
| 1016 isolate->factory()->NewExternalArray( | 1019 isolate->factory()->NewExternalArray( |
| 1017 static_cast<int>(length), array_type, | 1020 static_cast<int>(length), array_type, |
| 1018 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | 1021 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
| 1019 Handle<Map> map = | 1022 Handle<Map> map = |
| 1020 JSObject::GetElementsTransitionMap(holder, external_elements_kind); | 1023 JSObject::GetElementsTransitionMap(holder, external_elements_kind); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1041 HandleScope scope(isolate); | 1044 HandleScope scope(isolate); |
| 1042 ASSERT(args.length() == 4); | 1045 ASSERT(args.length() == 4); |
| 1043 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | 1046 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
| 1044 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | 1047 CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
| 1045 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); | 1048 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); |
| 1046 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); | 1049 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); |
| 1047 | 1050 |
| 1048 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && | 1051 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && |
| 1049 arrayId <= Runtime::ARRAY_ID_LAST); | 1052 arrayId <= Runtime::ARRAY_ID_LAST); |
| 1050 | 1053 |
| 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. | 1054 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
| 1058 size_t element_size = 1; // Bogus initialization. | 1055 size_t element_size = 1; // Bogus initialization. |
| 1059 ElementsKind external_elements_kind = | 1056 ElementsKind external_elements_kind = |
| 1060 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. | 1057 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. |
| 1061 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 1058 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
| 1062 Runtime::ArrayIdToTypeAndSize(arrayId, | 1059 Runtime::ArrayIdToTypeAndSize(arrayId, |
| 1063 &array_type, | 1060 &array_type, |
| 1064 &external_elements_kind, | 1061 &external_elements_kind, |
| 1065 &fixed_elements_kind, | 1062 &fixed_elements_kind, |
| 1066 &element_size); | 1063 &element_size); |
| 1067 | 1064 |
| 1068 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 1065 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
| 1069 | 1066 |
| 1070 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 1067 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| 1071 if (source->IsJSTypedArray() && | 1068 if (source->IsJSTypedArray() && |
| 1072 JSTypedArray::cast(*source)->type() == array_type) { | 1069 JSTypedArray::cast(*source)->type() == array_type) { |
| 1073 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); | 1070 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); |
| 1074 } | 1071 } |
| 1075 size_t length = 0; | 1072 size_t length = 0; |
| 1076 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); | 1073 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); |
| 1077 | 1074 |
| 1078 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || | 1075 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || |
| 1079 (length > (kMaxInt / element_size))) { | 1076 (length > (kMaxInt / element_size))) { |
| 1080 return isolate->Throw(*isolate->factory()-> | 1077 return isolate->Throw(*isolate->factory()-> |
| 1081 NewRangeError("invalid_typed_array_length", | 1078 NewRangeError("invalid_typed_array_length", |
| 1082 HandleVector<Object>(NULL, 0))); | 1079 HandleVector<Object>(NULL, 0))); |
| 1083 } | 1080 } |
| 1084 size_t byte_length = length * element_size; | 1081 size_t byte_length = length * element_size; |
| 1085 | 1082 |
| 1083 ASSERT(holder->GetInternalFieldCount() == |
| 1084 v8::ArrayBufferView::kInternalFieldCount); |
| 1085 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| 1086 holder->SetInternalField(i, Smi::FromInt(0)); |
| 1087 } |
| 1088 |
| 1086 // NOTE: not initializing backing store. | 1089 // NOTE: not initializing backing store. |
| 1087 // We assume that the caller of this function will initialize holder | 1090 // We assume that the caller of this function will initialize holder |
| 1088 // with the loop | 1091 // with the loop |
| 1089 // for(i = 0; i < length; i++) { holder[i] = source[i]; } | 1092 // for(i = 0; i < length; i++) { holder[i] = source[i]; } |
| 1090 // We assume that the caller of this function is always a typed array | 1093 // We assume that the caller of this function is always a typed array |
| 1091 // constructor. | 1094 // constructor. |
| 1092 // If source is a typed array, this loop will always run to completion, | 1095 // 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. | 1096 // so we are sure that the backing store will be initialized. |
| 1094 // Otherwise, the indexing operation might throw, so the loop will not | 1097 // Otherwise, the indexing operation might throw, so the loop will not |
| 1095 // run to completion and the typed array might remain partly initialized. | 1098 // 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 } | 15204 } |
| 15202 return NULL; | 15205 return NULL; |
| 15203 } | 15206 } |
| 15204 | 15207 |
| 15205 | 15208 |
| 15206 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15209 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 15207 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15210 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 15208 } | 15211 } |
| 15209 | 15212 |
| 15210 } } // namespace v8::internal | 15213 } } // namespace v8::internal |
| OLD | NEW |