[VM] Relax constraints for integer literals according to int64 spec
Handling of integer literals is corrected according to the informal spec for the fixed-size integers: https://github.com/dart-lang/sdk/blob/master/docs/language/informal/int64.md This change allows unsigned 64-bit hexadecimal literals and MIN_INT64 to be used when running on the VM with --limit-ints-to-64-bits option. Change-Id: Ied7a7688768bcf4ff40ab5b499dd71622d2c3948 Reviewed-on: https://dart-review.googlesource.com/19400 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
76ea9d3dfd
commit
59cdc65dc7
@@ -75,8 +75,6 @@ static RawInteger* DoubleToInteger(double val, const char* error_msg) {
|
||||
Exceptions::ThrowByType(Exceptions::kUnsupported, args);
|
||||
}
|
||||
if (FLAG_limit_ints_to_64_bits) {
|
||||
// TODO(alexmarkov): decide on the double-to-integer conversion semantics
|
||||
// in truncating mode.
|
||||
int64_t ival = 0;
|
||||
if (val <= static_cast<double>(kMinInt64)) {
|
||||
ival = kMinInt64;
|
||||
|
||||
@@ -167,6 +167,17 @@ test_shl(var v2, var v3, var v8, var v40) {
|
||||
}
|
||||
}
|
||||
|
||||
test_literals() {
|
||||
Expect.equals(0x7fffffffffffffff, 9223372036854775807);
|
||||
Expect.equals(0x8000000000000000, -9223372036854775808);
|
||||
Expect.equals(0x8000000000000000, -0x8000000000000000);
|
||||
Expect.equals(0x8000000000000001, -0x7fffffffffffffff);
|
||||
Expect.equals(0xabcdef0123456789, -0x543210FEDCBA9877);
|
||||
Expect.equals(0xffffffffffffffff, -1);
|
||||
Expect.equals(-9223372036854775808, -0x8000000000000000);
|
||||
Expect.equals(9223372036854775807 + 1, -9223372036854775808);
|
||||
}
|
||||
|
||||
main() {
|
||||
var v2 = 2; // smi
|
||||
var v3 = 3; // smi
|
||||
@@ -181,4 +192,5 @@ main() {
|
||||
test_sub(v2, v3, v3fxx, v5fxx, v7fxx, n60xx);
|
||||
test_mul(v2, v3, v3fxx, v5fxx, v7fxx, n60xx);
|
||||
test_shl(v2, v3, v8, v40);
|
||||
test_literals();
|
||||
}
|
||||
|
||||
+21
-4
@@ -18313,12 +18313,22 @@ const char* Integer::ToCString() const {
|
||||
return "NULL Integer";
|
||||
}
|
||||
|
||||
// String representation of kMaxInt64 + 1.
|
||||
static const char* kMaxInt64Plus1 = "9223372036854775808";
|
||||
|
||||
RawInteger* Integer::New(const String& str, Heap::Space space) {
|
||||
// We are not supposed to have integers represented as two byte strings.
|
||||
ASSERT(str.IsOneByteString());
|
||||
int64_t value;
|
||||
if (!OS::StringToInt64(str.ToCString(), &value)) {
|
||||
int64_t value = 0;
|
||||
const char* cstr = str.ToCString();
|
||||
if (!OS::StringToInt64(cstr, &value)) {
|
||||
if (FLAG_limit_ints_to_64_bits) {
|
||||
if (strcmp(cstr, kMaxInt64Plus1) == 0) {
|
||||
// Allow MAX_INT64 + 1 integer literal as it can be used as an argument
|
||||
// of unary minus to produce MIN_INT64 value. The value is automatically
|
||||
// wrapped to MIN_INT64.
|
||||
return Integer::New(kMinInt64, space);
|
||||
}
|
||||
// Out of range.
|
||||
return Integer::null();
|
||||
}
|
||||
@@ -18334,9 +18344,16 @@ RawInteger* Integer::New(const String& str, Heap::Space space) {
|
||||
RawInteger* Integer::NewCanonical(const String& str) {
|
||||
// We are not supposed to have integers represented as two byte strings.
|
||||
ASSERT(str.IsOneByteString());
|
||||
int64_t value;
|
||||
if (!OS::StringToInt64(str.ToCString(), &value)) {
|
||||
int64_t value = 0;
|
||||
const char* cstr = str.ToCString();
|
||||
if (!OS::StringToInt64(cstr, &value)) {
|
||||
if (FLAG_limit_ints_to_64_bits) {
|
||||
if (strcmp(cstr, kMaxInt64Plus1) == 0) {
|
||||
// Allow MAX_INT64 + 1 integer literal as it can be used as an argument
|
||||
// of unary minus to produce MIN_INT64 value. The value is automatically
|
||||
// wrapped to MIN_INT64.
|
||||
return Mint::NewCanonical(kMinInt64);
|
||||
}
|
||||
// Out of range.
|
||||
return Integer::null();
|
||||
}
|
||||
|
||||
@@ -353,7 +353,13 @@ bool OS::StringToInt64(const char* str, int64_t* value) {
|
||||
base = 16;
|
||||
}
|
||||
errno = 0;
|
||||
*value = strtoll(str, &endptr, base);
|
||||
if (FLAG_limit_ints_to_64_bits && (base == 16)) {
|
||||
// Unsigned 64-bit hexadecimal integer literals are allowed but
|
||||
// immediately interpreted as signed 64-bit integers.
|
||||
*value = static_cast<int64_t>(strtoull(str, &endptr, base));
|
||||
} else {
|
||||
*value = strtoll(str, &endptr, base);
|
||||
}
|
||||
return ((errno == 0) && (endptr != str) && (*endptr == 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,13 @@ bool OS::StringToInt64(const char* str, int64_t* value) {
|
||||
base = 16;
|
||||
}
|
||||
errno = 0;
|
||||
*value = strtoll(str, &endptr, base);
|
||||
if (FLAG_limit_ints_to_64_bits && (base == 16)) {
|
||||
// Unsigned 64-bit hexadecimal integer literals are allowed but
|
||||
// immediately interpreted as signed 64-bit integers.
|
||||
*value = static_cast<int64_t>(strtoull(str, &endptr, base));
|
||||
} else {
|
||||
*value = strtoll(str, &endptr, base);
|
||||
}
|
||||
return ((errno == 0) && (endptr != str) && (*endptr == 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -339,7 +339,13 @@ bool OS::StringToInt64(const char* str, int64_t* value) {
|
||||
base = 16;
|
||||
}
|
||||
errno = 0;
|
||||
*value = strtoll(str, &endptr, base);
|
||||
if (FLAG_limit_ints_to_64_bits && (base == 16)) {
|
||||
// Unsigned 64-bit hexadecimal integer literals are allowed but
|
||||
// immediately interpreted as signed 64-bit integers.
|
||||
*value = static_cast<int64_t>(strtoull(str, &endptr, base));
|
||||
} else {
|
||||
*value = strtoll(str, &endptr, base);
|
||||
}
|
||||
return ((errno == 0) && (endptr != str) && (*endptr == 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -328,7 +328,13 @@ bool OS::StringToInt64(const char* str, int64_t* value) {
|
||||
base = 16;
|
||||
}
|
||||
errno = 0;
|
||||
*value = strtoll(str, &endptr, base);
|
||||
if (FLAG_limit_ints_to_64_bits && (base == 16)) {
|
||||
// Unsigned 64-bit hexadecimal integer literals are allowed but
|
||||
// immediately interpreted as signed 64-bit integers.
|
||||
*value = static_cast<int64_t>(strtoull(str, &endptr, base));
|
||||
} else {
|
||||
*value = strtoll(str, &endptr, base);
|
||||
}
|
||||
return ((errno == 0) && (endptr != str) && (*endptr == 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -355,7 +355,13 @@ bool OS::StringToInt64(const char* str, int64_t* value) {
|
||||
base = 16;
|
||||
}
|
||||
errno = 0;
|
||||
*value = _strtoi64(str, &endptr, base);
|
||||
if (FLAG_limit_ints_to_64_bits && (base == 16)) {
|
||||
// Unsigned 64-bit hexadecimal integer literals are allowed but
|
||||
// immediately interpreted as signed 64-bit integers.
|
||||
*value = static_cast<int64_t>(_strtoui64(str, &endptr, base));
|
||||
} else {
|
||||
*value = _strtoi64(str, &endptr, base);
|
||||
}
|
||||
return ((errno == 0) && (endptr != str) && (*endptr == 0));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user