| 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 |