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

Side by Side Diff: frog/leg/compile_time_constants.dart

Issue 9592009: Reapply "Refactor constant part." (r4958) with fixes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update tests and fix code after renaming. Created 8 years, 9 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
« no previous file with comments | « no previous file | frog/leg/compiler.dart » ('j') | frog/leg/ssa/optimize.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Constant implements Hashable { 5 class Constant implements Hashable {
6 const Constant(); 6 const Constant();
7 7
8 bool isNull() => false; 8 bool isNull() => false;
9 /** [isInt] implies [isNum]. */ 9 /** [isInt] implies [isNum]. */
10 bool isInt() => false; 10 bool isInt() => false;
11 /** [isDouble] implies [isNum]. */ 11 /** [isDouble] implies [isNum]. */
12 bool isDouble() => false; 12 bool isDouble() => false;
13 bool isBool() => false; 13 bool isBool() => false;
14 bool isString() => false; 14 bool isString() => false;
15 /** [isList] implies [isObject]. */ 15 /** [isList] implies [isObject]. */
16 bool isList() => false; 16 bool isList() => false;
17 /** [isMap] implies [isObject]. */ 17 /** [isMap] implies [isObject]. */
18 bool isMap() => false; 18 bool isMap() => false;
19 bool isConstructedObject() => false; 19 bool isConstructedObject() => false;
20 20
21 bool isNum() => isInt() || isDouble(); 21 bool isNum() => isInt() || isDouble();
22 bool isObject() => isList() || isMap() || isConstructedObject(); 22 bool isObject() => isList() || isMap() || isConstructedObject();
23 bool isTrue() {
24 if (!isBool()) return false;
25 BoolConstant boolConstant = this;
26 return boolConstant.value;
27 }
28 bool isFalse() {
29 if (!isBool()) return false;
30 BoolConstant boolConstant = this;
31 return !boolConstant.value;
32 }
23 33
24 /** 34 /**
25 * Returns [:null:] if the operation is not supported on this constant. 35 * Returns [:null:] if the operation is not supported on this constant.
26 * The [op] operator is assumed to be a prefix operator. 36 * The [op] operator is assumed to be a prefix operator.
27 */ 37 */
28 Constant unaryFold(String op) => null; 38 Constant unaryFold(String op) => null;
29 39
30 /** 40 /**
31 * Returns [:null:] if the operation is not supported on this constant, or 41 * Returns [:null:] if the operation is not supported on this constant, or
32 * if the operation would have thrown an exception. 42 * if the operation would have thrown an exception.
33 */ 43 */
34 Constant binaryFold(String op, Constant other) { 44 Constant binaryFold(String op, Constant other) {
35 if (op == "==" || op == "===") { 45 if (op == "==" || op == "===") {
36 return new BoolConstant(this == other); 46 return new BoolConstant(this == other);
37 } else if (op == "!=" || op == "!==") { 47 } else if (op == "!=" || op == "!==") {
38 return new BoolConstant(this != other); 48 return new BoolConstant(this != other);
39 } 49 }
40 } 50 }
41 51
42 abstract void writeJsCode(StringBuffer buffer, 52 abstract void writeJsCode(StringBuffer buffer, ConstantHandler handler);
43 CompileTimeConstantHandler handler);
44 } 53 }
45 54
46 class PrimitiveConstant extends Constant { 55 class PrimitiveConstant extends Constant {
47 // TODO(floitsch): this should be an abstract getter, but there is a bug in 56 abstract get value();
48 // the VM.
49 get value() => null;
50 const PrimitiveConstant(); 57 const PrimitiveConstant();
51 58
52 bool operator ==(var other) { 59 bool operator ==(var other) {
53 if (other is !PrimitiveConstant) return false; 60 if (other is !PrimitiveConstant) return false;
54 PrimitiveConstant otherPrimitive = other; 61 PrimitiveConstant otherPrimitive = other;
55 // We use == instead of === so that DartStrings compare correctly. 62 // We use == instead of === so that DartStrings compare correctly.
56 return value == otherPrimitive.value; 63 return value == otherPrimitive.value;
57 } 64 }
65
66 String toString() => value.toString();
58 } 67 }
59 68
60 class NullConstant extends PrimitiveConstant { 69 class NullConstant extends PrimitiveConstant {
61 const NullConstant(); 70 const NullConstant();
62 bool isNull() => true; 71 bool isNull() => true;
63 get value() => null; 72 get value() => null;
64 73
65 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 74 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
66 buffer.add("(void 0)"); 75 buffer.add("(void 0)");
67 } 76 }
68 77
69 // The magic constant has no meaning. It is just a random value. 78 // The magic constant has no meaning. It is just a random value.
70 int hashCode() => 785965825; 79 int hashCode() => 785965825;
71 } 80 }
72 81
73 class IntConstant extends PrimitiveConstant { 82 class IntConstant extends PrimitiveConstant {
74 final int value; 83 final int value;
75 // TODO(floitsch): cache the most common integer values. 84 // TODO(floitsch): cache the most common integer values.
76 const IntConstant(this.value); 85 const IntConstant(this.value);
77 bool isInt() => true; 86 bool isInt() => true;
78 87
79 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 88 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
80 buffer.add("($value)"); 89 buffer.add("($value)");
81 } 90 }
82 91
83 IntConstant unaryFold(String op) { 92 IntConstant unaryFold(String op) {
84 if (op == "-") return new IntConstant(-value); 93 if (op == "-") return new IntConstant(-value);
85 if (op == "~") return new IntConstant(~value); 94 if (op == "~") return new IntConstant(~value);
86 return null; 95 return null;
87 } 96 }
88 97
89 Constant binaryFold(String op, Constant other) { 98 Constant binaryFold(String op, Constant other) {
(...skipping 17 matching lines...) Expand all
107 case "-": return new IntConstant(value - right); 116 case "-": return new IntConstant(value - right);
108 case "*": return new IntConstant(value * right); 117 case "*": return new IntConstant(value * right);
109 case "%": return new IntConstant(value % right); 118 case "%": return new IntConstant(value % right);
110 case "~/": return new IntConstant(value ~/ right); 119 case "~/": return new IntConstant(value ~/ right);
111 case "|": return new IntConstant(value | right); 120 case "|": return new IntConstant(value | right);
112 case "&": return new IntConstant(value & right); 121 case "&": return new IntConstant(value & right);
113 case "^": return new IntConstant(value ^ right); 122 case "^": return new IntConstant(value ^ right);
114 case "<<": 123 case "<<":
115 // TODO(floitsch): find a better way to guard against shifts to the 124 // TODO(floitsch): find a better way to guard against shifts to the
116 // left. 125 // left.
117 if (right > 100) null; 126 if (right > 100) return null;
118 if (right < 0) null; 127 if (right < 0) return null;
119 return new IntConstant(value << right); 128 return new IntConstant(value << right);
120 case ">>": 129 case ">>":
121 if (right < 0) return null; 130 if (right < 0) return null;
122 return new IntConstant(value >> right); 131 return new IntConstant(value >> right);
123 } 132 }
124 } else if (other.isDouble()) { 133 } else if (other.isDouble()) {
125 double right = rightNum; 134 double right = rightNum;
126 switch (op) { 135 switch (op) {
127 case "+": return new DoubleConstant(value + right); 136 case "+": return new DoubleConstant(value + right);
128 case "-": return new DoubleConstant(value - right); 137 case "-": return new DoubleConstant(value - right);
(...skipping 18 matching lines...) Expand all
147 } 156 }
148 157
149 int hashCode() => value.hashCode(); 158 int hashCode() => value.hashCode();
150 } 159 }
151 160
152 class DoubleConstant extends PrimitiveConstant { 161 class DoubleConstant extends PrimitiveConstant {
153 final double value; 162 final double value;
154 const DoubleConstant(this.value); 163 const DoubleConstant(this.value);
155 bool isDouble() => true; 164 bool isDouble() => true;
156 165
157 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 166 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
158 if (value.isNaN()) { 167 if (value.isNaN()) {
159 buffer.add("(0/0)"); 168 buffer.add("(0/0)");
160 } else if (value == double.INFINITY) { 169 } else if (value == double.INFINITY) {
161 buffer.add("(1/0)"); 170 buffer.add("(1/0)");
162 } else if (value == -double.INFINITY) { 171 } else if (value == -double.INFINITY) {
163 buffer.add("(-1/0)"); 172 buffer.add("(-1/0)");
164 } else { 173 } else {
165 buffer.add("($value)"); 174 buffer.add("($value)");
166 } 175 }
167 } 176 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 219 }
211 220
212 int hashCode() => value.hashCode(); 221 int hashCode() => value.hashCode();
213 } 222 }
214 223
215 class BoolConstant extends PrimitiveConstant { 224 class BoolConstant extends PrimitiveConstant {
216 final bool value; 225 final bool value;
217 const BoolConstant(this.value); 226 const BoolConstant(this.value);
218 bool isBool() => true; 227 bool isBool() => true;
219 228
220 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 229 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
221 buffer.add(value ? "true" : "false"); 230 buffer.add(value ? "true" : "false");
222 } 231 }
223 232
224 BoolConstant unaryFold(String op) { 233 BoolConstant unaryFold(String op) {
225 if (op == "!") return new BoolConstant(!value); 234 if (op == "!") return new BoolConstant(!value);
226 return null; 235 return null;
227 } 236 }
228 237
229 bool operator ==(var other) { 238 bool operator ==(var other) {
230 if (other is !BoolConstant) return false; 239 if (other is !BoolConstant) return false;
(...skipping 10 matching lines...) Expand all
241 final DartString value; 250 final DartString value;
242 int _hashCode; 251 int _hashCode;
243 252
244 StringConstant(this.value) { 253 StringConstant(this.value) {
245 // TODO(floitsch): compute hashcode without calling toString() on the 254 // TODO(floitsch): compute hashcode without calling toString() on the
246 // DartString. 255 // DartString.
247 _hashCode = value.toString().hashCode(); 256 _hashCode = value.toString().hashCode();
248 } 257 }
249 bool isString() => true; 258 bool isString() => true;
250 259
251 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 260 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
252 buffer.add("'"); 261 buffer.add("'");
253 CompileTimeConstantHandler.writeEscapedString(value, buffer, (reason) { 262 ConstantHandler.writeEscapedString(value, buffer, (reason) {
254 throw new CompilerCancelledException(reason); 263 throw new CompilerCancelledException(reason);
255 }); 264 });
256 buffer.add("'"); 265 buffer.add("'");
257 } 266 }
258 267
259 Constant binaryFold(String op, Constant other) { 268 Constant binaryFold(String op, Constant other) {
260 if (other.isString() && op == "+") { 269 if (other.isString() && op == "+") {
261 StringConstant otherString = other; 270 StringConstant otherString = other;
262 DartString right = otherString.value; 271 DartString right = otherString.value;
263 return new StringConstant(new ConsDartString(value, right)); 272 return new StringConstant(new ConsDartString(value, right));
(...skipping 22 matching lines...) Expand all
286 int _hashCode; 295 int _hashCode;
287 296
288 ListConstant(Type type, this.entries) : super(type) { 297 ListConstant(Type type, this.entries) : super(type) {
289 // TODO(floitsch): create a better hash. 298 // TODO(floitsch): create a better hash.
290 int hash = 0; 299 int hash = 0;
291 for (Constant input in entries) hash ^= input.hashCode(); 300 for (Constant input in entries) hash ^= input.hashCode();
292 _hashCode = hash; 301 _hashCode = hash;
293 } 302 }
294 bool isList() => true; 303 bool isList() => true;
295 304
296 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 305 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
297 // TODO(floitsch): we should not need to go through the compiler to make 306 // TODO(floitsch): we should not need to go through the compiler to make
298 // the list constant. 307 // the list constant.
299 buffer.add(handler.compiler.namer.ISOLATE); 308 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype";
300 buffer.add(".prototype.makeConstantList"); 309 buffer.add("$isolatePrototype.makeConstantList");
301 buffer.add("(["); 310 buffer.add("([");
302 for (int i = 0; i < entries.length; i++) { 311 for (int i = 0; i < entries.length; i++) {
303 if (i != 0) buffer.add(", "); 312 if (i != 0) buffer.add(", ");
304 Constant entry = entries[i]; 313 Constant entry = entries[i];
305 if (entry.isObject()) { 314 if (entry.isObject()) {
306 handler.getNameForConstant(entry); 315 String name = handler.getNameForConstant(entry);
316 buffer.add("$isolatePrototype.$name");
307 } else { 317 } else {
308 entry.writeJsCode(buffer, handler); 318 entry.writeJsCode(buffer, handler);
309 } 319 }
310 } 320 }
311 buffer.add("])"); 321 buffer.add("])");
312 } 322 }
313 323
314 bool operator ==(var other) { 324 bool operator ==(var other) {
315 if (other is !ListConstant) return false; 325 if (other is !ListConstant) return false;
316 ListConstant otherList = other; 326 ListConstant otherList = other;
(...skipping 18 matching lines...) Expand all
335 // TODO(floitsch): create a better hash. 345 // TODO(floitsch): create a better hash.
336 int hash = 0; 346 int hash = 0;
337 for (Constant field in fields) { 347 for (Constant field in fields) {
338 hash ^= field.hashCode(); 348 hash ^= field.hashCode();
339 } 349 }
340 hash ^= type.element.hashCode(); 350 hash ^= type.element.hashCode();
341 _hashCode = hash; 351 _hashCode = hash;
342 } 352 }
343 bool isConstructedObject() => true; 353 bool isConstructedObject() => true;
344 354
345 void writeJsCode(StringBuffer buffer, CompileTimeConstantHandler handler) { 355 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
346 buffer.add("new "); 356 buffer.add("new ");
347 buffer.add(handler.getJsConstructor(type.element)); 357 buffer.add(handler.getJsConstructor(type.element));
348 buffer.add("("); 358 buffer.add("(");
349 for (int i = 0; i < fields.length; i++) { 359 for (int i = 0; i < fields.length; i++) {
350 if (i != 0) buffer.add(", "); 360 if (i != 0) buffer.add(", ");
351 Constant field = fields[i]; 361 Constant field = fields[i];
352 // TODO(floitsch): share this code with the ListConstant. 362 // TODO(floitsch): share this code with the ListConstant.
353 if (field.isObject()) { 363 if (field.isObject()) {
354 handler.getNameForConstant(field); 364 handler.getNameForConstant(field);
355 } else { 365 } else {
(...skipping 13 matching lines...) Expand all
369 for (int i = 0; i < fields.length; i++) { 379 for (int i = 0; i < fields.length; i++) {
370 if (fields[i] != other.fields[i]) return false; 380 if (fields[i] != other.fields[i]) return false;
371 } 381 }
372 return true; 382 return true;
373 } 383 }
374 384
375 int hashCode() => _hashCode; 385 int hashCode() => _hashCode;
376 } 386 }
377 387
378 /** 388 /**
379 * The [CompileTimeConstantHandler] keeps track of compile-time constants, 389 * The [ConstantHandler] keeps track of compile-time constants,
380 * initializations of global and static fields, and default values of 390 * initializations of global and static fields, and default values of
381 * optional parameters. 391 * optional parameters.
382 */ 392 */
383 class CompileTimeConstantHandler extends CompilerTask { 393 class ConstantHandler extends CompilerTask {
384 // Contains the initial value of fields. Must contain all static and global 394 // Contains the initial value of fields. Must contain all static and global
385 // initializations of used fields. May contain caches for instance fields. 395 // initializations of used fields. May contain caches for instance fields.
386 final Map<VariableElement, Dynamic> initialVariableValues; 396 final Map<VariableElement, Dynamic> initialVariableValues;
387 397
388 // Map from compile-time constants to their JS name. 398 // Map from compile-time constants to their JS name.
389 final Map<Constant, String> compiledConstants; 399 final Map<Constant, String> compiledConstants;
390 400
391 CompileTimeConstantHandler(Compiler compiler) 401 ConstantHandler(Compiler compiler)
392 : initialVariableValues = new Map<VariableElement, Dynamic>(), 402 : initialVariableValues = new Map<VariableElement, Dynamic>(),
393 compiledConstants = new Map<Constant, String>(), 403 compiledConstants = new Map<Constant, String>(),
394 super(compiler); 404 super(compiler);
395 String get name() => 'CompileTimeConstantHandler'; 405 String get name() => 'ConstantHandler';
396 406
397 void registerCompileTimeConstant(Constant constant) { 407 void registerCompileTimeConstant(Constant constant) {
398 Function ifAbsentThunk = (() => compiler.namer.getFreshGlobalName("CTC")); 408 Function ifAbsentThunk = (() => compiler.namer.getFreshGlobalName("CTC"));
399 compiledConstants.putIfAbsent(constant, ifAbsentThunk); 409 compiledConstants.putIfAbsent(constant, ifAbsentThunk);
400 } 410 }
401 411
402 /** 412 /**
403 * Compiles the initial value of the given field and stores it in an internal 413 * Compiles the initial value of the given field and stores it in an internal
404 * map. 414 * map.
405 * 415 *
406 * [WorkItem] must contain a [VariableElement] refering to a global or 416 * [WorkItem] must contain a [VariableElement] refering to a global or
407 * static field. 417 * static field.
408 */ 418 */
409 void compileWorkItem(WorkItem work) { 419 void compileWorkItem(WorkItem work) {
410 assert(work.element.kind == ElementKind.FIELD 420 assert(work.element.kind == ElementKind.FIELD
411 || work.element.kind == ElementKind.PARAMETER); 421 || work.element.kind == ElementKind.PARAMETER);
412 VariableElement element = work.element; 422 VariableElement element = work.element;
413 // Shortcut if it has already been compiled. 423 // Shortcut if it has already been compiled.
414 if (initialVariableValues.containsKey(element)) return; 424 if (initialVariableValues.containsKey(element)) return;
415 compileVariableWithDefinitions(element, work.resolutionTree); 425 compileVariableWithDefinitions(element, work.resolutionTree);
416 } 426 }
417 427
418 compileVariable(VariableElement element) { 428 compileVariable(VariableElement element) {
419 if (initialVariableValues.containsKey(element)) { 429 if (initialVariableValues.containsKey(element)) {
420 Constant result = initialVariableValues[element]; 430 Constant result = initialVariableValues[element];
421 // TODO(floitsch): remove the following line once the rest of the
422 // compiler has been adapted.
423 if (!result.isObject()) return result.dynamic.value;
424 return result; 431 return result;
425 } 432 }
426 // TODO(floitsch): keep track of currently compiling elements so that we 433 // TODO(floitsch): keep track of currently compiling elements so that we
427 // don't end up in an infinite loop: final x = y; final y = x; 434 // don't end up in an infinite loop: final x = y; final y = x;
428 TreeElements definitions = compiler.analyzeElement(element); 435 TreeElements definitions = compiler.analyzeElement(element);
429 Constant constant = compileVariableWithDefinitions(element, definitions); 436 Constant constant = compileVariableWithDefinitions(element, definitions);
430 // TODO(floitsch): remove the following line once the rest of the
431 // compiler has been adapted.
432 if (!constant.isObject()) return constant.dynamic.value;
433 return constant; 437 return constant;
434 } 438 }
435 439
436 compileVariableWithDefinitions(VariableElement element, 440 compileVariableWithDefinitions(VariableElement element,
437 TreeElements definitions) { 441 TreeElements definitions) {
438 return measure(() { 442 return measure(() {
439 Node node = element.parseNode(compiler); 443 Node node = element.parseNode(compiler);
440 assert(node !== null); 444 assert(node !== null);
441 SendSet assignment = node.asSendSet(); 445 SendSet assignment = node.asSendSet();
442 var value; 446 var value;
443 if (assignment === null) { 447 if (assignment === null) {
444 // No initial value. 448 // No initial value.
445 value = const NullConstant(); 449 value = const NullConstant();
446 } else { 450 } else {
447 Node right = assignment.arguments.head; 451 Node right = assignment.arguments.head;
448 CompileTimeConstantEvaluator evaluator = 452 CompileTimeConstantEvaluator evaluator =
449 new CompileTimeConstantEvaluator(this, definitions, compiler); 453 new CompileTimeConstantEvaluator(this, definitions, compiler);
450 value = evaluator.evaluate(right); 454 value = evaluator.evaluate(right);
451 } 455 }
452 initialVariableValues[element] = value; 456 initialVariableValues[element] = value;
453 return value; 457 return value;
454 }); 458 });
455 } 459 }
456 460
457 ConstructedConstant compileObjectConstruction(Node node, 461 ConstructedConstant compileObjectConstruction(Node node,
458 Type type, 462 Type type,
459 List arguments) { 463 List arguments) {
460 if (!arguments.isEmpty()) { 464 if (!arguments.isEmpty()) {
461 compiler.unimplemented("CompileTimeConstantHandler with arguments", 465 compiler.unimplemented("ConstantHandler with arguments", node: node);
462 node: node);
463 } 466 }
464 ClassElement classElement = type.element; 467 ClassElement classElement = type.element;
465 for (Element member in classElement.members) { 468 for (Element member in classElement.members) {
466 if (Elements.isInstanceField(member)) { 469 if (Elements.isInstanceField(member)) {
467 compiler.unimplemented("CompileTimeConstantHandler with fields", 470 compiler.unimplemented("ConstantHandler with fields", node: node);
468 node: node);
469 } 471 }
470 } 472 }
471 if (classElement.superclass != compiler.coreLibrary.find(Types.OBJECT)) { 473 if (classElement.superclass != compiler.coreLibrary.find(Types.OBJECT)) {
472 compiler.unimplemented("CompileTimeConstantHandler with super", 474 compiler.unimplemented("ConstantHandler with super", node: node);
473 node: node);
474 } 475 }
475 compiler.registerInstantiatedClass(classElement); 476 compiler.registerInstantiatedClass(classElement);
476 Constant constant = new ConstructedConstant(type, arguments); 477 Constant constant = new ConstructedConstant(type, arguments);
477 registerCompileTimeConstant(constant); 478 registerCompileTimeConstant(constant);
478 return constant; 479 return constant;
479 } 480 }
480 481
481 ListConstant compileListLiteral(Node node, 482 ListConstant compileListLiteral(Node node,
482 Type type, 483 Type type,
483 List<Constant> arguments) { 484 List<Constant> arguments) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } 601 }
601 } 602 }
602 } 603 }
603 604
604 String getJsConstructor(ClassElement element) { 605 String getJsConstructor(ClassElement element) {
605 return compiler.namer.isolatePropertyAccess(element); 606 return compiler.namer.isolatePropertyAccess(element);
606 } 607 }
607 } 608 }
608 609
609 class CompileTimeConstantEvaluator extends AbstractVisitor { 610 class CompileTimeConstantEvaluator extends AbstractVisitor {
610 final CompileTimeConstantHandler constantHandler; 611 final ConstantHandler constantHandler;
611 final TreeElements definitions; 612 final TreeElements definitions;
612 final Compiler compiler; 613 final Compiler compiler;
613 614
614 CompileTimeConstantEvaluator(this.constantHandler, 615 CompileTimeConstantEvaluator(this.constantHandler,
615 this.definitions, 616 this.definitions,
616 this.compiler); 617 this.compiler);
617 618
618 Constant evaluate(Node node) { 619 Constant evaluate(Node node) {
619 return node.accept(this); 620 return node.accept(this);
620 } 621 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 } 664 }
664 665
665 // TODO(floitsch): provide better error-messages. 666 // TODO(floitsch): provide better error-messages.
666 visitSend(Send send) { 667 visitSend(Send send) {
667 Element element = definitions[send]; 668 Element element = definitions[send];
668 if (Elements.isStaticOrTopLevelField(element)) { 669 if (Elements.isStaticOrTopLevelField(element)) {
669 if (element.modifiers === null || 670 if (element.modifiers === null ||
670 !element.modifiers.isFinal()) { 671 !element.modifiers.isFinal()) {
671 error(send); 672 error(send);
672 } 673 }
673 // TODO(floitsch): compileVariable temporarily returns primitives, so 674 return constantHandler.compileVariable(element);
674 // that the rest of the compiler can be adapted incrementally. Therefore
675 // we have to get the constant from the hashtable instead of using the
676 // returned result directly.
677 constantHandler.compileVariable(element);
678 return constantHandler.initialVariableValues[element];
679 } else if (send.isPrefix) { 675 } else if (send.isPrefix) {
680 assert(send.isOperator); 676 assert(send.isOperator);
681 Constant receiverConstant = evaluate(send.receiver); 677 Constant receiverConstant = evaluate(send.receiver);
682 Operator op = send.selector; 678 Operator op = send.selector;
683 Constant folded = receiverConstant.unaryFold(op.source.stringValue); 679 Constant folded = receiverConstant.unaryFold(op.source.stringValue);
684 if (folded === null) error(send); 680 if (folded === null) error(send);
685 return folded; 681 return folded;
686 } else if (send.isOperator && !send.isPostfix) { 682 } else if (send.isOperator && !send.isPostfix) {
687 assert(send.argumentCount() == 1); 683 assert(send.argumentCount() == 1);
688 Constant left = evaluate(send.receiver); 684 Constant left = evaluate(send.receiver);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 arguments); 718 arguments);
723 } 719 }
724 720
725 error(Node node) { 721 error(Node node) {
726 // TODO(floitsch): get the list of constants that are currently compiled 722 // TODO(floitsch): get the list of constants that are currently compiled
727 // and present some kind of stack-trace. 723 // and present some kind of stack-trace.
728 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 724 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
729 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); 725 compiler.reportError(node, new CompileTimeConstantError(kind, const []));
730 } 726 }
731 } 727 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/compiler.dart » ('j') | frog/leg/ssa/optimize.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698