Chromium Code Reviews| 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" |
| 11 #include "vm/native_entry.h" | 11 #include "vm/native_entry.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | |
| 17 | |
| 16 // TypedData. | 18 // TypedData. |
| 17 | 19 |
| 18 // Checks to see if offset_in_bytes is in the range. | 20 // Checks to see if offset_in_bytes is in the range. |
| 19 static bool RangeCheck(intptr_t offset_in_bytes, intptr_t length_in_bytes) { | 21 static bool RangeCheck(intptr_t offset_in_bytes, intptr_t length_in_bytes) { |
| 20 return ((offset_in_bytes >= 0) && | 22 return ((offset_in_bytes >= 0) && |
| 21 (length_in_bytes > 0) && | 23 (length_in_bytes > 0) && |
| 22 (offset_in_bytes < length_in_bytes)); | 24 (offset_in_bytes < length_in_bytes)); |
| 23 } | 25 } |
| 24 | 26 |
| 25 | 27 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 const Array& args = Array::Handle(Array::New(1)); \ | 256 const Array& args = Array::Handle(Array::New(1)); \ |
| 255 args.SetAt(0, error); \ | 257 args.SetAt(0, error); \ |
| 256 Exceptions::ThrowByType(Exceptions::kArgument, args); \ | 258 Exceptions::ThrowByType(Exceptions::kArgument, args); \ |
| 257 } \ | 259 } \ |
| 258 Integer& result = Integer::Handle(); \ | 260 Integer& result = Integer::Handle(); \ |
| 259 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { \ | 261 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { \ |
| 260 result = BigintOperations::NewFromUint64(value); \ | 262 result = BigintOperations::NewFromUint64(value); \ |
| 261 } else { \ | 263 } else { \ |
| 262 result = Integer::New(value); \ | 264 result = Integer::New(value); \ |
| 263 } \ | 265 } \ |
| 266 if (FLAG_throw_on_javascript_int_overflow && !result.FitsIn53Bits()) { \ | |
|
siva
2013/05/23 17:38:57
Ditto comment about the FitsIn53Bits check here.
| |
| 267 Integer::CheckForFiftyThreeBitOverflow(result, "TypedData_getter"); \ | |
| 268 } \ | |
| 264 return result.raw(); \ | 269 return result.raw(); \ |
| 265 } \ | 270 } \ |
| 266 | 271 |
| 267 | 272 |
| 268 // TODO(asiva): Consider truncating the bigint value if it does not fit into | 273 // TODO(asiva): Consider truncating the bigint value if it does not fit into |
| 269 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))). | 274 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))). |
| 270 #define TYPED_DATA_UINT64_SETTER(setter, object) \ | 275 #define TYPED_DATA_UINT64_SETTER(setter, object) \ |
| 271 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ | 276 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ |
| 272 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ | 277 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ |
| 273 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ | 278 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 | 382 |
| 378 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) { | 383 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) { |
| 379 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 384 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
| 380 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 385 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
| 381 int64_t value = host_value.AsInt64Value(); | 386 int64_t value = host_value.AsInt64Value(); |
| 382 if (little_endian.value()) { | 387 if (little_endian.value()) { |
| 383 value = Utils::HostToLittleEndian64(value); | 388 value = Utils::HostToLittleEndian64(value); |
| 384 } else { | 389 } else { |
| 385 value = Utils::HostToBigEndian64(value); | 390 value = Utils::HostToBigEndian64(value); |
| 386 } | 391 } |
| 387 return Integer::New(value); | 392 const Integer& i = Integer::Handle(Integer::New(value)); |
| 393 if (FLAG_throw_on_javascript_int_overflow && !i.FitsIn53Bits()) { | |
|
siva
2013/05/23 17:38:57
Ditto comment about the FitsIn53Bits check here.
| |
| 394 Integer::CheckForFiftyThreeBitOverflow(i, "ByteData_ToEndianInt64"); | |
| 395 } | |
| 396 return i.raw(); | |
| 388 } | 397 } |
| 389 | 398 |
| 390 | 399 |
| 391 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { | 400 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { |
| 392 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 401 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
| 393 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 402 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
| 394 uint64_t value; | 403 uint64_t value; |
| 395 if (host_value.IsBigint()) { | 404 if (host_value.IsBigint()) { |
| 396 const Bigint& bigint = Bigint::Cast(host_value); | 405 const Bigint& bigint = Bigint::Cast(host_value); |
| 397 ASSERT(BigintOperations::FitsIntoUint64(bigint)); | 406 ASSERT(BigintOperations::FitsIntoUint64(bigint)); |
| 398 value = BigintOperations::AbsToUint64(bigint); | 407 value = BigintOperations::AbsToUint64(bigint); |
| 399 } else { | 408 } else { |
| 400 ASSERT(host_value.IsMint() || host_value.IsSmi()); | 409 ASSERT(host_value.IsMint() || host_value.IsSmi()); |
| 401 value = host_value.AsInt64Value(); | 410 value = host_value.AsInt64Value(); |
| 402 } | 411 } |
| 403 if (little_endian.value()) { | 412 if (little_endian.value()) { |
| 404 value = Utils::HostToLittleEndian64(value); | 413 value = Utils::HostToLittleEndian64(value); |
| 405 } else { | 414 } else { |
| 406 value = Utils::HostToBigEndian64(value); | 415 value = Utils::HostToBigEndian64(value); |
| 407 } | 416 } |
| 408 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 417 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
| 409 return BigintOperations::NewFromUint64(value); | 418 if (FLAG_throw_on_javascript_int_overflow) { |
| 419 const Array& arg = Array::Handle(Array::New(1)); | |
| 420 arg.SetAt(0, Object::Handle(String::New("ByteData_ToEndianUint64"))); | |
| 421 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, arg); | |
| 422 } else { | |
| 423 return BigintOperations::NewFromUint64(value); | |
| 424 } | |
| 410 } | 425 } |
| 411 return Integer::New(value); | 426 const Integer& i = Integer::Handle(Integer::New(value)); |
| 427 if (FLAG_throw_on_javascript_int_overflow && !i.FitsIn53Bits()) { | |
|
siva
2013/05/23 17:38:57
Ditto comment about FitsIn53Bits check here.
| |
| 428 Integer::CheckForFiftyThreeBitOverflow(i, "ByteData_ToEndianUint64"); | |
| 429 } | |
| 430 return i.raw(); | |
| 412 } | 431 } |
| 413 | 432 |
| 414 | 433 |
| 415 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat32, 2) { | 434 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat32, 2) { |
| 416 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); | 435 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); |
| 417 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 436 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
| 418 float value = host_value.value(); | 437 float value = host_value.value(); |
| 419 if (little_endian.value()) { | 438 if (little_endian.value()) { |
| 420 value = bit_cast<float>( | 439 value = bit_cast<float>( |
| 421 Utils::HostToLittleEndian32(bit_cast<uint32_t>(value))); | 440 Utils::HostToLittleEndian32(bit_cast<uint32_t>(value))); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 435 value = bit_cast<double>( | 454 value = bit_cast<double>( |
| 436 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); | 455 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); |
| 437 } else { | 456 } else { |
| 438 value = bit_cast<double>( | 457 value = bit_cast<double>( |
| 439 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); | 458 Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); |
| 440 } | 459 } |
| 441 return Double::New(value); | 460 return Double::New(value); |
| 442 } | 461 } |
| 443 | 462 |
| 444 } // namespace dart | 463 } // namespace dart |
| OLD | NEW |