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

Unified Diff: pkg/compiler/lib/src/js_backend/constant_system_javascript.dart

Issue 2400853003: dart2js: Constant fold num.round() (Closed)
Patch Set: Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 7f86482fd595d79f5dd2fbe2706e5801d8b29bb7..08174df252d834880d872d183b866b6d0a548a9e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -165,12 +165,50 @@ class JavaScriptIdentityOperation implements BinaryOperation {
apply(left, right) => identical(left, right);
}
+class JavaScriptRoundOperation implements UnaryOperation {
+ const JavaScriptRoundOperation();
+ String get name => DART_CONSTANT_SYSTEM.round.name;
+ ConstantValue fold(ConstantValue constant) {
+ // Be careful to round() only values that do not throw on either the host or
+ // target platform.
+ ConstantValue tryToRound(num value) {
+ // Due to differences between browsers, only 'round' easy cases. Avoid
+ // cases where nudging the value up or down changes the answer.
+ // 13 digits is safely within the ~15 digit precision of doubles.
+ const severalULP = 0.0000000000001;
+ // Use 'roundToDouble()' to avoid exceptions on rounding the nudged value.
+ double rounded = value.roundToDouble();
+ double rounded1 = (value * (1.0 + severalULP)).roundToDouble();
+ double rounded2 = (value * (1.0 - severalULP)).roundToDouble();
+ if (rounded != rounded1 || rounded != rounded2) return null;
+ return JAVA_SCRIPT_CONSTANT_SYSTEM
+ .convertToJavaScriptConstant(new IntConstantValue(value.round()));
+ }
+
+ if (constant.isInt) {
+ IntConstantValue intConstant = constant;
+ int value = intConstant.primitiveValue;
+ if (value >= -double.MAX_FINITE && value <= double.MAX_FINITE) {
+ return tryToRound(value);
+ }
+ }
+ if (constant.isDouble) {
+ DoubleConstantValue doubleConstant = constant;
+ double value = doubleConstant.primitiveValue;
+ // NaN and infinities will throw.
+ if (value.isNaN) return null;
+ if (value.isInfinite) return null;
+ return tryToRound(value);
+ }
+ return null;
+ }
+}
+
/**
* Constant system following the semantics for Dart code that has been
* compiled to JavaScript.
*/
class JavaScriptConstantSystem extends ConstantSystem {
- final int BITS31 = 0x8FFFFFFF;
final int BITS32 = 0xFFFFFFFF;
final add = const JavaScriptAddOperation();
@@ -203,6 +241,7 @@ class JavaScriptConstantSystem extends ConstantSystem {
final truncatingDivide = const JavaScriptBinaryArithmeticOperation(
const TruncatingDivideOperation());
final codeUnitAt = const CodeUnitAtRuntimeOperation();
+ final round = const JavaScriptRoundOperation();
const JavaScriptConstantSystem();
« no previous file with comments | « pkg/compiler/lib/src/constants/constant_system.dart ('k') | pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698