Treat 64 bit ints as unsigned until conversion to JS.

Change-Id: Idb9c5d4a3562f59bc75a5bb7eef4b7af8f5df992
Reviewed-on: https://dart-review.googlesource.com/57714
Commit-Queue: Emily Fortuna <efortuna@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
Emily Fortuna 2018-06-06 00:28:28 +00:00 committed by commit-bot@chromium.org
parent b375d69800
commit 134e00fd73
15 changed files with 171 additions and 25 deletions

View file

@ -604,7 +604,8 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
@override
ConstantExpression visitIntLiteral(ir.IntLiteral node) {
return new IntConstantExpression(new BigInt.from(node.value));
return new IntConstantExpression(
new BigInt.from(node.value).toUnsigned(64));
}
@override

View file

@ -2634,7 +2634,7 @@ class KernelSsaGraphBuilder extends ir.Visitor
@override
void visitIntLiteral(ir.IntLiteral node) {
stack.add(graph.addConstantInt(node.value, closedWorld));
stack.add(graph.addConstantIntAsUnsigned(node.value, closedWorld));
}
@override

View file

@ -235,8 +235,23 @@ class KernelImpactBuilder extends ir.Visitor {
@override
void visitIntLiteral(ir.IntLiteral literal) {
impactBuilder.registerConstantLiteral(
new IntConstantExpression(new BigInt.from(literal.value)));
// Check that this value can be precisely represented as a double, and throw
// an error if not:
if (new BigInt.from(literal.value) !=
new BigInt.from(literal.value.toDouble())) {
// TODO(efortuna): Switch to error message.
reporter.reportWarningMessage(
CURRENT_ELEMENT_SPANNABLE, MessageKind.GENERIC, {
'text': 'The integer literal '
'${new BigInt.from(literal.value)} cannot be represented'
' exactly in JavaScript and will be rounded to '
'${new BigInt.from(literal.value.toDouble())}. Use the rounded '
'value to avoid this warning.'
});
}
impactBuilder.registerConstantLiteral(new IntConstantExpression(
new BigInt.from(literal.value).toUnsigned(64)));
}
@override

View file

@ -301,6 +301,12 @@ class HGraph {
closedWorld.constantSystem.createIntFromInt(i), closedWorld);
}
HConstant addConstantIntAsUnsigned(int i, JClosedWorld closedWorld) {
return addConstant(
closedWorld.constantSystem.createInt(new BigInt.from(i).toUnsigned(64)),
closedWorld);
}
HConstant addConstantDouble(double d, JClosedWorld closedWorld) {
return addConstant(closedWorld.constantSystem.createDouble(d), closedWorld);
}

View file

@ -7053,6 +7053,7 @@ LayoutTests/fast/canvas/gradient-addColorStop-with-invalid-color_t01: Pass, Runt
LayoutTests/fast/canvas/rgba-parsing_t01: Pass, RuntimeError
LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError
LibTest/core/double/isInfinite_A01_t03: CompileTimeError # Larger than 64 bit int
LibTest/core/double/operator_GE_A01_t02: RuntimeError # WontFix: Not representable in JS.
LibTest/core/int/abs_A01_t01: CompileTimeError # Larger than 64 bit int
LibTest/core/int/ceilToDouble_A01_t01: CompileTimeError # Larger than 64 bit int
LibTest/core/int/ceil_A01_t01: CompileTimeError # Larger than 64 bit int
@ -7105,6 +7106,7 @@ LibTest/html/Window/postMessage_A01_t02: Crash
LibTest/html/Window/requestFileSystem_A01_t01: Crash
LibTest/html/Window/requestFileSystem_A01_t02: Crash
LibTest/html/Window/requestFileSystem_A02_t01: Crash
LibTest/math/pow_A09_t01: RuntimeError # WontFix: Not representable in JS.
LibTest/math/pow_A10_t01: CompileTimeError # Larger than 64 bit int
WebPlatformTest/html/semantics/embedded-content/the-audio-element/audio_constructor_t01: RuntimeError

View file

