| OLD | NEW |
| 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 11389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11400 if (FLAG_throw_on_javascript_int_overflow) { | 11400 if (FLAG_throw_on_javascript_int_overflow) { |
| 11401 ThrowJavascriptIntegerOverflow(big); | 11401 ThrowJavascriptIntegerOverflow(big); |
| 11402 } | 11402 } |
| 11403 return big.raw(); | 11403 return big.raw(); |
| 11404 } | 11404 } |
| 11405 return Integer::New(value, space); | 11405 return Integer::New(value, space); |
| 11406 } | 11406 } |
| 11407 | 11407 |
| 11408 | 11408 |
| 11409 // This is called from LiteralToken::New() in the parser, so we can't | 11409 // This is called from LiteralToken::New() in the parser, so we can't |
| 11410 // raise an exception for 54-bit overflow here. Instead we do it in | 11410 // raise an exception for javascript overflow here. Instead we do it in |
| 11411 // Parser::CurrentIntegerLiteral(), which is the point in the parser where | 11411 // Parser::CurrentIntegerLiteral(), which is the point in the parser where |
| 11412 // integer literals escape, so we can call Parser::ErrorMsg(). | 11412 // integer literals escape, so we can call Parser::ErrorMsg(). |
| 11413 RawInteger* Integer::NewCanonical(const String& str) { | 11413 RawInteger* Integer::NewCanonical(const String& str) { |
| 11414 // We are not supposed to have integers represented as two byte strings. | 11414 // We are not supposed to have integers represented as two byte strings. |
| 11415 ASSERT(str.IsOneByteString()); | 11415 ASSERT(str.IsOneByteString()); |
| 11416 int64_t value; | 11416 int64_t value; |
| 11417 if (!OS::StringToInt64(str.ToCString(), &value)) { | 11417 if (!OS::StringToInt64(str.ToCString(), &value)) { |
| 11418 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); | 11418 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); |
| 11419 ASSERT(!BigintOperations::FitsIntoSmi(big)); | 11419 ASSERT(!BigintOperations::FitsIntoSmi(big)); |
| 11420 ASSERT(!BigintOperations::FitsIntoInt64(big)); | 11420 ASSERT(!BigintOperations::FitsIntoInt64(big)); |
| 11421 return big.raw(); | 11421 return big.raw(); |
| 11422 } | 11422 } |
| 11423 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { | 11423 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| 11424 return Smi::New(value); | 11424 return Smi::New(value); |
| 11425 } | 11425 } |
| 11426 return Mint::NewCanonical(value); | 11426 return Mint::NewCanonical(value); |
| 11427 } | 11427 } |
| 11428 | 11428 |
| 11429 | 11429 |
| 11430 // dart2js represents integers as double precision floats. It does this using | 11430 // dart2js represents integers as double precision floats, which can represent |
| 11431 // a sign bit and 53 fraction bits. This gives us the range | 11431 // anything in the range -2^53 ... 2^53. |
| 11432 // -2^54 - 1 ... 2^54 - 1, i.e. the same as a 54-bit signed integer | 11432 static bool IsJavascriptInt(int64_t value) { |
| 11433 // without the most negative number. Thus, here we check if the value is | 11433 return ((-0x20000000000000LL <= value) && (value <= 0x20000000000000LL)); |
| 11434 // a 54-bit signed integer and not -2^54 | |
| 11435 static bool Is54BitNoMinInt(int64_t value) { | |
| 11436 return (Utils::IsInt(54, value)) && (value != (-0x1FFFFFFFFFFFFFLL - 1)); | |
| 11437 } | 11434 } |
| 11438 | 11435 |
| 11439 | 11436 |
| 11440 RawInteger* Integer::New(int64_t value, Heap::Space space) { | 11437 RawInteger* Integer::New(int64_t value, Heap::Space space) { |
| 11441 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { | 11438 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| 11442 return Smi::New(value); | 11439 return Smi::New(value); |
| 11443 } | 11440 } |
| 11444 if (FLAG_throw_on_javascript_int_overflow && !Is54BitNoMinInt(value)) { | 11441 if (FLAG_throw_on_javascript_int_overflow && !IsJavascriptInt(value)) { |
| 11445 const Integer &i = Integer::Handle(Mint::New(value)); | 11442 const Integer &i = Integer::Handle(Mint::New(value)); |
| 11446 ThrowJavascriptIntegerOverflow(i); | 11443 ThrowJavascriptIntegerOverflow(i); |
| 11447 } | 11444 } |
| 11448 return Mint::New(value, space); | 11445 return Mint::New(value, space); |
| 11449 } | 11446 } |
| 11450 | 11447 |
| 11451 | 11448 |
| 11452 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { | 11449 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |
| 11453 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 11450 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
| 11454 if (FLAG_throw_on_javascript_int_overflow) { | 11451 if (FLAG_throw_on_javascript_int_overflow) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 11475 } | 11472 } |
| 11476 | 11473 |
| 11477 | 11474 |
| 11478 int Integer::CompareWith(const Integer& other) const { | 11475 int Integer::CompareWith(const Integer& other) const { |
| 11479 UNIMPLEMENTED(); | 11476 UNIMPLEMENTED(); |
| 11480 return 0; | 11477 return 0; |
| 11481 } | 11478 } |
| 11482 | 11479 |
| 11483 | 11480 |
| 11484 // Returns true if the signed Integer does not fit into a | 11481 // Returns true if the signed Integer does not fit into a |
| 11485 // Javascript (54-bit) integer. | 11482 // Javascript integer. |
| 11486 bool Integer::CheckJavascriptIntegerOverflow() const { | 11483 bool Integer::CheckJavascriptIntegerOverflow() const { |
| 11487 // Always overflow if the value doesn't fit into an int64_t. | 11484 // Always overflow if the value doesn't fit into an int64_t. |
| 11488 int64_t value = 1ULL << 63; | 11485 int64_t value = 1ULL << 63; |
| 11489 if (IsSmi()) { | 11486 if (IsSmi()) { |
| 11490 value = AsInt64Value(); | 11487 value = AsInt64Value(); |
| 11491 } else if (IsMint()) { | 11488 } else if (IsMint()) { |
| 11492 Mint& mint = Mint::Handle(); | 11489 Mint& mint = Mint::Handle(); |
| 11493 mint ^= raw(); | 11490 mint ^= raw(); |
| 11494 value = mint.value(); | 11491 value = mint.value(); |
| 11495 } else { | 11492 } else { |
| 11496 ASSERT(IsBigint()); | 11493 ASSERT(IsBigint()); |
| 11497 Bigint& big_value = Bigint::Handle(); | 11494 Bigint& big_value = Bigint::Handle(); |
| 11498 big_value ^= raw(); | 11495 big_value ^= raw(); |
| 11499 if (BigintOperations::FitsIntoInt64(big_value)) { | 11496 if (BigintOperations::FitsIntoInt64(big_value)) { |
| 11500 value = BigintOperations::ToInt64(big_value); | 11497 value = BigintOperations::ToInt64(big_value); |
| 11501 } | 11498 } |
| 11502 } | 11499 } |
| 11503 return !Is54BitNoMinInt(value); | 11500 return !IsJavascriptInt(value); |
| 11504 } | 11501 } |
| 11505 | 11502 |
| 11506 | 11503 |
| 11507 RawInteger* Integer::AsValidInteger() const { | 11504 RawInteger* Integer::AsValidInteger() const { |
| 11508 if (FLAG_throw_on_javascript_int_overflow && | 11505 if (FLAG_throw_on_javascript_int_overflow && |
| 11509 CheckJavascriptIntegerOverflow()) { | 11506 CheckJavascriptIntegerOverflow()) { |
| 11510 ThrowJavascriptIntegerOverflow(*this); | 11507 ThrowJavascriptIntegerOverflow(*this); |
| 11511 } | 11508 } |
| 11512 if (IsSmi()) return raw(); | 11509 if (IsSmi()) return raw(); |
| 11513 if (IsMint()) { | 11510 if (IsMint()) { |
| (...skipping 3032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14546 } | 14543 } |
| 14547 | 14544 |
| 14548 | 14545 |
| 14549 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 14546 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 14550 stream->OpenObject(); | 14547 stream->OpenObject(); |
| 14551 stream->CloseObject(); | 14548 stream->CloseObject(); |
| 14552 } | 14549 } |
| 14553 | 14550 |
| 14554 | 14551 |
| 14555 } // namespace dart | 14552 } // namespace dart |
| OLD | NEW |