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 |