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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 * Documentation wanted -- johnniwinther | 1137 * Documentation wanted -- johnniwinther |
1138 * | 1138 * |
1139 * Invariant: [constructor] and [constructors] must all be implementation | 1139 * Invariant: [constructor] and [constructors] must all be implementation |
1140 * elements. | 1140 * elements. |
1141 */ | 1141 */ |
1142 void inlineSuperOrRedirect(FunctionElement constructor, | 1142 void inlineSuperOrRedirect(FunctionElement constructor, |
1143 Selector selector, | 1143 Selector selector, |
1144 Link<Node> arguments, | 1144 Link<Node> arguments, |
1145 List<FunctionElement> constructors, | 1145 List<FunctionElement> constructors, |
1146 Map<Element, HInstruction> fieldValues, | 1146 Map<Element, HInstruction> fieldValues, |
1147 FunctionElement inlinedFromElement, | 1147 FunctionElement inlinedFromElement) { |
1148 Node callNode) { | |
1149 compiler.withCurrentElement(constructor, () { | 1148 compiler.withCurrentElement(constructor, () { |
1150 assert(invariant(constructor, constructor.isImplementation)); | 1149 assert(invariant(constructor, constructor.isImplementation)); |
1151 constructors.addLast(constructor); | 1150 constructors.addLast(constructor); |
1152 | 1151 |
1153 List<HInstruction> compiledArguments = new List<HInstruction>(); | 1152 List<HInstruction> compiledArguments = new List<HInstruction>(); |
1154 bool succeeded = | 1153 bool succeeded = |
1155 inlinedFrom(inlinedFromElement, | 1154 inlinedFrom(inlinedFromElement, |
1156 () => addStaticSendArgumentsToList(selector, | 1155 () => addStaticSendArgumentsToList(selector, |
1157 arguments, | 1156 arguments, |
1158 constructor, | 1157 constructor, |
1159 compiledArguments)); | 1158 compiledArguments)); |
1160 if (!succeeded) { | 1159 if (!succeeded) { |
1161 // Non-matching super and redirects are compile-time errors and thus | 1160 // Non-matching super and redirects are compile-time errors and thus |
1162 // checked by the resolver. | 1161 // checked by the resolver. |
1163 compiler.internalError( | 1162 compiler.internalError( |
1164 "Parameters and arguments didn't match for super/redirect call", | 1163 "Parameters and arguments didn't match for super/redirect call", |
1165 element: constructor); | 1164 element: constructor); |
1166 } | 1165 } |
1167 | 1166 |
1168 ClassElement superclass = constructor.getEnclosingClass(); | |
1169 if (compiler.world.needsRti(superclass)) { | |
1170 // If [superclass] needs rti, we have to give a value to its | |
1171 // type parameters. Those values are in the [supertype] | |
1172 // declaration of [subclass]. | |
1173 ClassElement subclass = inlinedFromElement.getEnclosingClass(); | |
1174 DartType supertype = subclass.supertype; | |
1175 Link<DartType> typeVariable = superclass.typeVariables; | |
1176 supertype.typeArguments.forEach((DartType argument) { | |
1177 localsHandler.directLocals[typeVariable.head.element] = | |
1178 analyzeTypeArgument(argument, callNode); | |
1179 typeVariable = typeVariable.tail; | |
1180 }); | |
1181 // Also add null to non-provided type variables. | |
1182 while (!typeVariable.isEmpty) { | |
1183 localsHandler.directLocals[typeVariable.head.element] = | |
1184 graph.addConstantNull(constantSystem); | |
1185 typeVariable = typeVariable.tail; | |
1186 } | |
1187 } | |
1188 | |
1189 inlinedFrom(constructor, () { | 1167 inlinedFrom(constructor, () { |
1190 buildFieldInitializers(constructor.enclosingElement.implementation, | 1168 buildFieldInitializers(constructor.enclosingElement.implementation, |
1191 fieldValues); | 1169 fieldValues); |
1192 }); | 1170 }); |
1193 | 1171 |
1194 int index = 0; | 1172 int index = 0; |
1195 FunctionSignature params = constructor.computeSignature(compiler); | 1173 FunctionSignature params = constructor.computeSignature(compiler); |
1196 params.orderedForEachParameter((Element parameter) { | 1174 params.orderedForEachParameter((Element parameter) { |
1197 HInstruction argument = compiledArguments[index++]; | 1175 HInstruction argument = compiledArguments[index++]; |
1198 // Because we are inlining the initializer, we must update | 1176 // Because we are inlining the initializer, we must update |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 assert(link.head is Send); | 1239 assert(link.head is Send); |
1262 if (link.head is !SendSet) { | 1240 if (link.head is !SendSet) { |
1263 // A super initializer or constructor redirection. | 1241 // A super initializer or constructor redirection. |
1264 Send call = link.head; | 1242 Send call = link.head; |
1265 assert(Initializers.isSuperConstructorCall(call) || | 1243 assert(Initializers.isSuperConstructorCall(call) || |
1266 Initializers.isConstructorRedirect(call)); | 1244 Initializers.isConstructorRedirect(call)); |
1267 FunctionElement target = elements[call]; | 1245 FunctionElement target = elements[call]; |
1268 Selector selector = elements.getSelector(call); | 1246 Selector selector = elements.getSelector(call); |
1269 Link<Node> arguments = call.arguments; | 1247 Link<Node> arguments = call.arguments; |
1270 inlineSuperOrRedirect(target, selector, arguments, constructors, | 1248 inlineSuperOrRedirect(target, selector, arguments, constructors, |
1271 fieldValues, constructor, call); | 1249 fieldValues, constructor); |
1272 foundSuperOrRedirect = true; | 1250 foundSuperOrRedirect = true; |
1273 } else { | 1251 } else { |
1274 // A field initializer. | 1252 // A field initializer. |
1275 SendSet init = link.head; | 1253 SendSet init = link.head; |
1276 Link<Node> arguments = init.arguments; | 1254 Link<Node> arguments = init.arguments; |
1277 assert(!arguments.isEmpty && arguments.tail.isEmpty); | 1255 assert(!arguments.isEmpty && arguments.tail.isEmpty); |
1278 inlinedFrom(constructor, () { | 1256 inlinedFrom(constructor, () { |
1279 visit(arguments.head); | 1257 visit(arguments.head); |
1280 }); | 1258 }); |
1281 fieldValues[elements[init]] = pop(); | 1259 fieldValues[elements[init]] = pop(); |
(...skipping 14 matching lines...) Expand all Loading... |
1296 // TODO(johnniwinther): Should we find injected constructors as well? | 1274 // TODO(johnniwinther): Should we find injected constructors as well? |
1297 FunctionElement target = superClass.lookupConstructor(selector); | 1275 FunctionElement target = superClass.lookupConstructor(selector); |
1298 if (target == null) { | 1276 if (target == null) { |
1299 compiler.internalError("no default constructor available"); | 1277 compiler.internalError("no default constructor available"); |
1300 } | 1278 } |
1301 inlineSuperOrRedirect(target.implementation, | 1279 inlineSuperOrRedirect(target.implementation, |
1302 selector, | 1280 selector, |
1303 const Link<Node>(), | 1281 const Link<Node>(), |
1304 constructors, | 1282 constructors, |
1305 fieldValues, | 1283 fieldValues, |
1306 constructor, | 1284 constructor); |
1307 functionNode); | |
1308 } | 1285 } |
1309 } | 1286 } |
1310 } | 1287 } |
1311 | 1288 |
1312 /** | 1289 /** |
1313 * Run through the fields of [cls] and add their potential | 1290 * Run through the fields of [cls] and add their potential |
1314 * initializers. | 1291 * initializers. |
1315 * | 1292 * |
1316 * Invariant: [classElement] must be an implementation element. | 1293 * Invariant: [classElement] must be an implementation element. |
1317 */ | 1294 */ |
(...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3120 /** | 3097 /** |
3121 * Helper to create an instruction that gets the value of a type variable. | 3098 * Helper to create an instruction that gets the value of a type variable. |
3122 */ | 3099 */ |
3123 HInstruction addTypeVariableReference(TypeVariableType type) { | 3100 HInstruction addTypeVariableReference(TypeVariableType type) { |
3124 Element member = currentElement; | 3101 Element member = currentElement; |
3125 if (member.enclosingElement.isClosure()) { | 3102 if (member.enclosingElement.isClosure()) { |
3126 ClosureClassElement closureClass = member.enclosingElement; | 3103 ClosureClassElement closureClass = member.enclosingElement; |
3127 member = closureClass.methodElement; | 3104 member = closureClass.methodElement; |
3128 member = member.getOutermostEnclosingMemberOrTopLevel(); | 3105 member = member.getOutermostEnclosingMemberOrTopLevel(); |
3129 } | 3106 } |
3130 if (member.isConstructor()) { | 3107 if (member.isFactoryConstructor()) { |
3131 // The type variable is stored in a parameter of the method. | 3108 // The type variable is stored in a parameter of the method. |
3132 return localsHandler.readLocal(type.element); | 3109 return localsHandler.readLocal(type.element); |
3133 } else if (member.isInstanceMember()) { | 3110 } else if (member.isInstanceMember() || |
| 3111 member.isGenerativeConstructor()) { |
3134 // The type variable is stored on the object. Generate code to extract | 3112 // The type variable is stored on the object. Generate code to extract |
3135 // the type arguments from the object, substitute them as an instance | 3113 // the type arguments from the object, substitute them as an instance |
3136 // of the type we are testing against (if necessary), and extract the | 3114 // of the type we are testing against (if necessary), and extract the |
3137 // type argument by the index of the variable in the list of type | 3115 // type argument by the index of the variable in the list of type |
3138 // variables for that class. | 3116 // variables for that class. |
3139 int index = RuntimeTypeInformation.getTypeVariableIndex(type); | 3117 int index = RuntimeTypeInformation.getTypeVariableIndex(type); |
3140 HInstruction thisObject = localsHandler.readThis(); | 3118 HInstruction thisObject = localsHandler.readThis(); |
3141 String substitutionNameString = | 3119 String substitutionNameString = |
3142 backend.namer.substitutionName(member.getEnclosingClass()); | 3120 backend.namer.substitutionName(member.getEnclosingClass()); |
3143 HInstruction substitutionName = graph.addConstantString( | 3121 HInstruction substitutionName = graph.addConstantString( |
(...skipping 1855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4999 new HSubGraphBlockInformation(elseBranch.graph)); | 4977 new HSubGraphBlockInformation(elseBranch.graph)); |
5000 | 4978 |
5001 HBasicBlock conditionStartBlock = conditionBranch.block; | 4979 HBasicBlock conditionStartBlock = conditionBranch.block; |
5002 conditionStartBlock.setBlockFlow(info, joinBlock); | 4980 conditionStartBlock.setBlockFlow(info, joinBlock); |
5003 SubGraph conditionGraph = conditionBranch.graph; | 4981 SubGraph conditionGraph = conditionBranch.graph; |
5004 HIf branch = conditionGraph.end.last; | 4982 HIf branch = conditionGraph.end.last; |
5005 assert(branch is HIf); | 4983 assert(branch is HIf); |
5006 branch.blockInformation = conditionStartBlock.blockFlow; | 4984 branch.blockInformation = conditionStartBlock.blockFlow; |
5007 } | 4985 } |
5008 } | 4986 } |
OLD | NEW |