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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/constant_system_dart.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 part of dart2js;
6
7 const DART_CONSTANT_SYSTEM = const DartConstantSystem();
8
9 class BitNotOperation implements UnaryOperation {
10 final String name = '~';
11 const BitNotOperation();
12 ConstantValue fold(ConstantValue constant) {
13 if (constant.isInt) {
14 IntConstantValue intConstant = constant;
15 return DART_CONSTANT_SYSTEM.createInt(~intConstant.primitiveValue);
16 }
17 return null;
18 }
19 }
20
21 class NegateOperation implements UnaryOperation {
22 final String name = 'negate';
23 const NegateOperation();
24 ConstantValue fold(ConstantValue constant) {
25 if (constant.isInt) {
26 IntConstantValue intConstant = constant;
27 return DART_CONSTANT_SYSTEM.createInt(-intConstant.primitiveValue);
28 }
29 if (constant.isDouble) {
30 DoubleConstantValue doubleConstant = constant;
31 return DART_CONSTANT_SYSTEM.createDouble(-doubleConstant.primitiveValue);
32 }
33 return null;
34 }
35 }
36
37 class NotOperation implements UnaryOperation {
38 final String name = '!';
39 const NotOperation();
40 ConstantValue fold(ConstantValue constant) {
41 if (constant.isBool) {
42 BoolConstantValue boolConstant = constant;
43 return DART_CONSTANT_SYSTEM.createBool(!boolConstant.primitiveValue);
44 }
45 return null;
46 }
47 }
48
49 /**
50 * Operations that only work if both arguments are integers.
51 */
52 abstract class BinaryBitOperation implements BinaryOperation {
53 const BinaryBitOperation();
54 ConstantValue fold(ConstantValue left, ConstantValue right) {
55 if (left.isInt && right.isInt) {
56 IntConstantValue leftInt = left;
57 IntConstantValue rightInt = right;
58 int resultValue =
59 foldInts(leftInt.primitiveValue, rightInt.primitiveValue);
60 if (resultValue == null) return null;
61 return DART_CONSTANT_SYSTEM.createInt(resultValue);
62 }
63 return null;
64 }
65
66 int foldInts(int left, int right);
67 }
68
69 class BitOrOperation extends BinaryBitOperation {
70 final String name = '|';
71 const BitOrOperation();
72 int foldInts(int left, int right) => left | right;
73 apply(left, right) => left | right;
74 }
75
76 class BitAndOperation extends BinaryBitOperation {
77 final String name = '&';
78 const BitAndOperation();
79 int foldInts(int left, int right) => left & right;
80 apply(left, right) => left & right;
81 }
82
83 class BitXorOperation extends BinaryBitOperation {
84 final String name = '^';
85 const BitXorOperation();
86 int foldInts(int left, int right) => left ^ right;
87 apply(left, right) => left ^ right;
88 }
89
90 class ShiftLeftOperation extends BinaryBitOperation {
91 final String name = '<<';
92 const ShiftLeftOperation();
93 int foldInts(int left, int right) {
94 // TODO(floitsch): find a better way to guard against excessive shifts to
95 // the left.
96 if (right > 100 || right < 0) return null;
97 return left << right;
98 }
99 apply(left, right) => left << right;
100 }
101
102 class ShiftRightOperation extends BinaryBitOperation {
103 final String name = '>>';
104 const ShiftRightOperation();
105 int foldInts(int left, int right) {
106 if (right < 0) return null;
107 return left >> right;
108 }
109 apply(left, right) => left >> right;
110 }
111
112 abstract class BinaryBoolOperation implements BinaryOperation {
113 const BinaryBoolOperation();
114 ConstantValue fold(ConstantValue left, ConstantValue right) {
115 if (left.isBool && right.isBool) {
116 BoolConstantValue leftBool = left;
117 BoolConstantValue rightBool = right;
118 bool resultValue =
119 foldBools(leftBool.primitiveValue, rightBool.primitiveValue);
120 return DART_CONSTANT_SYSTEM.createBool(resultValue);
121 }
122 return null;
123 }
124
125 bool foldBools(bool left, bool right);
126 }
127
128 class BooleanAndOperation extends BinaryBoolOperation {
129 final String name = '&&';
130 const BooleanAndOperation();
131 bool foldBools(bool left, bool right) => left && right;
132 apply(left, right) => left && right;
133 }
134
135 class BooleanOrOperation extends BinaryBoolOperation {
136 final String name = '||';
137 const BooleanOrOperation();
138 bool foldBools(bool left, bool right) => left || right;
139 apply(left, right) => left || right;
140 }
141
142 abstract class ArithmeticNumOperation implements BinaryOperation {
143 const ArithmeticNumOperation();
144 ConstantValue fold(ConstantValue left, ConstantValue right) {
145 if (left.isNum && right.isNum) {
146 NumConstantValue leftNum = left;
147 NumConstantValue rightNum = right;
148 num foldedValue;
149 if (left.isInt && right.isInt) {
150 foldedValue = foldInts(leftNum.primitiveValue, rightNum.primitiveValue);
151 } else {
152 foldedValue = foldNums(leftNum.primitiveValue, rightNum.primitiveValue);
153 }
154 // A division by 0 means that we might not have a folded value.
155 if (foldedValue == null) return null;
156 if (left.isInt && right.isInt && !isDivide() ||
157 isTruncatingDivide()) {
158 assert(foldedValue is int);
159 return DART_CONSTANT_SYSTEM.createInt(foldedValue);
160 } else {
161 return DART_CONSTANT_SYSTEM.createDouble(foldedValue);
162 }
163 }
164 return null;
165 }
166
167 bool isDivide() => false;
168 bool isTruncatingDivide() => false;
169 num foldInts(int left, int right) => foldNums(left, right);
170 num foldNums(num left, num right);
171 }
172
173 class SubtractOperation extends ArithmeticNumOperation {
174 final String name = '-';
175 const SubtractOperation();
176 num foldNums(num left, num right) => left - right;
177 apply(left, right) => left - right;
178 }
179
180 class MultiplyOperation extends ArithmeticNumOperation {
181 final String name = '*';
182 const MultiplyOperation();
183 num foldNums(num left, num right) => left * right;
184 apply(left, right) => left * right;
185 }
186
187 class ModuloOperation extends ArithmeticNumOperation {
188 final String name = '%';
189 const ModuloOperation();
190 int foldInts(int left, int right) {
191 if (right == 0) return null;
192 return left % right;
193 }
194 num foldNums(num left, num right) => left % right;
195 apply(left, right) => left % right;
196 }
197
198 class TruncatingDivideOperation extends ArithmeticNumOperation {
199 final String name = '~/';
200 const TruncatingDivideOperation();
201 int foldInts(int left, int right) {
202 if (right == 0) return null;
203 return left ~/ right;
204 }
205 num foldNums(num left, num right) {
206 num ratio = left / right;
207 if (ratio.isNaN || ratio.isInfinite) return null;
208 return ratio.truncate().toInt();
209 }
210 apply(left, right) => left ~/ right;
211 bool isTruncatingDivide() => true;
212 }
213
214 class DivideOperation extends ArithmeticNumOperation {
215 final String name = '/';
216 const DivideOperation();
217 num foldNums(num left, num right) => left / right;
218 bool isDivide() => true;
219 apply(left, right) => left / right;
220 }
221
222 class AddOperation implements BinaryOperation {
223 final String name = '+';
224 const AddOperation();
225 ConstantValue fold(ConstantValue left, ConstantValue right) {
226 if (left.isInt && right.isInt) {
227 IntConstantValue leftInt = left;
228 IntConstantValue rightInt = right;
229 int result = leftInt.primitiveValue + rightInt.primitiveValue;
230 return DART_CONSTANT_SYSTEM.createInt(result);
231 } else if (left.isNum && right.isNum) {
232 NumConstantValue leftNum = left;
233 NumConstantValue rightNum = right;
234 double result = leftNum.primitiveValue + rightNum.primitiveValue;
235 return DART_CONSTANT_SYSTEM.createDouble(result);
236 } else {
237 return null;
238 }
239 }
240 apply(left, right) => left + right;
241 }
242
243 abstract class RelationalNumOperation implements BinaryOperation {
244 const RelationalNumOperation();
245 ConstantValue fold(ConstantValue left, ConstantValue right) {
246 if (!left.isNum || !right.isNum) return null;
247 NumConstantValue leftNum = left;
248 NumConstantValue rightNum = right;
249 bool foldedValue =
250 foldNums(leftNum.primitiveValue, rightNum.primitiveValue);
251 assert(foldedValue != null);
252 return DART_CONSTANT_SYSTEM.createBool(foldedValue);
253 }
254
255 bool foldNums(num left, num right);
256 }
257
258 class LessOperation extends RelationalNumOperation {
259 final String name = '<';
260 const LessOperation();
261 bool foldNums(num left, num right) => left < right;
262 apply(left, right) => left < right;
263 }
264
265 class LessEqualOperation extends RelationalNumOperation {
266 final String name = '<=';
267 const LessEqualOperation();
268 bool foldNums(num left, num right) => left <= right;
269 apply(left, right) => left <= right;
270 }
271
272 class GreaterOperation extends RelationalNumOperation {
273 final String name = '>';
274 const GreaterOperation();
275 bool foldNums(num left, num right) => left > right;
276 apply(left, right) => left > right;
277 }
278
279 class GreaterEqualOperation extends RelationalNumOperation {
280 final String name = '>=';
281 const GreaterEqualOperation();
282 bool foldNums(num left, num right) => left >= right;
283 apply(left, right) => left >= right;
284 }
285
286 class EqualsOperation implements BinaryOperation {
287 final String name = '==';
288 const EqualsOperation();
289 ConstantValue fold(ConstantValue left, ConstantValue right) {
290 if (left.isNum && right.isNum) {
291 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0,
292 // and 1 == 1.0.
293 NumConstantValue leftNum = left;
294 NumConstantValue rightNum = right;
295 bool result = leftNum.primitiveValue == rightNum.primitiveValue;
296 return DART_CONSTANT_SYSTEM.createBool(result);
297 }
298 if (left.isConstructedObject) {
299 // Unless we know that the user-defined object does not implement the
300 // equality operator we cannot fold here.
301 return null;
302 }
303 return DART_CONSTANT_SYSTEM.createBool(left == right);
304 }
305 apply(left, right) => left == right;
306 }
307
308 class IdentityOperation implements BinaryOperation {
309 final String name = '===';
310 const IdentityOperation();
311 BoolConstantValue fold(ConstantValue left, ConstantValue right) {
312 // In order to preserve runtime semantics which says that NaN !== NaN don't
313 // constant fold NaN === NaN. Otherwise the output depends on inlined
314 // variables and other optimizations.
315 if (left.isNaN && right.isNaN) return null;
316 return DART_CONSTANT_SYSTEM.createBool(left == right);
317 }
318 apply(left, right) => identical(left, right);
319 }
320
321 abstract class CodeUnitAtOperation implements BinaryOperation {
322 final String name = 'charCodeAt';
323 const CodeUnitAtOperation();
324 apply(left, right) => left.codeUnitAt(right);
325 }
326
327 class CodeUnitAtConstantOperation extends CodeUnitAtOperation {
328 const CodeUnitAtConstantOperation();
329 ConstantValue fold(ConstantValue left, ConstantValue right) {
330 // 'a'.codeUnitAt(0) is not a constant expression.
331 return null;
332 }
333 }
334
335 class CodeUnitAtRuntimeOperation extends CodeUnitAtOperation {
336 const CodeUnitAtRuntimeOperation();
337 IntConstantValue fold(ConstantValue left, ConstantValue right) {
338 if (left.isString && right.isInt) {
339 StringConstantValue stringConstant = left;
340 IntConstantValue indexConstant = right;
341 DartString dartString = stringConstant.primitiveValue;
342 int index = indexConstant.primitiveValue;
343 if (index < 0 || index >= dartString.length) return null;
344 String string = dartString.slowToString();
345 int value = string.codeUnitAt(index);
346 return DART_CONSTANT_SYSTEM.createInt(value);
347 }
348 return null;
349 }
350 }
351
352 /**
353 * A constant system implementing the Dart semantics. This system relies on
354 * the underlying runtime-system. That is, if dart2js is run in an environment
355 * that doesn't correctly implement Dart's semantics this constant system will
356 * not return the correct values.
357 */
358 class DartConstantSystem extends ConstantSystem {
359 final add = const AddOperation();
360 final bitAnd = const BitAndOperation();
361 final bitNot = const BitNotOperation();
362 final bitOr = const BitOrOperation();
363 final bitXor = const BitXorOperation();
364 final booleanAnd = const BooleanAndOperation();
365 final booleanOr = const BooleanOrOperation();
366 final divide = const DivideOperation();
367 final equal = const EqualsOperation();
368 final greaterEqual = const GreaterEqualOperation();
369 final greater = const GreaterOperation();
370 final identity = const IdentityOperation();
371 final lessEqual = const LessEqualOperation();
372 final less = const LessOperation();
373 final modulo = const ModuloOperation();
374 final multiply = const MultiplyOperation();
375 final negate = const NegateOperation();
376 final not = const NotOperation();
377 final shiftLeft = const ShiftLeftOperation();
378 final shiftRight = const ShiftRightOperation();
379 final subtract = const SubtractOperation();
380 final truncatingDivide = const TruncatingDivideOperation();
381 final codeUnitAt = const CodeUnitAtConstantOperation();
382
383 const DartConstantSystem();
384
385 IntConstantValue createInt(int i) => new IntConstantValue(i);
386 DoubleConstantValue createDouble(double d) => new DoubleConstantValue(d);
387 StringConstantValue createString(DartString string) {
388 return new StringConstantValue(string);
389 }
390 BoolConstantValue createBool(bool value) => new BoolConstantValue(value);
391 NullConstantValue createNull() => new NullConstantValue();
392 MapConstantValue createMap(Compiler compiler,
393 InterfaceType type,
394 List<ConstantValue> keys,
395 List<ConstantValue> values) {
396 return new MapConstantValue(type, keys, values);
397 }
398
399 bool isInt(ConstantValue constant) => constant.isInt;
400 bool isDouble(ConstantValue constant) => constant.isDouble;
401 bool isString(ConstantValue constant) => constant.isString;
402 bool isBool(ConstantValue constant) => constant.isBool;
403 bool isNull(ConstantValue constant) => constant.isNull;
404
405 bool isSubtype(Compiler compiler, DartType s, DartType t) {
406 return compiler.types.isSubtype(s, t);
407 }
408 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698