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 |