@ -66,6 +66,7 @@ from_environment_const_type_test/15: Fail # Flutter Issue 9111
from_environment_const_type_test/16: MissingCompileTimeError # Flutter Issue 9111
from_environment_const_type_test/none: Fail # Flutter Issue 9111
int_from_environment2_test: Fail # Flutter Issue 9111
int_from_environment_int64_test: Fail # Flutter Issue 9111
int_from_environment_test: Fail # Flutter Issue 9111
main_test: RuntimeError # Flutter Issue 9111
string_from_environment2_test: Fail # Flutter Issue 9111
@ -212,8 +213,6 @@ symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') sho
cast_test: RuntimeError
error_stack_trace1_test: RuntimeError
growable_list_test: RuntimeError
int_parse_radix_test/01: RuntimeError
int_parse_radix_test/02: RuntimeError
integer_to_radix_string_test/01: RuntimeError
integer_to_radix_string_test/02: RuntimeError
integer_to_radix_string_test/none: RuntimeError
@ -229,15 +228,19 @@ uri_parameters_all_test: RuntimeError
uri_test: RuntimeError
[ $compiler == dart2js && $fasta ]
int_from_environment_test: Pass # Issue 31762
int_parse_radix_test/none: Pass # Issue 31762
int_from_environment_int64_test: RuntimeError # WontFix: Int not precisely representable in JS
int_parse_radix_int64_test/01: RuntimeError # WontFix: Int not precisely representable in JS
int_parse_radix_int64_test/02: RuntimeError # WontFix: Int not precisely representable in JS
int_parse_radix_int64_test/none: RuntimeError # WontFix: Int not precisely representable in JS
int_parse_radix_test/01: RuntimeError
int_parse_radix_test/badTypes: RuntimeError # Issue 33351
int_parse_radix_test/none: RuntimeError # Issue 33351
int_try_parse_int64_test: RuntimeError # WontFix: Int not precisely representable in JS
[ $compiler == dart2js && $fasta && $host_checked && $strong ]
cast_test: RuntimeError
error_stack_trace1_test: RuntimeError # Issue 12399
growable_list_test: RuntimeError # Concurrent modifications test always runs
int_parse_radix_test/01: RuntimeError
int_parse_radix_test/02: RuntimeError
integer_to_radix_string_test/01: RuntimeError
integer_to_radix_string_test/02: RuntimeError
integer_to_radix_string_test/none: RuntimeError
@ -260,7 +263,6 @@ dynamic_nosuchmethod_test: RuntimeError
error_stack_trace1_test: RuntimeError # Issue 12399
growable_list_test: RuntimeError # Concurrent modifications test always runs
hash_set_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(_CustomHashSet.#x), local(_CustomHashSet.#)) for j:closure_call(_CustomHashSet__CustomHashSet_closure.call).
int_parse_radix_test/01: RuntimeError
int_parse_radix_test/02: RuntimeError
integer_to_radix_string_test/01: RuntimeError
integer_to_radix_string_test/02: RuntimeError
@ -414,8 +416,8 @@ date_time10_test: RuntimeError # Issue 29921
error_stack_trace_test/nullThrown: RuntimeError # .stackTrace not present for exception caught from 'throw null;'
hash_set_test/01: RuntimeError # Issue 29921
int_modulo_arith_test/none: RuntimeError # Issue 29921
int_parse_radix_int64_test/02: RuntimeError
int_parse_radix_test/01: RuntimeError # Issue 29921
int_parse_radix_test/02: RuntimeError # Issue 29921
int_parse_with_limited_ints_test: Skip # Requires fixed-size int64 support.
integer_arith_vm_test/modPow: RuntimeError # Issue 30170
integer_parsed_arith_vm_test: RuntimeError # Issue 29921

View file

@ -0,0 +1,11 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// SharedOptions=-Df=-9223372036854775808 -Dg=9223372036854775807
import "package:expect/expect.dart";
main() {
Expect.equals(-9223372036854775808, const int.fromEnvironment('f'));
Expect.equals(9223372036854775807, const int.fromEnvironment('g'));
}

View file

@ -1,7 +1,7 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=-9223372036854775808 -Dg=9223372036854775807
// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=-9007199254740991 -Dg=9007199254740991
import "package:expect/expect.dart";
@ -11,6 +11,6 @@ main() {
Expect.equals(0x123, const int.fromEnvironment('c'));
Expect.equals(-0x1234, const int.fromEnvironment('d'));
Expect.equals(0x112296, const int.fromEnvironment('e'));
Expect.equals(-9223372036854775808, const int.fromEnvironment('f'));
Expect.equals(9223372036854775807, const int.fromEnvironment('g'));
Expect.equals(-9007199254740991, const int.fromEnvironment('f'));
Expect.equals(9007199254740991, const int.fromEnvironment('g'));
}

View file

@ -0,0 +1,68 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
import "dart:math" show pow, log;
void main() {
const String oneByteWhiteSpace = "\x09\x0a\x0b\x0c\x0d\x20"
"\x85" //# 01: ok
"\xa0";
const String whiteSpace = "$oneByteWhiteSpace\u1680"
"\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a"
"\u2028\u2029\u202f\u205f\u3000\ufeff";
var digits = "0123456789abcdefghijklmnopqrstuvwxyz";
var zeros = "0" * 64;
void testParse(int result, String radixString, int radix) {
var m = "$radixString/$radix->$result";
Expect.equals(
result, int.parse(radixString.toLowerCase(), radix: radix), m);
Expect.equals(
result, int.parse(radixString.toUpperCase(), radix: radix), m);
Expect.equals(result, int.parse(" $radixString", radix: radix), m);
Expect.equals(result, int.parse("$radixString ", radix: radix), m);
Expect.equals(result, int.parse(" $radixString ", radix: radix), m);
Expect.equals(result, int.parse("+$radixString", radix: radix), m);
Expect.equals(result, int.parse(" +$radixString", radix: radix), m);
Expect.equals(result, int.parse("+$radixString ", radix: radix), m);
Expect.equals(result, int.parse(" +$radixString ", radix: radix), m);
Expect.equals(-result, int.parse("-$radixString", radix: radix), m);
Expect.equals(-result, int.parse(" -$radixString", radix: radix), m);
Expect.equals(-result, int.parse("-$radixString ", radix: radix), m);
Expect.equals(-result, int.parse(" -$radixString ", radix: radix), m);
Expect.equals(
result,
int.parse("$oneByteWhiteSpace$radixString$oneByteWhiteSpace",
radix: radix),
m);
Expect.equals(
-result,
int.parse("$oneByteWhiteSpace-$radixString$oneByteWhiteSpace",
radix: radix),
m);
Expect.equals(result,
int.parse("$whiteSpace$radixString$whiteSpace", radix: radix), m);
Expect.equals(-result,
int.parse("$whiteSpace-$radixString$whiteSpace", radix: radix), m);
Expect.equals(result, int.parse("$zeros$radixString", radix: radix), m);
Expect.equals(result, int.parse("+$zeros$radixString", radix: radix), m);
Expect.equals(-result, int.parse("-$zeros$radixString", radix: radix), m);
}
final max = 9223372036854775807;
for (int i = 2; i <= 36; i++) { // //# 02: ok
// Test with bignums. // //# 02: continued
final n = (log(max) / log(i)).truncate(); // //# 02: continued
var digit = digits[i - 1]; // //# 02: continued
testParse(pow(i, n) - 1, digit * n, i); // //# 02: continued
testParse(0, zeros, i); // //# 02: continued
} // //# 02: continued
// Big number.
Expect.equals(9223372036854775807, int.parse("9223372036854775807"));
Expect.equals(-9223372036854775808, int.parse("-9223372036854775808"));
}

View file

@ -65,7 +65,7 @@ void main() {
}
}
final max = 9223372036854775807;
final max = 0x1FFFFFFFFFFFFF;
for (int i = 2; i <= 36; i++) { // //# 02: ok
// Test with bignums. // //# 02: continued
final n = (log(max) / log(i)).truncate(); // //# 02: continued
@ -78,8 +78,9 @@ void main() {
Expect.equals(0xABCD, int.parse("ABCD", radix: 16));
Expect.equals(0xABCD, int.parse("abcd", radix: 16));
Expect.equals(15628859, int.parse("09azAZ", radix: 36));
// Big number.
Expect.equals(9223372036854775807, int.parse("9223372036854775807"));
// Big-ish number. (2^53)
Expect.equals(9007199254740991, int.parse("9007199254740991"));
Expect.equals(-9007199254740991, int.parse("-9007199254740991"));
Expect.equals(-9223372036854775808, int.parse("-9223372036854775808"));
// Allow whitespace before and after the number.
Expect.equals(1, int.parse(" 1", radix: 2));

View file

@ -0,0 +1,12 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
import "dart:math" show pow, log;
void main() {
// Big numbers (representable as both Int64 and double).
Expect.equals(9223372036854774784, int.tryParse("9223372036854774784"));
Expect.equals(-9223372036854775808, int.tryParse("-9223372036854775808"));
}

View file

@ -87,9 +87,9 @@ void main() {
Expect.equals(0xABCD, int.tryParse("ABCD", radix: 16));
Expect.equals(0xABCD, int.tryParse("abcd", radix: 16));
Expect.equals(15628859, int.tryParse("09azAZ", radix: 36));
// Big numbers (representable as both Int64 and double).
Expect.equals(9223372036854774784, int.tryParse("9223372036854774784"));
Expect.equals(-9223372036854775808, int.tryParse("-9223372036854775808"));
// Bigish numbers (representable precisely as both Int64 and double (2^53)).
Expect.equals(9007199254740991, int.tryParse("9007199254740991"));
Expect.equals(-9007199254740991, int.tryParse("-9007199254740991"));
// Allow whitespace before and after the number.
Expect.equals(1, int.tryParse(" 1", radix: 2));
Expect.equals(1, int.tryParse("1 ", radix: 2));

View file

@ -0,0 +1,28 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart test program to test arithmetic operations.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
library arithmetic_test;
import "package:expect/expect.dart";
import 'dart:math';
class ArithmeticTest {
static runOne() {
// Math functions.
Expect.equals(1234567890123456789, int.parse("1234567890123456789"));
Expect.equals(-1234567890123456789, int.parse("-1234567890123456789"));
Expect.equals(9223372036854775807, int.parse("9223372036854775807"));
Expect.equals(-9223372036854775808, int.parse("-9223372036854775808"));
}
static testMain() {
runOne();
}
}
main() {
ArithmeticTest.testMain();
}

View file

@ -403,10 +403,8 @@ class ArithmeticTest {
Expect.equals(12, int.parse("12"));
Expect.equals(-12, int.parse("-12"));
Expect.equals(1234567890123456789, int.parse("1234567890123456789"));
Expect.equals(-1234567890123456789, int.parse("-1234567890123456789"));
Expect.equals(9223372036854775807, int.parse("9223372036854775807"));
Expect.equals(-9223372036854775808, int.parse("-9223372036854775808"));
Expect.equals(9007199254740991, int.parse("9007199254740991"));
Expect.equals(-9007199254740991, int.parse("-9007199254740991"));
// Type checks.
{
int i = int.parse("12");

View file

@ -844,6 +844,7 @@ type_promotion_more_specific_test/04: CompileTimeError
type_variable_promotion_test: RuntimeError
[ $compiler == dart2js && $fasta ]
arithmetic_int64_test: RuntimeError # WontFix: Int not precisely representable in JS
call_method_as_cast_test/06: RuntimeError
call_method_implicit_tear_off_implements_function_test/05: RuntimeError
call_method_implicit_tear_off_implements_function_test/06: RuntimeError
@ -856,6 +857,7 @@ const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 1
function_propagation_test: RuntimeError
generic_test/01: MissingCompileTimeError # front end does not validate `extends`
instantiate_tearoff_of_call_test: RuntimeError
mint_compares_test: RuntimeError # WontFix: Int not precisely representable in JS
mixin_type_parameter_inference_error_test/none: CompileTimeError
mixin_type_parameter_inference_previous_mixin_test/01: CompileTimeError
mixin_type_parameter_inference_previous_mixin_test/02: CompileTimeError