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

Side by Side Diff: lib/compiler/implementation/compile_time_constants.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
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 bool isBool() => false; 9 bool isBool() => false;
10 bool isTrue() => false; 10 bool isTrue() => false;
11 bool isFalse() => false; 11 bool isFalse() => false;
12 bool isInt() => false; 12 bool isInt() => false;
13 bool isDouble() => false; 13 bool isDouble() => false;
14 bool isNum() => false; 14 bool isNum() => false;
15 bool isString() => false; 15 bool isString() => false;
16 bool isList() => false; 16 bool isList() => false;
17 bool isMap() => false; 17 bool isMap() => false;
18 bool isConstructedObject() => false; 18 bool isConstructedObject() => false;
19 /** Returns true if the constant is null, a bool, a number or a string. */ 19 /** Returns true if the constant is null, a bool, a number or a string. */
20 bool isPrimitive() => false; 20 bool isPrimitive() => false;
21 /** Returns true if the constant is a list, a map or a constructed object. */ 21 /** Returns true if the constant is a list, a map or a constructed object. */
22 bool isObject() => false; 22 bool isObject() => false;
23 23
24 bool isNaN() => false; 24 bool isNaN() => false;
25 bool isMinusZero() => false;
25 26
26 abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler); 27 abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler);
27 /** 28 /**
28 * Unless the constant can be emitted multiple times (as for numbers and 29 * Unless the constant can be emitted multiple times (as for numbers and
29 * strings) adds its canonical name to the buffer. 30 * strings) adds its canonical name to the buffer.
30 */ 31 */
31 abstract void _writeCanonicalizedJsCode(CodeBuffer buffer, 32 abstract void _writeCanonicalizedJsCode(CodeBuffer buffer,
32 ConstantHandler handler); 33 ConstantHandler handler);
33 abstract List<Constant> getDependencies(); 34 abstract List<Constant> getDependencies();
34 } 35 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return const DoubleConstant._internal(0.0); 134 return const DoubleConstant._internal(0.0);
134 } else if (value == 1.0) { 135 } else if (value == 1.0) {
135 return const DoubleConstant._internal(1.0); 136 return const DoubleConstant._internal(1.0);
136 } else { 137 } else {
137 return new DoubleConstant._internal(value); 138 return new DoubleConstant._internal(value);
138 } 139 }
139 } 140 }
140 const DoubleConstant._internal(this.value); 141 const DoubleConstant._internal(this.value);
141 bool isDouble() => true; 142 bool isDouble() => true;
142 bool isNaN() => value.isNaN(); 143 bool isNaN() => value.isNaN();
144 bool isMinusZero() => value == 0.0 && value.isNegative();
ngeoffray 2012/08/17 08:32:59 Please add a comment why -0.0 doesn't work.
floitsch 2012/09/03 14:34:52 Done.
143 145
144 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { 146 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) {
145 if (value.isNaN()) { 147 if (value.isNaN()) {
146 buffer.add("(0/0)"); 148 buffer.add("(0/0)");
147 } else if (value == double.INFINITY) { 149 } else if (value == double.INFINITY) {
148 buffer.add("(1/0)"); 150 buffer.add("(1/0)");
149 } else if (value == -double.INFINITY) { 151 } else if (value == -double.INFINITY) {
150 buffer.add("(-1/0)"); 152 buffer.add("(-1/0)");
151 } else { 153 } else {
152 buffer.add("$value"); 154 buffer.add("$value");
(...skipping 17 matching lines...) Expand all
170 DartString toDartString() => new DartString.literal(value.toString()); 172 DartString toDartString() => new DartString.literal(value.toString());
171 } 173 }
172 174
173 class BoolConstant extends PrimitiveConstant { 175 class BoolConstant extends PrimitiveConstant {
174 factory BoolConstant(value) { 176 factory BoolConstant(value) {
175 return value ? new TrueConstant() : new FalseConstant(); 177 return value ? new TrueConstant() : new FalseConstant();
176 } 178 }
177 const BoolConstant._internal(); 179 const BoolConstant._internal();
178 bool isBool() => true; 180 bool isBool() => true;
179 181
180 BoolConstant unaryFold(String op) {
181 if (op == "!") return new BoolConstant(!value);
182 return null;
183 }
184
185 abstract BoolConstant negate(); 182 abstract BoolConstant negate();
186 } 183 }
187 184
188 class TrueConstant extends BoolConstant { 185 class TrueConstant extends BoolConstant {
189 final bool value = true; 186 final bool value = true;
190 187
191 factory TrueConstant() => const TrueConstant._internal(); 188 factory TrueConstant() => const TrueConstant._internal();
192 const TrueConstant._internal() : super._internal(); 189 const TrueConstant._internal() : super._internal();
193 bool isTrue() => true; 190 bool isTrue() => true;
194 191
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 int hashCode() => _hashCode; 471 int hashCode() => _hashCode;
475 List<Constant> getDependencies() => fields; 472 List<Constant> getDependencies() => fields;
476 } 473 }
477 474
478 /** 475 /**
479 * The [ConstantHandler] keeps track of compile-time constants, 476 * The [ConstantHandler] keeps track of compile-time constants,
480 * initializations of global and static fields, and default values of 477 * initializations of global and static fields, and default values of
481 * optional parameters. 478 * optional parameters.
482 */ 479 */
483 class ConstantHandler extends CompilerTask { 480 class ConstantHandler extends CompilerTask {
481 final FoldingOperations foldingOperations;
484 // Contains the initial value of fields. Must contain all static and global 482 // Contains the initial value of fields. Must contain all static and global
485 // initializations of used fields. May contain caches for instance fields. 483 // initializations of used fields. May contain caches for instance fields.
486 final Map<VariableElement, Constant> initialVariableValues; 484 final Map<VariableElement, Constant> initialVariableValues;
487 485
488 // Map from compile-time constants to their JS name. 486 // Map from compile-time constants to their JS name.
489 final Map<Constant, String> compiledConstants; 487 final Map<Constant, String> compiledConstants;
490 488
491 // The set of variable elements that are in the process of being computed. 489 // The set of variable elements that are in the process of being computed.
492 final Set<VariableElement> pendingVariables; 490 final Set<VariableElement> pendingVariables;
493 491
494 ConstantHandler(Compiler compiler) 492 ConstantHandler(Compiler compiler, this.foldingOperations)
495 : initialVariableValues = new Map<VariableElement, Dynamic>(), 493 : initialVariableValues = new Map<VariableElement, Dynamic>(),
496 compiledConstants = new Map<Constant, String>(), 494 compiledConstants = new Map<Constant, String>(),
497 pendingVariables = new Set<VariableElement>(), 495 pendingVariables = new Set<VariableElement>(),
498 super(compiler); 496 super(compiler);
499 String get name() => 'ConstantHandler'; 497 String get name() => 'ConstantHandler';
500 498
501 void registerCompileTimeConstant(Constant constant) { 499 void registerCompileTimeConstant(Constant constant) {
502 Function ifAbsentThunk = (() => compiler.namer.getFreshGlobalName("CTC")); 500 Function ifAbsentThunk = (() => compiler.namer.getFreshGlobalName("CTC"));
503 compiledConstants.putIfAbsent(constant, ifAbsentThunk); 501 compiledConstants.putIfAbsent(constant, ifAbsentThunk);
504 } 502 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 555 }
558 initialVariableValues[element] = value; 556 initialVariableValues[element] = value;
559 pendingVariables.remove(element); 557 pendingVariables.remove(element);
560 return value; 558 return value;
561 }); 559 });
562 } 560 }
563 561
564 Constant compileNodeWithDefinitions(Node node, TreeElements definitions) { 562 Constant compileNodeWithDefinitions(Node node, TreeElements definitions) {
565 return measure(() { 563 return measure(() {
566 assert(node !== null); 564 assert(node !== null);
567 CompileTimeConstantEvaluator evaluator = 565 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
568 new CompileTimeConstantEvaluator(definitions, compiler); 566 foldingOperations, definitions, compiler);
569 return evaluator.evaluate(node); 567 return evaluator.evaluate(node);
570 }); 568 });
571 } 569 }
572 570
573 /** Attempts to compile a constant expression. Returns null if not possible */ 571 /** Attempts to compile a constant expression. Returns null if not possible */
574 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { 572 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) {
575 return measure(() { 573 return measure(() {
576 assert(node !== null); 574 assert(node !== null);
577 try { 575 try {
578 TryCompileTimeConstantEvaluator evaluator = 576 TryCompileTimeConstantEvaluator evaluator =
579 new TryCompileTimeConstantEvaluator(definitions, compiler); 577 new TryCompileTimeConstantEvaluator(foldingOperations,
578 definitions,
579 compiler);
580 return evaluator.evaluate(node); 580 return evaluator.evaluate(node);
581 } catch (CompileTimeConstantError exn) { 581 } catch (CompileTimeConstantError exn) {
582 return null; 582 return null;
583 } 583 }
584 }); 584 });
585 } 585 }
586 586
587 /** 587 /**
588 * Returns a [List] of static non final fields that need to be initialized. 588 * Returns a [List] of static non final fields that need to be initialized.
589 * The list must be evaluated in order since the fields might depend on each 589 * The list must be evaluated in order since the fields might depend on each
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 706 }
707 } 707 }
708 } 708 }
709 709
710 String getJsConstructor(ClassElement element) { 710 String getJsConstructor(ClassElement element) {
711 return compiler.namer.isolatePropertiesAccess(element); 711 return compiler.namer.isolatePropertiesAccess(element);
712 } 712 }
713 } 713 }
714 714
715 class CompileTimeConstantEvaluator extends AbstractVisitor { 715 class CompileTimeConstantEvaluator extends AbstractVisitor {
716 final FoldingOperations foldingOperations;
716 final TreeElements elements; 717 final TreeElements elements;
717 final Compiler compiler; 718 final Compiler compiler;
718 719
719 CompileTimeConstantEvaluator(this.elements, this.compiler); 720 CompileTimeConstantEvaluator(this.foldingOperations,
721 this.elements,
722 this.compiler);
720 723
721 Constant evaluate(Node node) { 724 Constant evaluate(Node node) {
722 return node.accept(this); 725 return node.accept(this);
723 } 726 }
724 727
725 visitNode(Node node) { 728 visitNode(Node node) {
726 error(node); 729 error(node);
727 } 730 }
728 731
729 Constant visitLiteralBool(LiteralBool node) { 732 Constant visitLiteralBool(LiteralBool node) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 error(send); 846 error(send);
844 } 847 }
845 return compiler.compileVariable(element); 848 return compiler.compileVariable(element);
846 } else if (send.isPrefix) { 849 } else if (send.isPrefix) {
847 assert(send.isOperator); 850 assert(send.isOperator);
848 Constant receiverConstant = evaluate(send.receiver); 851 Constant receiverConstant = evaluate(send.receiver);
849 Operator op = send.selector; 852 Operator op = send.selector;
850 Constant folded; 853 Constant folded;
851 switch (op.source.stringValue) { 854 switch (op.source.stringValue) {
852 case "!": 855 case "!":
853 folded = const NotOperation().fold(receiverConstant); 856 folded = foldingOperations.not.fold(receiverConstant);
854 break; 857 break;
855 case "-": 858 case "-":
856 folded = const NegateOperation().fold(receiverConstant); 859 folded = foldingOperations.negate.fold(receiverConstant);
857 break; 860 break;
858 case "~": 861 case "~":
859 folded = const BitNotOperation().fold(receiverConstant); 862 folded = foldingOperations.bitNot.fold(receiverConstant);
860 break; 863 break;
861 default: 864 default:
862 compiler.internalError("Unexpected operator.", node: op); 865 compiler.internalError("Unexpected operator.", node: op);
863 break; 866 break;
864 } 867 }
865 if (folded === null) error(send); 868 if (folded === null) error(send);
866 return folded; 869 return folded;
867 } else if (send.isOperator && !send.isPostfix) { 870 } else if (send.isOperator && !send.isPostfix) {
868 assert(send.argumentCount() == 1); 871 assert(send.argumentCount() == 1);
869 Constant left = evaluate(send.receiver); 872 Constant left = evaluate(send.receiver);
870 Constant right = evaluate(send.argumentsNode.nodes.head); 873 Constant right = evaluate(send.argumentsNode.nodes.head);
871 Operator op = send.selector.asOperator(); 874 Operator op = send.selector.asOperator();
872 Constant folded = null; 875 Constant folded = null;
873 switch (op.source.stringValue) { 876 switch (op.source.stringValue) {
874 case "+": 877 case "+":
875 folded = const AddOperation().fold(left, right); 878 folded = foldingOperations.add.fold(left, right);
876 break; 879 break;
877 case "-": 880 case "-":
878 folded = const SubtractOperation().fold(left, right); 881 folded = foldingOperations.subtract.fold(left, right);
879 break; 882 break;
880 case "*": 883 case "*":
881 folded = const MultiplyOperation().fold(left, right); 884 folded = foldingOperations.multiply.fold(left, right);
882 break; 885 break;
883 case "/": 886 case "/":
884 folded = const DivideOperation().fold(left, right); 887 folded = foldingOperations.divide.fold(left, right);
885 break; 888 break;
886 case "%": 889 case "%":
887 folded = const ModuloOperation().fold(left, right); 890 folded = foldingOperations.modulo.fold(left, right);
888 break; 891 break;
889 case "~/": 892 case "~/":
890 folded = const TruncatingDivideOperation().fold(left, right); 893 folded = foldingOperations.truncatingDivide.fold(left, right);
891 break; 894 break;
892 case "|": 895 case "|":
893 folded = const BitOrOperation().fold(left, right); 896 folded = foldingOperations.bitOr.fold(left, right);
894 break; 897 break;
895 case "&": 898 case "&":
896 folded = const BitAndOperation().fold(left, right); 899 folded = foldingOperations.bitAnd.fold(left, right);
897 break; 900 break;
898 case "^": 901 case "^":
899 folded = const BitXorOperation().fold(left, right); 902 folded = foldingOperations.bitXor.fold(left, right);
900 break; 903 break;
901 case "||": 904 case "||":
902 folded = const BooleanOr().fold(left, right); 905 folded = foldingOperations.booleanOr.fold(left, right);
903 break; 906 break;
904 case "&&": 907 case "&&":
905 folded = const BooleanAnd().fold(left, right); 908 folded = foldingOperations.booleanAnd.fold(left, right);
906 break; 909 break;
907 case "<<": 910 case "<<":
908 folded = const ShiftLeftOperation().fold(left, right); 911 folded = foldingOperations.shiftLeft.fold(left, right);
909 break; 912 break;
910 case ">>": 913 case ">>":
911 folded = const ShiftRightOperation().fold(left, right); 914 folded = foldingOperations.shiftRight.fold(left, right);
912 break; 915 break;
913 case "<": 916 case "<":
914 folded = const LessOperation().fold(left, right); 917 folded = foldingOperations.less.fold(left, right);
915 break; 918 break;
916 case "<=": 919 case "<=":
917 folded = const LessEqualOperation().fold(left, right); 920 folded = foldingOperations.lessEqual.fold(left, right);
918 break; 921 break;
919 case ">": 922 case ">":
920 folded = const GreaterOperation().fold(left, right); 923 folded = foldingOperations.greater.fold(left, right);
921 break; 924 break;
922 case ">=": 925 case ">=":
923 folded = const GreaterEqualOperation().fold(left, right); 926 folded = foldingOperations.greaterEqual.fold(left, right);
924 break; 927 break;
925 case "==": 928 case "==":
926 if (left.isPrimitive() && right.isPrimitive()) { 929 if (left.isPrimitive() && right.isPrimitive()) {
927 folded = const EqualsOperation().fold(left, right); 930 folded = foldingOperations.equal.fold(left, right);
928 } 931 }
929 break; 932 break;
930 case "===": 933 case "===":
931 if (left.isPrimitive() && right.isPrimitive()) { 934 if (left.isPrimitive() && right.isPrimitive()) {
932 folded = const IdentityOperation().fold(left, right); 935 folded = foldingOperations.identity.fold(left, right);
933 } 936 }
934 break; 937 break;
935 case "!=": 938 case "!=":
936 if (left.isPrimitive() && right.isPrimitive()) { 939 if (left.isPrimitive() && right.isPrimitive()) {
937 BoolConstant areEquals = const EqualsOperation().fold(left, right); 940 BoolConstant areEquals = foldingOperations.equal.fold(left, right);
938 if (areEquals === null) { 941 if (areEquals === null) {
939 folded = null; 942 folded = null;
940 } else { 943 } else {
941 folded = areEquals.negate(); 944 folded = areEquals.negate();
942 } 945 }
943 } 946 }
944 break; 947 break;
945 case "!==": 948 case "!==":
946 if (left.isPrimitive() && right.isPrimitive()) { 949 if (left.isPrimitive() && right.isPrimitive()) {
947 BoolConstant areIdentical = 950 BoolConstant areIdentical =
948 const IdentityOperation().fold(left, right); 951 foldingOperations.identity.fold(left, right);
949 if (areIdentical === null) { 952 if (areIdentical === null) {
950 folded = null; 953 folded = null;
951 } else { 954 } else {
952 folded = areIdentical.negate(); 955 folded = areIdentical.negate();
953 } 956 }
954 } 957 }
955 break; 958 break;
956 } 959 }
957 if (folded === null) error(send); 960 if (folded === null) error(send);
958 return folded; 961 return folded;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 if (classElement.isInterface()) { 994 if (classElement.isInterface()) {
992 compiler.resolver.resolveMethodElement(constructor); 995 compiler.resolver.resolveMethodElement(constructor);
993 constructor = constructor.defaultImplementation; 996 constructor = constructor.defaultImplementation;
994 classElement = constructor.getEnclosingClass(); 997 classElement = constructor.getEnclosingClass();
995 } 998 }
996 999
997 Selector selector = elements.getSelector(send); 1000 Selector selector = elements.getSelector(send);
998 List<Constant> arguments = 1001 List<Constant> arguments =
999 evaluateArgumentsToConstructor(selector, send.arguments, constructor); 1002 evaluateArgumentsToConstructor(selector, send.arguments, constructor);
1000 ConstructorEvaluator evaluator = 1003 ConstructorEvaluator evaluator =
1001 new ConstructorEvaluator(constructor, compiler); 1004 new ConstructorEvaluator(constructor, foldingOperations, compiler);
1002 evaluator.evaluateConstructorFieldValues(arguments); 1005 evaluator.evaluateConstructorFieldValues(arguments);
1003 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); 1006 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
1004 1007
1005 compiler.registerInstantiatedClass(classElement); 1008 compiler.registerInstantiatedClass(classElement);
1006 // TODO(floitsch): take generic types into account. 1009 // TODO(floitsch): take generic types into account.
1007 Type type = classElement.computeType(compiler); 1010 Type type = classElement.computeType(compiler);
1008 Constant constant = new ConstructedConstant(type, jsNewArguments); 1011 Constant constant = new ConstructedConstant(type, jsNewArguments);
1009 compiler.constantHandler.registerCompileTimeConstant(constant); 1012 compiler.constantHandler.registerCompileTimeConstant(constant);
1010 return constant; 1013 return constant;
1011 } 1014 }
1012 1015
1013 Constant visitParenthesizedExpression(ParenthesizedExpression node) { 1016 Constant visitParenthesizedExpression(ParenthesizedExpression node) {
1014 return node.expression.accept(this); 1017 return node.expression.accept(this);
1015 } 1018 }
1016 1019
1017 error(Node node) { 1020 error(Node node) {
1018 // TODO(floitsch): get the list of constants that are currently compiled 1021 // TODO(floitsch): get the list of constants that are currently compiled
1019 // and present some kind of stack-trace. 1022 // and present some kind of stack-trace.
1020 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 1023 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
1021 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); 1024 compiler.reportError(node, new CompileTimeConstantError(kind, const []));
1022 } 1025 }
1023 } 1026 }
1024 1027
1025 class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator { 1028 class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator {
1026 TryCompileTimeConstantEvaluator(TreeElements elements, Compiler compiler): 1029 TryCompileTimeConstantEvaluator(FoldingOperations foldingOperations,
1027 super(elements, compiler); 1030 TreeElements elements,
1031 Compiler compiler):
1032 super(foldingOperations, elements, compiler);
1028 1033
1029 error(Node node) { 1034 error(Node node) {
1030 // Just fail without reporting it anywhere. 1035 // Just fail without reporting it anywhere.
1031 throw new CompileTimeConstantError( 1036 throw new CompileTimeConstantError(
1032 MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []); 1037 MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []);
1033 } 1038 }
1034 } 1039 }
1035 1040
1036 class ConstructorEvaluator extends CompileTimeConstantEvaluator { 1041 class ConstructorEvaluator extends CompileTimeConstantEvaluator {
1037 FunctionElement constructor; 1042 FunctionElement constructor;
1038 final Map<Element, Constant> definitions; 1043 final Map<Element, Constant> definitions;
1039 final Map<Element, Constant> fieldValues; 1044 final Map<Element, Constant> fieldValues;
1040 1045
1041 ConstructorEvaluator(FunctionElement constructor, Compiler compiler) 1046 ConstructorEvaluator(FunctionElement constructor,
1047 FoldingOperations foldingOperations,
1048 Compiler compiler)
1042 : this.constructor = constructor, 1049 : this.constructor = constructor,
1043 this.definitions = new Map<Element, Constant>(), 1050 this.definitions = new Map<Element, Constant>(),
1044 this.fieldValues = new Map<Element, Constant>(), 1051 this.fieldValues = new Map<Element, Constant>(),
1045 super(compiler.resolver.resolveMethodElement(constructor), 1052 super(foldingOperations,
1053 compiler.resolver.resolveMethodElement(constructor),
1046 compiler); 1054 compiler);
1047 1055
1048 Constant visitSend(Send send) { 1056 Constant visitSend(Send send) {
1049 Element element = elements[send]; 1057 Element element = elements[send];
1050 if (Elements.isLocal(element)) { 1058 if (Elements.isLocal(element)) {
1051 Constant constant = definitions[element]; 1059 Constant constant = definitions[element];
1052 if (constant === null) { 1060 if (constant === null) {
1053 compiler.internalError("Local variable without value", node: send); 1061 compiler.internalError("Local variable without value", node: send);
1054 } 1062 }
1055 return constant; 1063 return constant;
(...skipping 19 matching lines...) Expand all
1075 } 1083 }
1076 }); 1084 });
1077 } 1085 }
1078 1086
1079 void evaluateSuperOrRedirectSend(Selector selector, 1087 void evaluateSuperOrRedirectSend(Selector selector,
1080 Link<Node> arguments, 1088 Link<Node> arguments,
1081 FunctionElement targetConstructor) { 1089 FunctionElement targetConstructor) {
1082 List<Constant> compiledArguments = 1090 List<Constant> compiledArguments =
1083 evaluateArgumentsToConstructor(selector, arguments, targetConstructor); 1091 evaluateArgumentsToConstructor(selector, arguments, targetConstructor);
1084 1092
1085 ConstructorEvaluator evaluator = 1093 ConstructorEvaluator evaluator = new ConstructorEvaluator(
1086 new ConstructorEvaluator(targetConstructor, compiler); 1094 targetConstructor, foldingOperations, compiler);
1087 evaluator.evaluateConstructorFieldValues(compiledArguments); 1095 evaluator.evaluateConstructorFieldValues(compiledArguments);
1088 // Copy over the fieldValues from the super/redirect-constructor. 1096 // Copy over the fieldValues from the super/redirect-constructor.
1089 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); 1097 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
1090 } 1098 }
1091 1099
1092 /** 1100 /**
1093 * Runs through the initializers of the given [constructor] and updates 1101 * Runs through the initializers of the given [constructor] and updates
1094 * the [fieldValues] map. 1102 * the [fieldValues] map.
1095 */ 1103 */
1096 void evaluateConstructorInitializers() { 1104 void evaluateConstructorInitializers() {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 Constant fieldValue = fieldValues[field]; 1177 Constant fieldValue = fieldValues[field];
1170 if (fieldValue === null) { 1178 if (fieldValue === null) {
1171 // Use the default value. 1179 // Use the default value.
1172 fieldValue = compiler.compileVariable(field); 1180 fieldValue = compiler.compileVariable(field);
1173 } 1181 }
1174 jsNewArguments.add(fieldValue); 1182 jsNewArguments.add(fieldValue);
1175 }); 1183 });
1176 return jsNewArguments; 1184 return jsNewArguments;
1177 } 1185 }
1178 } 1186 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698