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

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

Issue 21876005: Fixes obo error in javascript int checking. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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) 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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | tests/standalone/javascript_int_overflow_literal_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698