| 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 |