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