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

Side by Side Diff: lib/compiler/implementation/javascript_operations.dart

Issue 10825386: Use JavaScript runtime semantics when constant folding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove top-level constanst. Created 8 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 class JavaScriptBitNotOperation extends BitNotOperation {
6 static const int BITS32 = 0xFFFFFFFF;
7
8 const JavaScriptBitNotOperation();
9 Constant fold(Constant constant) {
10 // In JavaScript we don't check for -0 and treat it as if it was zero.
11 if (constant.isMinusZero()) constant = new IntConstant(0);
12 if (constant.isInt()) {
13 IntConstant intConstant = constant;
14 // We convert the result of bit-operations to 32 bit unsigned integers.
15 return new IntConstant((~intConstant.value) & BITS32);
16 }
17 return null;
18 }
19 }
20
21 /**
22 * In JavaScript we truncate the result to an unsigned 32 bit integer. Also, -0
23 * is treated as if it was the integer 0.
24 */
25 class JavaScriptBinaryBitOperation implements BinaryOperation {
26 static const int BITS32 = 0xFFFFFFFF;
ngeoffray 2012/08/17 08:32:59 Share it with JavaScriptBitNotOperation?
floitsch 2012/09/03 14:34:52 Done.
27
28 final BinaryBitOperation dartBitOperation;
29 const JavaScriptBinaryBitOperation(this.dartBitOperation);
30
31 bool isUserDefinable() => dartBitOperation.isUserDefinable();
32 SourceString get name() => dartBitOperation.name;
33
34 Constant fold(Constant left, Constant right) {
35 // In JavaScript we don't check for -0 and treat it as if it was zero.
36 if (left.isMinusZero()) left = new IntConstant(0);
37 if (right.isMinusZero()) right = new IntConstant(0);
38 IntConstant result = dartBitOperation.fold(left, right);
39 if (result != null) {
40 // We convert the result of bit-operations to 32 bit unsigned integers.
41 int clampedValue = result.value & BITS32;
42 if (clampedValue != result.value) {
43 result = new IntConstant(clampedValue);
44 }
45 }
46 return result;
47 }
48 }
49
50 class JavaScriptNegateOperation implements UnaryOperation {
51 final NegateOperation dartNegateOperation = const NegateOperation();
52 const JavaScriptNegateOperation();
53
54 bool isUserDefinable() => dartNegateOperation.isUserDefinable();
55 SourceString get name() => dartNegateOperation.name;
56
57 Constant fold(Constant constant) {
58 if (constant.isInt()) {
59 IntConstant intConstant = constant;
60 if (intConstant.value == 0) return new DoubleConstant(-0.0);
61 }
62 return dartNegateOperation.fold(constant);
63 }
64 }
65
66 class JavaScriptBinaryArithmeticOperation implements BinaryOperation {
67 final BinaryOperation dartArithmeticOperation;
68 const JavaScriptBinaryArithmeticOperation(this.dartArithmeticOperation);
69
70 bool isUserDefinable() => dartArithmeticOperation.isUserDefinable();
71 SourceString get name() => dartArithmeticOperation.name;
72
73 /**
74 * Returns true if the given [value] fits into a double without losing
75 * precision.
76 */
77 bool integerFitsIntoDouble(int value) {
78 // The maximum integer value a double can represent without losing
79 // precision.
80 final int BITS53 = 0x1FFFFFFFFFFFFF;
81
82 int absValue = value.abs();
83 return (absValue & BITS53) == absValue;
84 }
85
86 Constant fold(Constant left, Constant right) {
87 Constant result = dartArithmeticOperation.fold(left, right);
88 if (result == null) return result;
89 if (result.isInt()) {
90 // TODO(floitsch): make sure that the constant folding operation has the
91 // same semantics as during runtime.
92 IntConstant intResult = result;
93 int intValue = intResult.value;
94 if (!integerFitsIntoDouble(intValue)) {
95 return new DoubleConstant(intValue.toDouble());
96 }
97 } else if (result.isDouble()) {
98 DoubleConstant doubleResult = result;
99 double doubleValue = doubleResult.value;
100 if (!doubleValue.isInfinite() && !doubleValue.isNaN()) {
101 int intValue = doubleValue.toInt();
102 if (intValue == doubleValue && integerFitsIntoDouble(intValue)) {
103 return new IntConstant(intValue);
104 }
105 }
106 }
107 return result;
108 }
109 }
110
111 class JavaScriptIdentityOperation implements BinaryOperation {
112 final IdentityOperation dartIdentityOperation = const IdentityOperation();
113
114 const JavaScriptIdentityOperation();
115
116 bool isUserDefinable() => dartIdentityOperation.isUserDefinable();
117 SourceString get name() => dartIdentityOperation.name;
118
119 BoolConstant fold(Constant left, Constant right) {
120 BoolConstant result = dartIdentityOperation.fold(left, right);
121 if (result == null || result.value) return result;
122 // In JavaScript -0.0 === 0 and all doubles are equal to their integer
123 // values.
124 if (left.isNum() && right.isNum()) {
125 NumConstant leftNum = left;
126 NumConstant rightNum = right;
127 double leftDouble = leftNum.value.toDouble();
128 double rightDouble = rightNum.value.toDouble();
129 return new BoolConstant(leftDouble == rightDouble);
130 }
131 return result;
132 }
133 }
134
135 /**
136 * Folding operations following the semantics for Dart code that has been
137 * compiled to JavaScript.
138 */
139 class JavaScriptFoldingOperations implements FoldingOperations {
140 final add = const JavaScriptBinaryArithmeticOperation(const AddOperation());
141 final bitAnd = const JavaScriptBinaryBitOperation(const BitAndOperation());
142 final bitNot = const JavaScriptBitNotOperation();
143 final bitOr = const JavaScriptBinaryBitOperation(const BitOrOperation());
144 final bitXor = const JavaScriptBinaryBitOperation(const BitXorOperation());
145 final booleanAnd = const BooleanAndOperation();
146 final booleanOr = const BooleanOrOperation();
147 final divide =
148 const JavaScriptBinaryArithmeticOperation(const DivideOperation());
149 final equal = const EqualsOperation();
150 final greaterEqual = const GreaterEqualOperation();
151 final greater = const GreaterOperation();
152 final identity = const JavaScriptIdentityOperation();
153 final lessEqual = const LessEqualOperation();
154 final less = const LessOperation();
155 final modulo =
156 const JavaScriptBinaryArithmeticOperation(const ModuloOperation());
157 final multiply =
158 const JavaScriptBinaryArithmeticOperation(const MultiplyOperation());
159 final negate = const JavaScriptNegateOperation();
160 final not = const NotOperation();
161 final shiftLeft =
162 const JavaScriptBinaryBitOperation(const ShiftLeftOperation());
163 final shiftRight =
164 const JavaScriptBinaryBitOperation(const ShiftRightOperation());
165 final subtract =
166 const JavaScriptBinaryArithmeticOperation(const SubtractOperation());
167 final truncatingDivide = const JavaScriptBinaryArithmeticOperation(
168 const TruncatingDivideOperation());
169
170 const JavaScriptFoldingOperations();
171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698