Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: runtime/lib/typed_data.cc

Issue 15743017: Adds a flag to the standalone vm to throw an exception on 53-bit integer overflow. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_53bit_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
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_53bit_overflow && !result.FitsIn53Bits()) { \
267 const Array& exc_args = Array::Handle(Array::New(1)); \
268 exc_args.SetAt(0, Object::Handle(String::New("TypedData_getter"))); \
269 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);\
270 } \
264 return result.raw(); \ 271 return result.raw(); \
265 } \ 272 } \
266 273
267 274
268 // TODO(asiva): Consider truncating the bigint value if it does not fit into 275 // TODO(asiva): Consider truncating the bigint value if it does not fit into
269 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))). 276 // a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))).
270 #define TYPED_DATA_UINT64_SETTER(setter, object) \ 277 #define TYPED_DATA_UINT64_SETTER(setter, object) \
271 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ 278 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \
272 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \ 279 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
273 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \ 280 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 384
378 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) { 385 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) {
379 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); 386 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
380 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); 387 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
381 int64_t value = host_value.AsInt64Value(); 388 int64_t value = host_value.AsInt64Value();
382 if (little_endian.value()) { 389 if (little_endian.value()) {
383 value = Utils::HostToLittleEndian64(value); 390 value = Utils::HostToLittleEndian64(value);
384 } else { 391 } else {
385 value = Utils::HostToBigEndian64(value); 392 value = Utils::HostToBigEndian64(value);
386 } 393 }
387 return Integer::New(value); 394 const Integer& i = Integer::Handle(Integer::New(value));
395 if (FLAG_throw_on_53bit_overflow && !i.FitsIn53Bits()) {
396 const Array& exc_args = Array::Handle(Array::New(1));
397 exc_args.SetAt(0, Object::Handle(String::New("ByteData_ToEndianInt64")));
398 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
399 }
400 return i.AsValidInteger();
siva 2013/05/23 01:28:22 Ditto comment about the AsValidInteger.
zra 2013/05/23 15:59:07 Done.
388 } 401 }
389 402
390 403
391 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { 404 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) {
392 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); 405 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
393 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); 406 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
394 uint64_t value; 407 uint64_t value;
395 if (host_value.IsBigint()) { 408 if (host_value.IsBigint()) {
396 const Bigint& bigint = Bigint::Cast(host_value); 409 const Bigint& bigint = Bigint::Cast(host_value);
397 ASSERT(BigintOperations::FitsIntoUint64(bigint)); 410 ASSERT(BigintOperations::FitsIntoUint64(bigint));
398 value = BigintOperations::AbsToUint64(bigint); 411 value = BigintOperations::AbsToUint64(bigint);
399 } else { 412 } else {
400 ASSERT(host_value.IsMint() || host_value.IsSmi()); 413 ASSERT(host_value.IsMint() || host_value.IsSmi());
401 value = host_value.AsInt64Value(); 414 value = host_value.AsInt64Value();
402 } 415 }
403 if (little_endian.value()) { 416 if (little_endian.value()) {
404 value = Utils::HostToLittleEndian64(value); 417 value = Utils::HostToLittleEndian64(value);
405 } else { 418 } else {
406 value = Utils::HostToBigEndian64(value); 419 value = Utils::HostToBigEndian64(value);
407 } 420 }
408 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { 421 if (value > static_cast<uint64_t>(Mint::kMaxValue)) {
siva 2013/05/23 01:28:22 What about throwing an exception here?
zra 2013/05/23 15:59:07 Yes, I've added a throw here, too.
409 return BigintOperations::NewFromUint64(value); 422 return BigintOperations::NewFromUint64(value);
410 } 423 }
411 return Integer::New(value); 424 const Integer& i = Integer::Handle(Integer::New(value));
425 if (FLAG_throw_on_53bit_overflow && !i.FitsIn53Bits()) {
426 const Array& exc_args = Array::Handle(Array::New(1));
427 exc_args.SetAt(0, Object::Handle(String::New("ByteData_ToEndianUint64")));
428 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
429 }
430 return i.AsValidInteger();
siva 2013/05/23 01:28:22 Ditto comment about AsValidInteger
zra 2013/05/23 15:59:07 Done.
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
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
OLDNEW
« runtime/lib/integers.cc ('K') | « runtime/lib/integers.cc ('k') | runtime/vm/exceptions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698