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

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

Issue 25478009: Handle compile-time constness for conditionals and type literal calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 unified diff | Download patch | Annotate | Revision Log
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 part of dart2js; 5 part of dart2js;
6 6
7 /** 7 /**
8 * The [ConstantHandler] keeps track of compile-time constants, 8 * The [ConstantHandler] keeps track of compile-time constants,
9 * initializations of global and static fields, and default values of 9 * initializations of global and static fields, and default values of
10 * optional parameters. 10 * optional parameters.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 /** 84 /**
85 * Returns the a compile-time constant if the variable could be compiled 85 * Returns the a compile-time constant if the variable could be compiled
86 * eagerly. If the variable needs to be initialized lazily returns `null`. 86 * eagerly. If the variable needs to be initialized lazily returns `null`.
87 * If the variable is `const` but cannot be compiled eagerly reports an 87 * If the variable is `const` but cannot be compiled eagerly reports an
88 * error. 88 * error.
89 */ 89 */
90 Constant compileVariableWithDefinitions(VariableElement element, 90 Constant compileVariableWithDefinitions(VariableElement element,
91 TreeElements definitions, 91 TreeElements definitions,
92 {bool isConst: false}) { 92 {bool isConst: false}) {
93 return measure(() { 93 return measure(() {
94 // Initializers for parameters must be const.
95 isConst = isConst || element.modifiers.isConst()
96 || !Elements.isStaticOrTopLevel(element);
97 if (!isConst && lazyStatics.contains(element)) return null; 94 if (!isConst && lazyStatics.contains(element)) return null;
98 95
99 Node node = element.parseNode(compiler); 96 Node node = element.parseNode(compiler);
100 if (pendingVariables.contains(element)) { 97 if (pendingVariables.contains(element)) {
101 if (isConst) { 98 if (isConst) {
102 compiler.reportFatalError( 99 compiler.reportFatalError(
103 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); 100 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
104 } else { 101 } else {
105 lazyStatics.add(element); 102 lazyStatics.add(element);
106 return null; 103 return null;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 pendingVariables.remove(element); 141 pendingVariables.remove(element);
145 return value; 142 return value;
146 }); 143 });
147 } 144 }
148 145
149 Constant compileNodeWithDefinitions(Node node, 146 Constant compileNodeWithDefinitions(Node node,
150 TreeElements definitions, 147 TreeElements definitions,
151 {bool isConst: false}) { 148 {bool isConst: false}) {
152 return measure(() { 149 return measure(() {
153 assert(node != null); 150 assert(node != null);
151 Constant constant = definitions.getConstant(node);
152 if (constant != null) {
153 return constant;
154 }
154 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( 155 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
155 this, definitions, compiler, isConst: isConst); 156 this, definitions, compiler, isConst: isConst);
156 return evaluator.evaluate(node); 157 constant = evaluator.evaluate(node);
158 if (constant != null) {
159 definitions.setConstant(node, constant);
160 }
161 return constant;
157 }); 162 });
158 } 163 }
159 164
160 /** 165 /**
161 * Returns an [Iterable] of static non final fields that need to be 166 * Returns an [Iterable] of static non final fields that need to be
162 * initialized. The fields list must be evaluated in order since they might 167 * initialized. The fields list must be evaluated in order since they might
163 * depend on each other. 168 * depend on each other.
164 */ 169 */
165 Iterable<VariableElement> getStaticNonFinalFieldsForEmission() { 170 Iterable<VariableElement> getStaticNonFinalFieldsForEmission() {
166 return initialVariableValues.keys.where((element) { 171 return initialVariableValues.keys.where((element) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 List<Constant> createArguments(_) { 395 List<Constant> createArguments(_) {
391 return [constantSystem.createString( 396 return [constantSystem.createString(
392 new DartString.literal(node.slowNameString), node)]; 397 new DartString.literal(node.slowNameString), node)];
393 } 398 }
394 return makeConstructedConstant( 399 return makeConstructedConstant(
395 node, type, compiler.symbolConstructor, createArguments); 400 node, type, compiler.symbolConstructor, createArguments);
396 } 401 }
397 402
398 Constant makeTypeConstant(Element element) { 403 Constant makeTypeConstant(Element element) {
399 DartType elementType = element.computeType(compiler).asRaw(); 404 DartType elementType = element.computeType(compiler).asRaw();
400 compiler.backend.registerTypeLiteral( 405 compiler.backend.registerTypeLiteral(
karlklose 2013/10/02 11:08:55 Move this registration.
Johnni Winther 2013/10/02 12:39:33 Done.
401 element, compiler.enqueuer.codegen, elements); 406 element, compiler.enqueuer.codegen, elements);
402 DartType constantType = 407 DartType constantType =
403 compiler.backend.typeImplementation.computeType(compiler); 408 compiler.backend.typeImplementation.computeType(compiler);
404 return new TypeConstant(elementType, constantType); 409 return new TypeConstant(elementType, constantType);
405 } 410 }
406 411
407 // TODO(floitsch): provide better error-messages. 412 // TODO(floitsch): provide better error-messages.
408 Constant visitSend(Send send) { 413 Constant visitSend(Send send) {
409 Element element = elements[send]; 414 Element element = elements[send];
410 if (send.isPropertyAccess) { 415 if (send.isPropertyAccess) {
411 if (Elements.isStaticOrTopLevelFunction(element)) { 416 if (Elements.isStaticOrTopLevelFunction(element)) {
412 return new FunctionConstant(element); 417 return new FunctionConstant(element);
413 } else if (Elements.isStaticOrTopLevelField(element)) { 418 } else if (Elements.isStaticOrTopLevelField(element)) {
414 Constant result; 419 Constant result;
415 if (element.modifiers.isConst()) { 420 if (element.modifiers.isConst()) {
416 result = handler.compileConstant(element); 421 result = handler.compileConstant(element);
417 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { 422 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) {
418 result = handler.compileVariable(element); 423 result = handler.compileVariable(element);
419 } 424 }
420 if (result != null) return result; 425 if (result != null) return result;
421 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { 426 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
427 assert(elements.isTypeLiteral(send));
422 return makeTypeConstant(element); 428 return makeTypeConstant(element);
423 } else if (send.receiver != null) { 429 } else if (send.receiver != null) {
424 // Fall through to error handling. 430 // Fall through to error handling.
425 } else if (!Elements.isUnresolved(element) 431 } else if (!Elements.isUnresolved(element)
426 && element.isVariable() 432 && element.isVariable()
427 && element.modifiers.isConst()) { 433 && element.modifiers.isConst()) {
428 Constant result = handler.compileConstant(element); 434 Constant result = handler.compileConstant(element);
429 if (result != null) return result; 435 if (result != null) return result;
430 } 436 }
431 return signalNotCompileTimeConstant(send); 437 return signalNotCompileTimeConstant(send);
432 } else if (send.isCall) { 438 } else if (send.isCall) {
433 if (identical(element, compiler.identicalFunction) 439 if (identical(element, compiler.identicalFunction)
434 && send.argumentCount() == 2) { 440 && send.argumentCount() == 2) {
435 Constant left = evaluate(send.argumentsNode.nodes.head); 441 Constant left = evaluate(send.argumentsNode.nodes.head);
436 Constant right = evaluate(send.argumentsNode.nodes.tail.head); 442 Constant right = evaluate(send.argumentsNode.nodes.tail.head);
437 Constant result = constantSystem.identity.fold(left, right); 443 Constant result = constantSystem.identity.fold(left, right);
438 if (result != null) return result; 444 if (result != null) return result;
439 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { 445 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
440 return makeTypeConstant(element); 446 // The node itself is not a constant but we register the selector (the
447 // identifier that refers to the class/typedef) as a constant.
448 Constant typeConstant = makeTypeConstant(element);
449 elements.setConstant(send.selector, typeConstant);
441 } 450 }
442 return signalNotCompileTimeConstant(send); 451 return signalNotCompileTimeConstant(send);
443 } else if (send.isPrefix) { 452 } else if (send.isPrefix) {
444 assert(send.isOperator); 453 assert(send.isOperator);
445 Constant receiverConstant = evaluate(send.receiver); 454 Constant receiverConstant = evaluate(send.receiver);
446 if (receiverConstant == null) return null; 455 if (receiverConstant == null) return null;
447 Operator op = send.selector; 456 Operator op = send.selector;
448 Constant folded; 457 Constant folded;
449 switch (op.source.stringValue) { 458 switch (op.source.stringValue) {
450 case "!": 459 case "!":
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 folded = areIdentical.negate(); 557 folded = areIdentical.negate();
549 } 558 }
550 break; 559 break;
551 } 560 }
552 if (folded == null) return signalNotCompileTimeConstant(send); 561 if (folded == null) return signalNotCompileTimeConstant(send);
553 return folded; 562 return folded;
554 } 563 }
555 return signalNotCompileTimeConstant(send); 564 return signalNotCompileTimeConstant(send);
556 } 565 }
557 566
567 Constant visitConditional(Conditional node) {
568 Constant condition = evaluate(node.condition);
569 if (condition == null || !condition.isBool()) {
570 return signalNotCompileTimeConstant(node);
ngeoffray 2013/10/02 10:44:43 IF condition is not bool, we might want a differen
Johnni Winther 2013/10/02 12:39:33 Done.
571 }
572 Constant thenExpression = evaluate(node.thenExpression);
573 Constant elseExpression = evaluate(node.elseExpression);
ngeoffray 2013/10/02 10:44:43 IS evaluating both expressions a requirement from
Johnni Winther 2013/10/02 12:39:33 We don't need to evaluate them but we need to chec
574 BoolConstant boolCondition = condition;
575 return boolCondition.value ? thenExpression : elseExpression;
576 }
577
558 Constant visitSendSet(SendSet node) { 578 Constant visitSendSet(SendSet node) {
559 return signalNotCompileTimeConstant(node); 579 return signalNotCompileTimeConstant(node);
560 } 580 }
561 581
562 /** 582 /**
563 * Returns the list of constants that are passed to the static function. 583 * Returns the list of constants that are passed to the static function.
564 * 584 *
565 * Invariant: [target] must be an implementation element. 585 * Invariant: [target] must be an implementation element.
566 */ 586 */
567 List<Constant> evaluateArgumentsToConstructor(Node node, 587 List<Constant> evaluateArgumentsToConstructor(Node node,
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 if (fieldValue == null) { 872 if (fieldValue == null) {
853 // Use the default value. 873 // Use the default value.
854 fieldValue = handler.compileConstant(field); 874 fieldValue = handler.compileConstant(field);
855 } 875 }
856 jsNewArguments.add(fieldValue); 876 jsNewArguments.add(fieldValue);
857 }, 877 },
858 includeSuperAndInjectedMembers: true); 878 includeSuperAndInjectedMembers: true);
859 return jsNewArguments; 879 return jsNewArguments;
860 } 880 }
861 } 881 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698