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

Side by Side Diff: runtime/vm/object.cc

Issue 16664003: Improvements to 53-bit overflow checking. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 10394 matching lines...) Expand 10 before | Expand all | Expand 10 after
10405 } 10405 }
10406 10406
10407 10407
10408 const char* Integer::ToCString() const { 10408 const char* Integer::ToCString() const {
10409 // Integer is an interface. No instances of Integer should exist. 10409 // Integer is an interface. No instances of Integer should exist.
10410 UNREACHABLE(); 10410 UNREACHABLE();
10411 return "Integer"; 10411 return "Integer";
10412 } 10412 }
10413 10413
10414 10414
10415 // Throw FiftyThreeBitOverflow exception.
10416 static void ThrowFiftyThreeBitOverflow(const Integer& i) {
10417 const Array& exc_args = Array::Handle(Array::New(1));
10418 exc_args.SetAt(0, i);
10419 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
10420 }
10421
10422
10415 RawInteger* Integer::New(const String& str, Heap::Space space) { 10423 RawInteger* Integer::New(const String& str, Heap::Space space) {
10416 // We are not supposed to have integers represented as two byte strings. 10424 // We are not supposed to have integers represented as two byte strings.
10417 ASSERT(str.IsOneByteString()); 10425 ASSERT(str.IsOneByteString());
10418 int64_t value; 10426 int64_t value;
10419 if (!OS::StringToInt64(str.ToCString(), &value)) { 10427 if (!OS::StringToInt64(str.ToCString(), &value)) {
10420 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); 10428 const Bigint& big = Bigint::Handle(Bigint::New(str, space));
10421 ASSERT(!BigintOperations::FitsIntoSmi(big)); 10429 ASSERT(!BigintOperations::FitsIntoSmi(big));
10422 ASSERT(!BigintOperations::FitsIntoInt64(big)); 10430 ASSERT(!BigintOperations::FitsIntoInt64(big));
10431 if (FLAG_throw_on_javascript_int_overflow) {
10432 ThrowFiftyThreeBitOverflow(big);
10433 }
10423 return big.raw(); 10434 return big.raw();
10424 } 10435 }
10425 return Integer::New(value, space); 10436 return Integer::New(value, space);
10426 } 10437 }
10427 10438
10428 10439
10440 // This is called from LiteralToken::New() in the parser, so we can't
10441 // raise an exception for 53-bit overflow here. Instead we do it in
10442 // Parser::CurrentIntegerLiteral(), which is the point in the parser where
10443 // integer literals escape, so we can call Parser::ErrorMsg().
10429 RawInteger* Integer::NewCanonical(const String& str) { 10444 RawInteger* Integer::NewCanonical(const String& str) {
10430 // We are not supposed to have integers represented as two byte strings. 10445 // We are not supposed to have integers represented as two byte strings.
10431 ASSERT(str.IsOneByteString()); 10446 ASSERT(str.IsOneByteString());
10432 int64_t value; 10447 int64_t value;
10433 if (!OS::StringToInt64(str.ToCString(), &value)) { 10448 if (!OS::StringToInt64(str.ToCString(), &value)) {
10434 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); 10449 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str));
10435 ASSERT(!BigintOperations::FitsIntoSmi(big)); 10450 ASSERT(!BigintOperations::FitsIntoSmi(big));
10436 ASSERT(!BigintOperations::FitsIntoInt64(big)); 10451 ASSERT(!BigintOperations::FitsIntoInt64(big));
10437 return big.raw(); 10452 return big.raw();
10438 } 10453 }
10439 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { 10454 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
10440 return Smi::New(value); 10455 return Smi::New(value);
10441 } 10456 }
10442 return Mint::NewCanonical(value); 10457 return Mint::NewCanonical(value);
10443 } 10458 }
10444 10459
10445 10460
10446 // Throw FiftyThreeBitOverflow exception.
10447 static void ThrowFiftyThreeBitOverflow(const Integer& i) {
10448 const Array& exc_args = Array::Handle(Array::New(1));
10449 exc_args.SetAt(0, i);
10450 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
10451 }
10452
10453
10454 RawInteger* Integer::New(int64_t value, Heap::Space space) { 10461 RawInteger* Integer::New(int64_t value, Heap::Space space) {
10455 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { 10462 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
10456 return Smi::New(value); 10463 return Smi::New(value);
10457 } 10464 }
10458 if (FLAG_throw_on_javascript_int_overflow && !Utils::IsInt(53, value)) { 10465 if (FLAG_throw_on_javascript_int_overflow && !Utils::IsInt(53, value)) {
10459 const Integer &i = Integer::Handle(Mint::New(value)); 10466 const Integer &i = Integer::Handle(Mint::New(value));
10460 ThrowFiftyThreeBitOverflow(i); 10467 ThrowFiftyThreeBitOverflow(i);
10461 } 10468 }
10462 return Mint::New(value, space); 10469 return Mint::New(value, space);
10463 } 10470 }
(...skipping 24 matching lines...) Expand all
10488 return 0; 10495 return 0;
10489 } 10496 }
10490 10497
10491 10498
10492 int Integer::CompareWith(const Integer& other) const { 10499 int Integer::CompareWith(const Integer& other) const {
10493 UNIMPLEMENTED(); 10500 UNIMPLEMENTED();
10494 return 0; 10501 return 0;
10495 } 10502 }
10496 10503
10497 10504
10498 static void CheckFiftyThreeBitOverflow(const Integer &i) { 10505 // Returns true if the signed Integer requires more than 53 bits.
10506 bool Integer::CheckFiftyThreeBitOverflow() const {
10499 // Always overflow if the value doesn't fit into an int64_t. 10507 // Always overflow if the value doesn't fit into an int64_t.
10500 int64_t value = 1ULL << 63; 10508 int64_t value = 1ULL << 63;
10501 if (i.IsSmi()) { 10509 if (IsSmi()) {
10502 value = i.AsInt64Value(); 10510 value = AsInt64Value();
10503 } else if (i.IsMint()) { 10511 } else if (IsMint()) {
10504 Mint& mint = Mint::Handle(); 10512 Mint& mint = Mint::Handle();
10505 mint ^= i.raw(); 10513 mint ^= raw();
10506 value = mint.value(); 10514 value = mint.value();
10507 } else { 10515 } else {
10508 ASSERT(i.IsBigint()); 10516 ASSERT(IsBigint());
10509 Bigint& big_value = Bigint::Handle(); 10517 Bigint& big_value = Bigint::Handle();
10510 big_value ^= i.raw(); 10518 big_value ^= raw();
10511 if (BigintOperations::FitsIntoInt64(big_value)) { 10519 if (BigintOperations::FitsIntoInt64(big_value)) {
10512 value = BigintOperations::ToInt64(big_value); 10520 value = BigintOperations::ToInt64(big_value);
10513 } 10521 }
10514 } 10522 }
10515 if (Utils::IsInt(53, value)) return; 10523 return !Utils::IsInt(53, value);
10516 ThrowFiftyThreeBitOverflow(i);
10517 } 10524 }
10518 10525
10519 10526
10520 RawInteger* Integer::AsValidInteger() const { 10527 RawInteger* Integer::AsValidInteger() const {
10521 if (FLAG_throw_on_javascript_int_overflow) { 10528 if (FLAG_throw_on_javascript_int_overflow &&
10522 CheckFiftyThreeBitOverflow(*this); 10529 CheckFiftyThreeBitOverflow()) {
10530 ThrowFiftyThreeBitOverflow(*this);
10523 } 10531 }
10524 if (IsSmi()) return raw(); 10532 if (IsSmi()) return raw();
10525 if (IsMint()) { 10533 if (IsMint()) {
10526 Mint& mint = Mint::Handle(); 10534 Mint& mint = Mint::Handle();
10527 mint ^= raw(); 10535 mint ^= raw();
10528 if (Smi::IsValid64(mint.value())) { 10536 if (Smi::IsValid64(mint.value())) {
10529 return Smi::New(mint.value()); 10537 return Smi::New(mint.value());
10530 } else { 10538 } else {
10531 return raw(); 10539 return raw();
10532 } 10540 }
(...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after
13374 space); 13382 space);
13375 return reinterpret_cast<RawWeakProperty*>(raw); 13383 return reinterpret_cast<RawWeakProperty*>(raw);
13376 } 13384 }
13377 13385
13378 13386
13379 const char* WeakProperty::ToCString() const { 13387 const char* WeakProperty::ToCString() const {
13380 return "_WeakProperty"; 13388 return "_WeakProperty";
13381 } 13389 }
13382 13390
13383 } // namespace dart 13391 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698