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" | |
10 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
11 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
12 #include "vm/object.h" | 11 #include "vm/object.h" |
13 | 12 |
14 namespace dart { | 13 namespace dart { |
15 | 14 |
16 // TypedData. | 15 // TypedData. |
17 | 16 |
18 // Checks to see if offsetInBytes + num_bytes is in the range. | 17 // Checks to see if offsetInBytes + num_bytes is in the range. |
19 static void RangeCheck(intptr_t offset_in_bytes, | 18 static void RangeCheck(intptr_t offset_in_bytes, |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 const String& error = String::Handle(String::NewFormatted( \ | 272 const String& error = String::Handle(String::NewFormatted( \ |
274 "Expected a TypedData object but found %s", instance.ToCString())); \ | 273 "Expected a TypedData object but found %s", instance.ToCString())); \ |
275 Exceptions::ThrowArgumentError(error); \ | 274 Exceptions::ThrowArgumentError(error); \ |
276 } \ | 275 } \ |
277 return Integer::NewFromUint64(value); \ | 276 return Integer::NewFromUint64(value); \ |
278 } \ | 277 } \ |
279 | 278 |
280 | 279 |
281 // TODO(asiva): Consider truncating the bigint value if it does not fit into | 280 // TODO(asiva): Consider truncating the bigint value if it does not fit into |
282 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))). | 281 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))). |
| 282 // TODO(regis): Shouldn't we throw an argument error if the bigint is too large |
| 283 // instead of assert faulting or truncating the bigint as suggested? |
283 #define TYPED_DATA_UINT64_SETTER(setter, object) \ | 284 #define TYPED_DATA_UINT64_SETTER(setter, object) \ |
284 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ | 285 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ |
285 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ | 286 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ |
286 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ | 287 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ |
287 GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2)); \ | 288 GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2)); \ |
288 uint64_t object_value; \ | 289 uint64_t object_value; \ |
289 if (value.IsBigint()) { \ | 290 if (value.IsBigint()) { \ |
290 const Bigint& bigint = Bigint::Cast(value); \ | 291 const Bigint& bigint = Bigint::Cast(value); \ |
291 ASSERT(BigintOperations::FitsIntoUint64(bigint)); \ | 292 ASSERT(bigint.FitsIntoUint64()); \ |
292 object_value = BigintOperations::AbsToUint64(bigint); \ | 293 object_value = bigint.AsUint64Value(); \ |
293 } else { \ | 294 } else { \ |
294 ASSERT(value.IsMint() || value.IsSmi()); \ | 295 ASSERT(value.IsMint() || value.IsSmi()); \ |
295 object_value = value.AsInt64Value(); \ | 296 object_value = value.AsInt64Value(); \ |
296 } \ | 297 } \ |
297 if (instance.IsTypedData()) { \ | 298 if (instance.IsTypedData()) { \ |
298 const TypedData& array = TypedData::Cast(instance); \ | 299 const TypedData& array = TypedData::Cast(instance); \ |
299 RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \ | 300 RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \ |
300 array.setter(offsetInBytes.Value(), object_value); \ | 301 array.setter(offsetInBytes.Value(), object_value); \ |
301 } else if (instance.IsExternalTypedData()) { \ | 302 } else if (instance.IsExternalTypedData()) { \ |
302 const ExternalTypedData& array = ExternalTypedData::Cast(instance); \ | 303 const ExternalTypedData& array = ExternalTypedData::Cast(instance); \ |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 return Integer::New(value); | 409 return Integer::New(value); |
409 } | 410 } |
410 | 411 |
411 | 412 |
412 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { | 413 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { |
413 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 414 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
414 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 415 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
415 uint64_t value; | 416 uint64_t value; |
416 if (host_value.IsBigint()) { | 417 if (host_value.IsBigint()) { |
417 const Bigint& bigint = Bigint::Cast(host_value); | 418 const Bigint& bigint = Bigint::Cast(host_value); |
418 ASSERT(BigintOperations::FitsIntoUint64(bigint)); | 419 ASSERT(bigint.FitsIntoUint64()); |
419 value = BigintOperations::AbsToUint64(bigint); | 420 value = bigint.AsUint64Value(); |
420 } else { | 421 } else { |
421 ASSERT(host_value.IsMint() || host_value.IsSmi()); | 422 ASSERT(host_value.IsMint() || host_value.IsSmi()); |
422 value = host_value.AsInt64Value(); | 423 value = host_value.AsInt64Value(); |
423 } | 424 } |
424 if (little_endian.value()) { | 425 if (little_endian.value()) { |
425 value = Utils::HostToLittleEndian64(value); | 426 value = Utils::HostToLittleEndian64(value); |
426 } else { | 427 } else { |
427 value = Utils::HostToBigEndian64(value); | 428 value = Utils::HostToBigEndian64(value); |
428 } | 429 } |
429 return Integer::NewFromUint64(value); | 430 return Integer::NewFromUint64(value); |
(...skipping 23 matching lines...) Expand all Loading... |
453 value = bit_cast<double>( | 454 value = bit_cast<double>( |
454 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); | 455 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); |
455 } else { | 456 } else { |
456 value = bit_cast<double>( | 457 value = bit_cast<double>( |
457 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); | 458 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); |
458 } | 459 } |
459 return Double::New(value); | 460 return Double::New(value); |
460 } | 461 } |
461 | 462 |
462 } // namespace dart | 463 } // namespace dart |
OLD | NEW |