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/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 static void LengthCheck(intptr_t len, intptr_t max) { | 34 static void LengthCheck(intptr_t len, intptr_t max) { |
35 if (len < 0 || len > max) { | 35 if (len < 0 || len > max) { |
36 const String& error = String::Handle(String::NewFormatted( | 36 const String& error = String::Handle(String::NewFormatted( |
37 "Length (%" Pd ") of object must be in range [0..%" Pd "]", | 37 "Length (%" Pd ") of object must be in range [0..%" Pd "]", |
38 len, max)); | 38 len, max)); |
39 Exceptions::ThrowArgumentError(error); | 39 Exceptions::ThrowArgumentError(error); |
40 } | 40 } |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 static void PeerFinalizer(void* isolate_callback_data, | |
45 Dart_WeakPersistentHandle handle, | |
46 void* peer) { | |
47 OS::AlignedFree(peer); | |
48 } | |
49 | |
50 | |
51 DEFINE_NATIVE_ENTRY(TypedData_length, 1) { | 44 DEFINE_NATIVE_ENTRY(TypedData_length, 1) { |
52 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); | 45 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); |
53 if (instance.IsTypedData()) { | 46 if (instance.IsTypedData()) { |
54 const TypedData& array = TypedData::Cast(instance); | 47 const TypedData& array = TypedData::Cast(instance); |
55 return Smi::New(array.Length()); | 48 return Smi::New(array.Length()); |
56 } | 49 } |
57 if (instance.IsExternalTypedData()) { | 50 if (instance.IsExternalTypedData()) { |
58 const ExternalTypedData& array = ExternalTypedData::Cast(instance); | 51 const ExternalTypedData& array = ExternalTypedData::Cast(instance); |
59 return Smi::New(array.Length()); | 52 return Smi::New(array.Length()); |
60 } | 53 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) { \ | 161 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) { \ |
169 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \ | 162 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \ |
170 intptr_t cid = kTypedData##name##Cid; \ | 163 intptr_t cid = kTypedData##name##Cid; \ |
171 intptr_t len = length.Value(); \ | 164 intptr_t len = length.Value(); \ |
172 intptr_t max = TypedData::MaxElements(cid); \ | 165 intptr_t max = TypedData::MaxElements(cid); \ |
173 LengthCheck(len, max); \ | 166 LengthCheck(len, max); \ |
174 return TypedData::New(cid, len); \ | 167 return TypedData::New(cid, len); \ |
175 } \ | 168 } \ |
176 | 169 |
177 | 170 |
178 // We check the length parameter against a possible maximum length for the | |
179 // array based on available physical addressable memory on the system. The | |
180 // maximum possible length is a scaled value of kSmiMax which is set up based | |
181 // on whether the underlying architecture is 32-bit or 64-bit. | |
182 // Argument 0 is type arguments and is ignored. | |
183 #define EXT_TYPED_DATA_NEW(name) \ | |
184 DEFINE_NATIVE_ENTRY(ExternalTypedData_##name##_new, 2) { \ | |
185 const int kAlignment = 16; \ | |
186 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \ | |
187 intptr_t cid = kExternalTypedData##name##Cid; \ | |
188 intptr_t len = length.Value(); \ | |
189 intptr_t max = ExternalTypedData::MaxElements(cid); \ | |
190 LengthCheck(len, max); \ | |
191 intptr_t len_bytes = len * ExternalTypedData::ElementSizeInBytes(cid); \ | |
192 uint8_t* data = OS::AllocateAlignedArray<uint8_t>(len_bytes, kAlignment); \ | |
193 const ExternalTypedData& obj = \ | |
194 ExternalTypedData::Handle(ExternalTypedData::New(cid, data, len)); \ | |
195 obj.AddFinalizer(data, PeerFinalizer); \ | |
196 return obj.raw(); \ | |
197 } \ | |
198 | |
199 | |
200 #define TYPED_DATA_NEW_NATIVE(name) \ | 171 #define TYPED_DATA_NEW_NATIVE(name) \ |
201 TYPED_DATA_NEW(name) \ | 172 TYPED_DATA_NEW(name) \ |
202 EXT_TYPED_DATA_NEW(name) \ | |
203 | 173 |
204 | 174 |
205 CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE) | 175 CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE) |
206 | 176 |
207 #define TYPED_DATA_GETTER(getter, object, ctor, access_size) \ | 177 #define TYPED_DATA_GETTER(getter, object, ctor, access_size) \ |
208 DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) { \ | 178 DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) { \ |
209 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ | 179 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ |
210 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ | 180 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ |
211 if (instance.IsTypedData()) { \ | 181 if (instance.IsTypedData()) { \ |
212 const TypedData& array = TypedData::Cast(instance); \ | 182 const TypedData& array = TypedData::Cast(instance); \ |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 value = bit_cast<double>( | 362 value = bit_cast<double>( |
393 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); | 363 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); |
394 } else { | 364 } else { |
395 value = bit_cast<double>( | 365 value = bit_cast<double>( |
396 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); | 366 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); |
397 } | 367 } |
398 return Double::New(value); | 368 return Double::New(value); |
399 } | 369 } |
400 | 370 |
401 } // namespace dart | 371 } // namespace dart |
OLD | NEW |