| 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 HTypeList parameterTypes = | 212 HTypeList parameterTypes = |
| 213 backend.optimisticParameterTypes(element.declaration, | 213 backend.optimisticParameterTypes(element.declaration, |
| 214 defaultValueTypes); | 214 defaultValueTypes); |
| 215 if (!parameterTypes.allUnknown) { | 215 if (!parameterTypes.allUnknown) { |
| 216 int i = 0; | 216 int i = 0; |
| 217 signature.orderedForEachParameter((Element param) { | 217 signature.orderedForEachParameter((Element param) { |
| 218 builder.parameters[param].guaranteedType = parameterTypes[i++]; | 218 builder.parameters[param].guaranteedType = parameterTypes[i++]; |
| 219 }); | 219 }); |
| 220 } | 220 } |
| 221 backend.registerParameterTypesOptimization( | 221 backend.registerParameterTypesOptimization( |
| 222 element, parameterTypes, defaultValueTypes); | 222 element.declaration, parameterTypes, defaultValueTypes); |
| 223 } | 223 } |
| 224 | 224 |
| 225 if (compiler.tracer.enabled) { | 225 if (compiler.tracer.enabled) { |
| 226 String name; | 226 String name; |
| 227 if (element.isMember()) { | 227 if (element.isMember()) { |
| 228 String className = element.getEnclosingClass().name.slowToString(); | 228 String className = element.getEnclosingClass().name.slowToString(); |
| 229 String memberName = element.name.slowToString(); | 229 String memberName = element.name.slowToString(); |
| 230 name = "$className.$memberName"; | 230 name = "$className.$memberName"; |
| 231 if (element.isGenerativeConstructorBody()) { | 231 if (element.isGenerativeConstructorBody()) { |
| 232 name = "$name (body)"; | 232 name = "$name (body)"; |
| 233 } | 233 } |
| 234 } else { | 234 } else { |
| 235 name = "${element.name.slowToString()}"; | 235 name = "${element.name.slowToString()}"; |
| 236 } | 236 } |
| 237 compiler.tracer.traceCompilation(name, work.compilationContext); | 237 compiler.tracer.traceCompilation(name, work.compilationContext); |
| 238 compiler.tracer.traceGraph('builder', graph); | 238 compiler.tracer.traceGraph('builder', graph); |
| 239 } | 239 } |
| 240 return graph; | 240 return graph; |
| 241 }); | 241 }); |
| 242 } | 242 } |
| 243 | 243 |
| 244 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { | 244 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { |
| 245 // The body of the constructor will be generated in a separate function. | 245 // The body of the constructor will be generated in a separate function. |
| 246 final ClassElement classElement = work.element.getEnclosingClass(); | 246 final ClassElement classElement = work.element.getEnclosingClass(); |
| 247 return builder.buildFactory(classElement, work.element.implementation); | 247 return builder.buildFactory(classElement.implementation, |
| 248 work.element.implementation); |
| 248 } | 249 } |
| 249 } | 250 } |
| 250 | 251 |
| 251 /** | 252 /** |
| 252 * Keeps track of locals (including parameters and phis) when building. The | 253 * Keeps track of locals (including parameters and phis) when building. The |
| 253 * 'this' reference is treated as parameter and hence handled by this class, | 254 * 'this' reference is treated as parameter and hence handled by this class, |
| 254 * too. | 255 * too. |
| 255 */ | 256 */ |
| 256 class LocalsHandler { | 257 class LocalsHandler { |
| 257 /** | 258 /** |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 } | 970 } |
| 970 } | 971 } |
| 971 if (bodyElement === null) { | 972 if (bodyElement === null) { |
| 972 bodyElement = new ConstructorBodyElement(constructor); | 973 bodyElement = new ConstructorBodyElement(constructor); |
| 973 // [:resolveMethodElement:] require the passed element to be a | 974 // [:resolveMethodElement:] require the passed element to be a |
| 974 // declaration. | 975 // declaration. |
| 975 TreeElements treeElements = | 976 TreeElements treeElements = |
| 976 compiler.resolver.resolveMethodElement(constructor.declaration); | 977 compiler.resolver.resolveMethodElement(constructor.declaration); |
| 977 classElement.backendMembers = | 978 classElement.backendMembers = |
| 978 classElement.backendMembers.prepend(bodyElement); | 979 classElement.backendMembers.prepend(bodyElement); |
| 980 |
| 981 if (constructor.isPatch) { |
| 982 // Create origin body element for patched constructors. |
| 983 bodyElement.origin = new ConstructorBodyElement(constructor.origin); |
| 984 bodyElement.origin.patch = bodyElement; |
| 985 classElement.origin.backendMembers = |
| 986 classElement.origin.backendMembers.prepend(bodyElement.origin); |
| 987 } |
| 979 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration, | 988 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration, |
| 980 treeElements); | 989 treeElements); |
| 981 } | 990 } |
| 982 assert(bodyElement.isGenerativeConstructorBody()); | 991 assert(bodyElement.isGenerativeConstructorBody()); |
| 983 return bodyElement; | 992 return bodyElement; |
| 984 } | 993 } |
| 985 | 994 |
| 986 /** | 995 /** |
| 987 * Documentation wanted -- johnniwinther | 996 * Documentation wanted -- johnniwinther |
| 988 * | 997 * |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 compiledArguments); | 1118 compiledArguments); |
| 1110 if (!succeeded) { | 1119 if (!succeeded) { |
| 1111 // Non-matching super and redirects are compile-time errors and thus | 1120 // Non-matching super and redirects are compile-time errors and thus |
| 1112 // checked by the resolver. | 1121 // checked by the resolver. |
| 1113 compiler.internalError( | 1122 compiler.internalError( |
| 1114 "Parameters and arguments didn't match for super/redirect call", | 1123 "Parameters and arguments didn't match for super/redirect call", |
| 1115 element: constructor); | 1124 element: constructor); |
| 1116 } | 1125 } |
| 1117 | 1126 |
| 1118 sourceElementStack.add(constructor.enclosingElement); | 1127 sourceElementStack.add(constructor.enclosingElement); |
| 1119 buildFieldInitializers(constructor.enclosingElement, fieldValues); | 1128 buildFieldInitializers(constructor.enclosingElement.implementation, |
| 1129 fieldValues); |
| 1120 sourceElementStack.removeLast(); | 1130 sourceElementStack.removeLast(); |
| 1121 | 1131 |
| 1122 int index = 0; | 1132 int index = 0; |
| 1123 FunctionSignature params = constructor.computeSignature(compiler); | 1133 FunctionSignature params = constructor.computeSignature(compiler); |
| 1124 params.orderedForEachParameter((Element parameter) { | 1134 params.orderedForEachParameter((Element parameter) { |
| 1125 HInstruction argument = compiledArguments[index++]; | 1135 HInstruction argument = compiledArguments[index++]; |
| 1126 localsHandler.updateLocal(parameter, argument); | 1136 localsHandler.updateLocal(parameter, argument); |
| 1127 // Don't forget to update the field, if the parameter is of the | 1137 // Don't forget to update the field, if the parameter is of the |
| 1128 // form [:this.x:]. | 1138 // form [:this.x:]. |
| 1129 if (parameter.kind == ElementKind.FIELD_PARAMETER) { | 1139 if (parameter.kind == ElementKind.FIELD_PARAMETER) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 if (!foundSuperOrRedirect) { | 1199 if (!foundSuperOrRedirect) { |
| 1190 // No super initializer found. Try to find the default constructor if | 1200 // No super initializer found. Try to find the default constructor if |
| 1191 // the class is not Object. | 1201 // the class is not Object. |
| 1192 ClassElement enclosingClass = constructor.getEnclosingClass(); | 1202 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| 1193 ClassElement superClass = enclosingClass.superclass; | 1203 ClassElement superClass = enclosingClass.superclass; |
| 1194 if (!enclosingClass.isObject(compiler)) { | 1204 if (!enclosingClass.isObject(compiler)) { |
| 1195 assert(superClass !== null); | 1205 assert(superClass !== null); |
| 1196 assert(superClass.resolutionState == STATE_DONE); | 1206 assert(superClass.resolutionState == STATE_DONE); |
| 1197 Selector selector = | 1207 Selector selector = |
| 1198 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); | 1208 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); |
| 1209 // TODO(johnniwinther): Should we find injected constructors as well? |
| 1199 FunctionElement target = superClass.lookupConstructor(superClass.name); | 1210 FunctionElement target = superClass.lookupConstructor(superClass.name); |
| 1200 if (target === null) { | 1211 if (target === null) { |
| 1201 compiler.internalError("no default constructor available"); | 1212 compiler.internalError("no default constructor available"); |
| 1202 } | 1213 } |
| 1203 inlineSuperOrRedirect(target.implementation, | 1214 inlineSuperOrRedirect(target.implementation, |
| 1204 selector, | 1215 selector, |
| 1205 const EmptyLink<Node>(), | 1216 const EmptyLink<Node>(), |
| 1206 constructors, | 1217 constructors, |
| 1207 fieldValues); | 1218 fieldValues); |
| 1208 } | 1219 } |
| 1209 } | 1220 } |
| 1210 } | 1221 } |
| 1211 | 1222 |
| 1212 /** | 1223 /** |
| 1213 * Run through the fields of [cls] and add their potential | 1224 * Run through the fields of [cls] and add their potential |
| 1214 * initializers. | 1225 * initializers. |
| 1215 * | 1226 * |
| 1216 * Invariant: [classElement] must be a declaration element. | 1227 * Invariant: [classElement] must be an implementation element. |
| 1217 */ | 1228 */ |
| 1218 void buildFieldInitializers(ClassElement classElement, | 1229 void buildFieldInitializers(ClassElement classElement, |
| 1219 Map<Element, HInstruction> fieldValues) { | 1230 Map<Element, HInstruction> fieldValues) { |
| 1220 assert(invariant(classElement, classElement.isDeclaration)); | 1231 assert(invariant(classElement, classElement.isImplementation)); |
| 1221 classElement.forEachInstanceField( | 1232 classElement.forEachInstanceField( |
| 1222 includeBackendMembers: true, | 1233 includeBackendMembers: true, |
| 1223 includeSuperMembers: false, | 1234 includeSuperMembers: false, |
| 1224 f: (ClassElement enclosingClass, Element member) { | 1235 f: (ClassElement enclosingClass, Element member) { |
| 1225 TreeElements definitions = compiler.analyzeElement(member); | 1236 TreeElements definitions = compiler.analyzeElement(member); |
| 1226 Node node = member.parseNode(compiler); | 1237 Node node = member.parseNode(compiler); |
| 1227 SendSet assignment = node.asSendSet(); | 1238 SendSet assignment = node.asSendSet(); |
| 1228 HInstruction value; | 1239 HInstruction value; |
| 1229 if (assignment === null) { | 1240 if (assignment === null) { |
| 1230 value = graph.addConstantNull(constantSystem); | 1241 value = graph.addConstantNull(constantSystem); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1243 | 1254 |
| 1244 /** | 1255 /** |
| 1245 * Build the factory function corresponding to the constructor | 1256 * Build the factory function corresponding to the constructor |
| 1246 * [functionElement]: | 1257 * [functionElement]: |
| 1247 * - Initialize fields with the values of the field initializers of the | 1258 * - Initialize fields with the values of the field initializers of the |
| 1248 * current constructor and super constructors or constructors redirected | 1259 * current constructor and super constructors or constructors redirected |
| 1249 * to, starting from the current constructor. | 1260 * to, starting from the current constructor. |
| 1250 * - Call the the constructor bodies, starting from the constructor(s) in the | 1261 * - Call the the constructor bodies, starting from the constructor(s) in the |
| 1251 * super class(es). | 1262 * super class(es). |
| 1252 * | 1263 * |
| 1253 * Invariants: [classElement] must be a declaration element, and | 1264 * Invariant: Both [classElement] and [functionElement] must be |
| 1254 * [functionElement] must be an implementation element. | 1265 * implementation elements. |
| 1255 */ | 1266 */ |
| 1256 HGraph buildFactory(ClassElement classElement, | 1267 HGraph buildFactory(ClassElement classElement, |
| 1257 FunctionElement functionElement) { | 1268 FunctionElement functionElement) { |
| 1258 assert(invariant(classElement, classElement.isDeclaration)); | 1269 assert(invariant(classElement, classElement.isImplementation)); |
| 1259 assert(invariant(functionElement, functionElement.isImplementation)); | 1270 assert(invariant(functionElement, functionElement.isImplementation)); |
| 1260 FunctionExpression function = functionElement.parseNode(compiler); | 1271 FunctionExpression function = functionElement.parseNode(compiler); |
| 1261 // Note that constructors (like any other static function) do not need | 1272 // Note that constructors (like any other static function) do not need |
| 1262 // to deal with optional arguments. It is the callers job to provide all | 1273 // to deal with optional arguments. It is the callers job to provide all |
| 1263 // arguments as if they were positional. | 1274 // arguments as if they were positional. |
| 1264 | 1275 |
| 1265 // The initializer list could contain closures. | 1276 // The initializer list could contain closures. |
| 1266 openFunction(functionElement, function); | 1277 openFunction(functionElement, function); |
| 1267 | 1278 |
| 1268 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); | 1279 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); |
| (...skipping 3109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4378 new HSubGraphBlockInformation(elseBranch.graph)); | 4389 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4379 | 4390 |
| 4380 HBasicBlock conditionStartBlock = conditionBranch.block; | 4391 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4381 conditionStartBlock.setBlockFlow(info, joinBlock); | 4392 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4382 SubGraph conditionGraph = conditionBranch.graph; | 4393 SubGraph conditionGraph = conditionBranch.graph; |
| 4383 HIf branch = conditionGraph.end.last; | 4394 HIf branch = conditionGraph.end.last; |
| 4384 assert(branch is HIf); | 4395 assert(branch is HIf); |
| 4385 branch.blockInformation = conditionStartBlock.blockFlow; | 4396 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4386 } | 4397 } |
| 4387 } | 4398 } |
| OLD | NEW |