OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 if (instance.IsExternalTypedData()) { | 58 if (instance.IsExternalTypedData()) { |
59 const ExternalTypedData& array = ExternalTypedData::Cast(instance); | 59 const ExternalTypedData& array = ExternalTypedData::Cast(instance); |
60 return Smi::New(array.Length()); | 60 return Smi::New(array.Length()); |
61 } | 61 } |
62 const String& error = String::Handle(String::NewFormatted( | 62 const String& error = String::Handle(String::NewFormatted( |
63 "Expected a TypedData object but found %s", instance.ToCString())); | 63 "Expected a TypedData object but found %s", instance.ToCString())); |
64 Exceptions::ThrowArgumentError(error); | 64 Exceptions::ThrowArgumentError(error); |
65 return Integer::null(); | 65 return Integer::null(); |
66 } | 66 } |
67 | 67 |
| 68 |
68 template <typename DstType, typename SrcType> | 69 template <typename DstType, typename SrcType> |
69 static RawBool* CopyData(const Instance& dst, const Instance& src, | 70 static RawBool* CopyData(const Instance& dst, const Instance& src, |
70 const Smi& dst_start, const Smi& src_start, | 71 const Smi& dst_start, const Smi& src_start, |
71 const Smi& length) { | 72 const Smi& length) { |
72 const DstType& dst_array = DstType::Cast(dst); | 73 const DstType& dst_array = DstType::Cast(dst); |
73 const SrcType& src_array = SrcType::Cast(src); | 74 const SrcType& src_array = SrcType::Cast(src); |
74 intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes(); | 75 const intptr_t dst_offset_in_bytes = dst_start.Value(); |
75 intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes; | 76 const intptr_t src_offset_in_bytes = src_start.Value(); |
76 intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes; | 77 const intptr_t length_in_bytes = length.Value(); |
77 intptr_t length_in_bytes = length.Value() * element_size_in_bytes; | |
78 if (dst_array.ElementType() != src_array.ElementType()) { | 78 if (dst_array.ElementType() != src_array.ElementType()) { |
79 return Bool::False().raw(); | 79 return Bool::False().raw(); |
80 } | 80 } |
81 RangeCheck(src_offset_in_bytes, | 81 ASSERT(Utils::RangeCheck( |
82 length_in_bytes, | 82 src_offset_in_bytes, length_in_bytes, src_array.LengthInBytes())); |
83 src_array.LengthInBytes(), | 83 ASSERT(Utils::RangeCheck( |
84 element_size_in_bytes); | 84 dst_offset_in_bytes, length_in_bytes, dst_array.LengthInBytes())); |
85 RangeCheck(dst_offset_in_bytes, | |
86 length_in_bytes, | |
87 dst_array.LengthInBytes(), | |
88 element_size_in_bytes); | |
89 TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes, | 85 TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes, |
90 src_array, src_offset_in_bytes, | 86 src_array, src_offset_in_bytes, |
91 length_in_bytes); | 87 length_in_bytes); |
92 return Bool::True().raw(); | 88 return Bool::True().raw(); |
93 } | 89 } |
94 | 90 |
95 | |
96 DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) { | 91 DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) { |
97 GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0)); | 92 GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0)); |
98 GET_NON_NULL_NATIVE_ARGUMENT(Smi, dst_start, arguments->NativeArgAt(1)); | 93 GET_NON_NULL_NATIVE_ARGUMENT(Smi, dst_start, arguments->NativeArgAt(1)); |
99 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(2)); | 94 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(2)); |
100 GET_NON_NULL_NATIVE_ARGUMENT(Instance, src, arguments->NativeArgAt(3)); | 95 GET_NON_NULL_NATIVE_ARGUMENT(Instance, src, arguments->NativeArgAt(3)); |
101 GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(4)); | 96 GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(4)); |
102 | 97 |
103 if (length.Value() < 0) { | 98 if (length.Value() < 0) { |
104 const String& error = String::Handle(String::NewFormatted( | 99 const String& error = String::Handle(String::NewFormatted( |
105 "length (%" Pd ") must be non-negative", length.Value())); | 100 "length (%" Pd ") must be non-negative", length.Value())); |
106 Exceptions::ThrowArgumentError(error); | 101 Exceptions::ThrowArgumentError(error); |
107 } | 102 } |
108 if (dst.IsTypedData()) { | 103 if (dst.IsTypedData()) { |
109 if (src.IsTypedData()) { | 104 if (src.IsTypedData()) { |
110 return CopyData<TypedData, TypedData>( | 105 return CopyData<TypedData, TypedData>( |
111 dst, src, dst_start, src_start, length); | 106 dst, src, dst_start, src_start, length); |
112 } else if (src.IsExternalTypedData()) { | 107 } else if (src.IsExternalTypedData()) { |
113 return CopyData<TypedData, ExternalTypedData>( | 108 return CopyData<TypedData, ExternalTypedData>( |
114 dst, src, dst_start, src_start, length); | 109 dst, src, dst_start, src_start, length); |
115 } | 110 } |
116 } else if (dst.IsExternalTypedData()) { | 111 } else if (dst.IsExternalTypedData()) { |
117 if (src.IsTypedData()) { | 112 if (src.IsTypedData()) { |
118 return CopyData<ExternalTypedData, TypedData>( | 113 return CopyData<ExternalTypedData, TypedData>( |
119 dst, src, dst_start, src_start, length); | 114 dst, src, dst_start, src_start, length); |
120 } else if (src.IsExternalTypedData()) { | 115 } else if (src.IsExternalTypedData()) { |
121 return CopyData<ExternalTypedData, ExternalTypedData>( | 116 return CopyData<ExternalTypedData, ExternalTypedData>( |
122 dst, src, dst_start, src_start, length); | 117 dst, src, dst_start, src_start, length); |
123 } | 118 } |
124 } | 119 } |
| 120 UNREACHABLE(); |
125 return Bool::False().raw(); | 121 return Bool::False().raw(); |
126 } | 122 } |
127 | 123 |
128 | |
129 // We check the length parameter against a possible maximum length for the | 124 // We check the length parameter against a possible maximum length for the |
130 // array based on available physical addressable memory on the system. The | 125 // array based on available physical addressable memory on the system. The |
131 // maximum possible length is a scaled value of kSmiMax which is set up based | 126 // maximum possible length is a scaled value of kSmiMax which is set up based |
132 // on whether the underlying architecture is 32-bit or 64-bit. | 127 // on whether the underlying architecture is 32-bit or 64-bit. |
133 #define TYPED_DATA_NEW(name) \ | 128 #define TYPED_DATA_NEW(name) \ |
134 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 1) { \ | 129 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 1) { \ |
135 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); \ | 130 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); \ |
136 intptr_t cid = kTypedData##name##Cid; \ | 131 intptr_t cid = kTypedData##name##Cid; \ |
137 intptr_t len = length.Value(); \ | 132 intptr_t len = length.Value(); \ |
138 intptr_t max = TypedData::MaxElements(cid); \ | 133 intptr_t max = TypedData::MaxElements(cid); \ |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 value = bit_cast<double>( | 403 value = bit_cast<double>( |
409 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); | 404 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); |
410 } else { | 405 } else { |
411 value = bit_cast<double>( | 406 value = bit_cast<double>( |
412 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); | 407 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); |
413 } | 408 } |
414 return Double::New(value); | 409 return Double::New(value); |
415 } | 410 } |
416 | 411 |
417 } // namespace dart | 412 } // namespace dart |
OLD | NEW |