OLD | NEW |
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 Interceptors { | 5 class Interceptors { |
6 Compiler compiler; | 6 Compiler compiler; |
7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
8 | 8 |
9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 constructor, | 997 constructor, |
998 compiledArguments); | 998 compiledArguments); |
999 if (!succeeded) { | 999 if (!succeeded) { |
1000 // Non-matching super and redirects are compile-time errors and thus | 1000 // Non-matching super and redirects are compile-time errors and thus |
1001 // checked by the resolver. | 1001 // checked by the resolver. |
1002 compiler.internalError( | 1002 compiler.internalError( |
1003 "Parameters and arguments didn't match for super/redirect call", | 1003 "Parameters and arguments didn't match for super/redirect call", |
1004 element: constructor); | 1004 element: constructor); |
1005 } | 1005 } |
1006 | 1006 |
| 1007 buildFieldInitializers(constructor.enclosingElement, fieldValues); |
| 1008 |
1007 int index = 0; | 1009 int index = 0; |
1008 FunctionSignature params = constructor.computeSignature(compiler); | 1010 FunctionSignature params = constructor.computeSignature(compiler); |
1009 params.forEachParameter((Element parameter) { | 1011 params.forEachParameter((Element parameter) { |
1010 HInstruction argument = compiledArguments[index++]; | 1012 HInstruction argument = compiledArguments[index++]; |
1011 localsHandler.updateLocal(parameter, argument); | 1013 localsHandler.updateLocal(parameter, argument); |
1012 // Don't forget to update the field, if the parameter is of the | 1014 // Don't forget to update the field, if the parameter is of the |
1013 // form [:this.x:]. | 1015 // form [:this.x:]. |
1014 if (parameter.kind == ElementKind.FIELD_PARAMETER) { | 1016 if (parameter.kind == ElementKind.FIELD_PARAMETER) { |
1015 FieldParameterElement fieldParameterElement = parameter; | 1017 FieldParameterElement fieldParameterElement = parameter; |
1016 fieldValues[fieldParameterElement.fieldElement] = argument; | 1018 fieldValues[fieldParameterElement.fieldElement] = argument; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 inlineSuperOrRedirect(target, | 1083 inlineSuperOrRedirect(target, |
1082 selector, | 1084 selector, |
1083 const EmptyLink<Node>(), | 1085 const EmptyLink<Node>(), |
1084 constructors, | 1086 constructors, |
1085 fieldValues); | 1087 fieldValues); |
1086 } | 1088 } |
1087 } | 1089 } |
1088 } | 1090 } |
1089 | 1091 |
1090 /** | 1092 /** |
| 1093 * Run through the fields of [cls] and add their potential |
| 1094 * initializers. |
| 1095 */ |
| 1096 void buildFieldInitializers(ClassElement classElement, |
| 1097 Map<Element, HInstruction> fieldValues) { |
| 1098 classElement.forEachInstanceField( |
| 1099 includeBackendMembers: true, |
| 1100 includeSuperMembers: false, |
| 1101 f: (ClassElement enclosingClass, Element member) { |
| 1102 TreeElements definitions = compiler.analyzeElement(member); |
| 1103 Node node = member.parseNode(compiler); |
| 1104 SendSet assignment = node.asSendSet(); |
| 1105 HInstruction value; |
| 1106 if (assignment === null) { |
| 1107 value = graph.addConstantNull(); |
| 1108 } else { |
| 1109 Node right = assignment.arguments.head; |
| 1110 TreeElements savedElements = elements; |
| 1111 elements = definitions; |
| 1112 right.accept(this); |
| 1113 elements = savedElements; |
| 1114 value = pop(); |
| 1115 } |
| 1116 fieldValues[member] = value; |
| 1117 }); |
| 1118 } |
| 1119 |
| 1120 |
| 1121 /** |
1091 * Build the factory function corresponding to the constructor | 1122 * Build the factory function corresponding to the constructor |
1092 * [functionElement]: | 1123 * [functionElement]: |
1093 * - Initialize fields with the values of the field initializers of the | 1124 * - Initialize fields with the values of the field initializers of the |
1094 * current constructor and super constructors or constructors redirected | 1125 * current constructor and super constructors or constructors redirected |
1095 * to, starting from the current constructor. | 1126 * to, starting from the current constructor. |
1096 * - Call the the constructor bodies, starting from the constructor(s) in the | 1127 * - Call the the constructor bodies, starting from the constructor(s) in the |
1097 * super class(es). | 1128 * super class(es). |
1098 */ | 1129 */ |
1099 HGraph buildFactory(ClassElement classElement, | 1130 HGraph buildFactory(ClassElement classElement, |
1100 FunctionElement functionElement) { | 1131 FunctionElement functionElement) { |
1101 FunctionExpression function = functionElement.parseNode(compiler); | 1132 FunctionExpression function = functionElement.parseNode(compiler); |
1102 // Note that constructors (like any other static function) do not need | 1133 // Note that constructors (like any other static function) do not need |
1103 // to deal with optional arguments. It is the callers job to provide all | 1134 // to deal with optional arguments. It is the callers job to provide all |
1104 // arguments as if they were positional. | 1135 // arguments as if they were positional. |
1105 | 1136 |
1106 // The initializer list could contain closures. | 1137 // The initializer list could contain closures. |
1107 openFunction(functionElement, function); | 1138 openFunction(functionElement, function); |
1108 | 1139 |
1109 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); | 1140 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); |
| 1141 |
| 1142 // Compile the possible initialization code for local fields and |
| 1143 // super fields. |
| 1144 buildFieldInitializers(classElement, fieldValues); |
| 1145 |
| 1146 // Compile field-parameters such as [:this.x:]. |
1110 FunctionSignature params = functionElement.computeSignature(compiler); | 1147 FunctionSignature params = functionElement.computeSignature(compiler); |
1111 params.forEachParameter((Element element) { | 1148 params.forEachParameter((Element element) { |
1112 if (element.kind == ElementKind.FIELD_PARAMETER) { | 1149 if (element.kind == ElementKind.FIELD_PARAMETER) { |
1113 // If the [element] is a field-parameter (such as [:this.x:] then | 1150 // If the [element] is a field-parameter then |
1114 // initialize the field element with its value. | 1151 // initialize the field element with its value. |
1115 FieldParameterElement fieldParameterElement = element; | 1152 FieldParameterElement fieldParameterElement = element; |
1116 HInstruction parameterValue = localsHandler.readLocal(element); | 1153 HInstruction parameterValue = localsHandler.readLocal(element); |
1117 fieldValues[fieldParameterElement.fieldElement] = parameterValue; | 1154 fieldValues[fieldParameterElement.fieldElement] = parameterValue; |
1118 } | 1155 } |
1119 }); | 1156 }); |
1120 | 1157 |
1121 List<FunctionElement> constructors = <FunctionElement>[functionElement]; | |
1122 | |
1123 // Analyze the constructor and all referenced constructors and collect | 1158 // Analyze the constructor and all referenced constructors and collect |
1124 // initializers and constructor bodies. | 1159 // initializers and constructor bodies. |
| 1160 List<FunctionElement> constructors = <FunctionElement>[functionElement]; |
1125 buildInitializers(functionElement, constructors, fieldValues); | 1161 buildInitializers(functionElement, constructors, fieldValues); |
1126 | 1162 |
1127 // Call the JavaScript constructor with the fields as argument. | 1163 // Call the JavaScript constructor with the fields as argument. |
1128 List<HInstruction> constructorArguments = <HInstruction>[]; | 1164 List<HInstruction> constructorArguments = <HInstruction>[]; |
1129 classElement.forEachInstanceField( | 1165 classElement.forEachInstanceField( |
1130 includeBackendMembers: true, | 1166 includeBackendMembers: true, |
1131 includeSuperMembers: true, | 1167 includeSuperMembers: true, |
1132 f: (ClassElement enclosingClass, Element member) { | 1168 f: (ClassElement enclosingClass, Element member) { |
1133 HInstruction value = fieldValues[member]; | 1169 constructorArguments.add(fieldValues[member]); |
1134 if (value === null) { | |
1135 // The field has no value in the initializer list. Initialize it | |
1136 // with the declaration-site constant (if any). | |
1137 Constant fieldValue = compiler.constantHandler.compileVariable(member); | |
1138 value = graph.addConstant(fieldValue); | |
1139 } | |
1140 constructorArguments.add(value); | |
1141 }); | 1170 }); |
1142 | 1171 |
1143 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 1172 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
1144 add(newObject); | 1173 add(newObject); |
1145 // Generate calls to the constructor bodies. | 1174 // Generate calls to the constructor bodies. |
1146 for (int index = constructors.length - 1; index >= 0; index--) { | 1175 for (int index = constructors.length - 1; index >= 0; index--) { |
1147 FunctionElement constructor = constructors[index]; | 1176 FunctionElement constructor = constructors[index]; |
1148 ConstructorBodyElement body = getConstructorBody(constructor); | 1177 ConstructorBodyElement body = getConstructorBody(constructor); |
1149 if (body === null) continue; | 1178 if (body === null) continue; |
1150 List bodyCallInputs = <HInstruction>[]; | 1179 List bodyCallInputs = <HInstruction>[]; |
(...skipping 2694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3845 new HSubGraphBlockInformation(elseBranch.graph)); | 3874 new HSubGraphBlockInformation(elseBranch.graph)); |
3846 | 3875 |
3847 HBasicBlock conditionStartBlock = conditionBranch.block; | 3876 HBasicBlock conditionStartBlock = conditionBranch.block; |
3848 conditionStartBlock.setBlockFlow(info, joinBlock); | 3877 conditionStartBlock.setBlockFlow(info, joinBlock); |
3849 SubGraph conditionGraph = conditionBranch.graph; | 3878 SubGraph conditionGraph = conditionBranch.graph; |
3850 HIf branch = conditionGraph.end.last; | 3879 HIf branch = conditionGraph.end.last; |
3851 assert(branch is HIf); | 3880 assert(branch is HIf); |
3852 branch.blockInformation = conditionStartBlock.blockFlow; | 3881 branch.blockInformation = conditionStartBlock.blockFlow; |
3853 } | 3882 } |
3854 } | 3883 } |
OLD | NEW |