Chromium Code Reviews| 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 bool inLoop = functionsCalledInLoop.contains(element.declaration); | 188 bool inLoop = functionsCalledInLoop.contains(element.declaration); |
| 189 if (!inLoop) { | 189 if (!inLoop) { |
| 190 Selector selector = selectorsCalledInLoop[element.name]; | 190 Selector selector = selectorsCalledInLoop[element.name]; |
| 191 inLoop = selector !== null && selector.applies(element, compiler); | 191 inLoop = selector !== null && selector.applies(element, compiler); |
| 192 } | 192 } |
| 193 graph.calledInLoop = inLoop; | 193 graph.calledInLoop = inLoop; |
| 194 | 194 |
| 195 // If there is an estimate of the parameter types assume these types | 195 // If there is an estimate of the parameter types assume these types |
| 196 // when compiling. | 196 // when compiling. |
| 197 OptionalParameterTypes defaultValueTypes = null; | 197 OptionalParameterTypes defaultValueTypes = null; |
| 198 FunctionSignature signature = element.computeSignature(compiler); | 198 FunctionSignature signature = |
| 199 element.computeSignature(compiler); | |
|
ahe
2012/10/02 13:27:04
Why this change?
Johnni Winther
2012/10/03 09:22:59
There was more code here at an intermediate step.
| |
| 199 if (signature.optionalParameterCount > 0) { | 200 if (signature.optionalParameterCount > 0) { |
| 200 defaultValueTypes = | 201 defaultValueTypes = |
| 201 new OptionalParameterTypes(signature.optionalParameterCount); | 202 new OptionalParameterTypes(signature.optionalParameterCount); |
| 202 int index = 0; | 203 int index = 0; |
| 203 signature.forEachOptionalParameter((Element parameter) { | 204 signature.forEachOptionalParameter((Element parameter) { |
| 204 Constant defaultValue = compiler.compileVariable(parameter); | 205 Constant defaultValue = compiler.compileVariable(parameter); |
| 205 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); | 206 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); |
| 206 defaultValueTypes.update(index, parameter.name, type); | 207 defaultValueTypes.update(index, parameter.name, type); |
| 207 index++; | 208 index++; |
| 208 }); | 209 }); |
| 209 } | 210 } |
| 210 HTypeList parameterTypes = | 211 HTypeList parameterTypes = |
| 211 backend.optimisticParameterTypes(element.declaration, | 212 backend.optimisticParameterTypes(element.declaration, |
| 212 defaultValueTypes); | 213 defaultValueTypes); |
| 213 if (!parameterTypes.allUnknown) { | 214 if (!parameterTypes.allUnknown) { |
| 214 int i = 0; | 215 int i = 0; |
| 215 signature.forEachParameter((Element param) { | 216 signature.forEachParameter((Element param) { |
| 216 builder.parameters[param].guaranteedType = parameterTypes[i++]; | 217 builder.parameters[param].guaranteedType = parameterTypes[i++]; |
| 217 }); | 218 }); |
| 218 } | 219 } |
| 219 backend.registerParameterTypesOptimization( | 220 backend.registerParameterTypesOptimization( |
| 220 element, parameterTypes, defaultValueTypes); | 221 element.declaration, parameterTypes, defaultValueTypes); |
| 221 } | 222 } |
| 222 | 223 |
| 223 if (compiler.tracer.enabled) { | 224 if (compiler.tracer.enabled) { |
| 224 String name; | 225 String name; |
| 225 if (element.isMember()) { | 226 if (element.isMember()) { |
| 226 String className = element.getEnclosingClass().name.slowToString(); | 227 String className = element.getEnclosingClass().name.slowToString(); |
| 227 String memberName = element.name.slowToString(); | 228 String memberName = element.name.slowToString(); |
| 228 name = "$className.$memberName"; | 229 name = "$className.$memberName"; |
| 229 if (element.isGenerativeConstructorBody()) { | 230 if (element.isGenerativeConstructorBody()) { |
| 230 name = "$name (body)"; | 231 name = "$name (body)"; |
| 231 } | 232 } |
| 232 } else { | 233 } else { |
| 233 name = "${element.name.slowToString()}"; | 234 name = "${element.name.slowToString()}"; |
| 234 } | 235 } |
| 235 compiler.tracer.traceCompilation(name, work.compilationContext); | 236 compiler.tracer.traceCompilation(name, work.compilationContext); |
| 236 compiler.tracer.traceGraph('builder', graph); | 237 compiler.tracer.traceGraph('builder', graph); |
| 237 } | 238 } |
| 238 return graph; | 239 return graph; |
| 239 }); | 240 }); |
| 240 } | 241 } |
| 241 | 242 |
| 242 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { | 243 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { |
| 243 // The body of the constructor will be generated in a separate function. | 244 // The body of the constructor will be generated in a separate function. |
| 244 final ClassElement classElement = work.element.getEnclosingClass(); | 245 final ClassElement classElement = work.element.getEnclosingClass(); |
| 245 return builder.buildFactory(classElement, work.element.implementation); | 246 return builder.buildFactory(classElement.implementation, |
| 247 work.element.implementation); | |
| 246 } | 248 } |
| 247 } | 249 } |
| 248 | 250 |
| 249 /** | 251 /** |
| 250 * Keeps track of locals (including parameters and phis) when building. The | 252 * Keeps track of locals (including parameters and phis) when building. The |
| 251 * 'this' reference is treated as parameter and hence handled by this class, | 253 * 'this' reference is treated as parameter and hence handled by this class, |
| 252 * too. | 254 * too. |
| 253 */ | 255 */ |
| 254 class LocalsHandler { | 256 class LocalsHandler { |
| 255 /** | 257 /** |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 967 } | 969 } |
| 968 } | 970 } |
| 969 if (bodyElement === null) { | 971 if (bodyElement === null) { |
| 970 bodyElement = new ConstructorBodyElement(constructor); | 972 bodyElement = new ConstructorBodyElement(constructor); |
| 971 // [:resolveMethodElement:] require the passed element to be a | 973 // [:resolveMethodElement:] require the passed element to be a |
| 972 // declaration. | 974 // declaration. |
| 973 TreeElements treeElements = | 975 TreeElements treeElements = |
| 974 compiler.resolver.resolveMethodElement(constructor.declaration); | 976 compiler.resolver.resolveMethodElement(constructor.declaration); |
| 975 classElement.backendMembers = | 977 classElement.backendMembers = |
| 976 classElement.backendMembers.prepend(bodyElement); | 978 classElement.backendMembers.prepend(bodyElement); |
| 979 | |
| 980 if (constructor.origin != null) { | |
|
ahe
2012/10/02 13:27:04
isPatched?
Johnni Winther
2012/10/03 09:22:59
Done.
| |
| 981 // Create origin body element for patched constructors. | |
| 982 bodyElement.origin = new ConstructorBodyElement(constructor.origin); | |
| 983 bodyElement.origin.patch = bodyElement; | |
| 984 classElement.origin.backendMembers = | |
| 985 classElement.origin.backendMembers.prepend(bodyElement.origin); | |
| 986 } | |
| 977 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration, | 987 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration, |
| 978 treeElements); | 988 treeElements); |
| 979 } | 989 } |
| 980 assert(bodyElement.isGenerativeConstructorBody()); | 990 assert(bodyElement.isGenerativeConstructorBody()); |
| 981 return bodyElement; | 991 return bodyElement; |
| 982 } | 992 } |
| 983 | 993 |
| 984 /** | 994 /** |
| 985 * Documentation wanted -- johnniwinther | 995 * Documentation wanted -- johnniwinther |
| 986 * | 996 * |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 constructor, | 1114 constructor, |
| 1105 compiledArguments); | 1115 compiledArguments); |
| 1106 if (!succeeded) { | 1116 if (!succeeded) { |
| 1107 // Non-matching super and redirects are compile-time errors and thus | 1117 // Non-matching super and redirects are compile-time errors and thus |
| 1108 // checked by the resolver. | 1118 // checked by the resolver. |
| 1109 compiler.internalError( | 1119 compiler.internalError( |
| 1110 "Parameters and arguments didn't match for super/redirect call", | 1120 "Parameters and arguments didn't match for super/redirect call", |
| 1111 element: constructor); | 1121 element: constructor); |
| 1112 } | 1122 } |
| 1113 | 1123 |
| 1114 buildFieldInitializers(constructor.enclosingElement, fieldValues); | 1124 buildFieldInitializers(constructor.enclosingElement.implementation, |
| 1125 fieldValues); | |
| 1115 | 1126 |
| 1116 int index = 0; | 1127 int index = 0; |
| 1117 FunctionSignature params = constructor.computeSignature(compiler); | 1128 FunctionSignature params = constructor.computeSignature(compiler); |
| 1118 params.forEachParameter((Element parameter) { | 1129 params.forEachParameter((Element parameter) { |
| 1119 HInstruction argument = compiledArguments[index++]; | 1130 HInstruction argument = compiledArguments[index++]; |
| 1120 localsHandler.updateLocal(parameter, argument); | 1131 localsHandler.updateLocal(parameter, argument); |
| 1121 // Don't forget to update the field, if the parameter is of the | 1132 // Don't forget to update the field, if the parameter is of the |
| 1122 // form [:this.x:]. | 1133 // form [:this.x:]. |
| 1123 if (parameter.kind == ElementKind.FIELD_PARAMETER) { | 1134 if (parameter.kind == ElementKind.FIELD_PARAMETER) { |
| 1124 FieldParameterElement fieldParameterElement = parameter; | 1135 FieldParameterElement fieldParameterElement = parameter; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1182 if (!foundSuperOrRedirect) { | 1193 if (!foundSuperOrRedirect) { |
| 1183 // No super initializer found. Try to find the default constructor if | 1194 // No super initializer found. Try to find the default constructor if |
| 1184 // the class is not Object. | 1195 // the class is not Object. |
| 1185 ClassElement enclosingClass = constructor.getEnclosingClass(); | 1196 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| 1186 ClassElement superClass = enclosingClass.superclass; | 1197 ClassElement superClass = enclosingClass.superclass; |
| 1187 if (!enclosingClass.isObject(compiler)) { | 1198 if (!enclosingClass.isObject(compiler)) { |
| 1188 assert(superClass !== null); | 1199 assert(superClass !== null); |
| 1189 assert(superClass.resolutionState == STATE_DONE); | 1200 assert(superClass.resolutionState == STATE_DONE); |
| 1190 Selector selector = | 1201 Selector selector = |
| 1191 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); | 1202 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); |
| 1203 // TODO(johnniwinther): Should we find injected constructors as well? | |
| 1192 FunctionElement target = superClass.lookupConstructor(superClass.name); | 1204 FunctionElement target = superClass.lookupConstructor(superClass.name); |
| 1193 if (target === null) { | 1205 if (target === null) { |
| 1194 compiler.internalError("no default constructor available"); | 1206 compiler.internalError("no default constructor available"); |
| 1195 } | 1207 } |
| 1196 inlineSuperOrRedirect(target.implementation, | 1208 inlineSuperOrRedirect(target.implementation, |
| 1197 selector, | 1209 selector, |
| 1198 const EmptyLink<Node>(), | 1210 const EmptyLink<Node>(), |
| 1199 constructors, | 1211 constructors, |
| 1200 fieldValues); | 1212 fieldValues); |
| 1201 } | 1213 } |
| 1202 } | 1214 } |
| 1203 } | 1215 } |
| 1204 | 1216 |
| 1205 /** | 1217 /** |
| 1206 * Run through the fields of [cls] and add their potential | 1218 * Run through the fields of [cls] and add their potential |
| 1207 * initializers. | 1219 * initializers. |
| 1208 * | 1220 * |
| 1209 * Invariant: [classElement] must be a declaration element. | 1221 * Invariant: [classElement] must be an implementation element. |
| 1210 */ | 1222 */ |
| 1211 void buildFieldInitializers(ClassElement classElement, | 1223 void buildFieldInitializers(ClassElement classElement, |
| 1212 Map<Element, HInstruction> fieldValues) { | 1224 Map<Element, HInstruction> fieldValues) { |
| 1213 assert(invariant(classElement, classElement.isDeclaration)); | 1225 assert(invariant(classElement, classElement.isImplementation)); |
| 1214 classElement.forEachInstanceField( | 1226 classElement.forEachInstanceField( |
| 1215 includeBackendMembers: true, | 1227 includeBackendMembers: true, |
| 1216 includeSuperMembers: false, | 1228 includeSuperMembers: false, |
| 1217 f: (ClassElement enclosingClass, Element member) { | 1229 f: (ClassElement enclosingClass, Element member) { |
| 1218 TreeElements definitions = compiler.analyzeElement(member); | 1230 TreeElements definitions = compiler.analyzeElement(member); |
| 1219 Node node = member.parseNode(compiler); | 1231 Node node = member.parseNode(compiler); |
| 1220 SendSet assignment = node.asSendSet(); | 1232 SendSet assignment = node.asSendSet(); |
| 1221 HInstruction value; | 1233 HInstruction value; |
| 1222 if (assignment === null) { | 1234 if (assignment === null) { |
| 1223 value = graph.addConstantNull(constantSystem); | 1235 value = graph.addConstantNull(constantSystem); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1236 | 1248 |
| 1237 /** | 1249 /** |
| 1238 * Build the factory function corresponding to the constructor | 1250 * Build the factory function corresponding to the constructor |
| 1239 * [functionElement]: | 1251 * [functionElement]: |
| 1240 * - Initialize fields with the values of the field initializers of the | 1252 * - Initialize fields with the values of the field initializers of the |
| 1241 * current constructor and super constructors or constructors redirected | 1253 * current constructor and super constructors or constructors redirected |
| 1242 * to, starting from the current constructor. | 1254 * to, starting from the current constructor. |
| 1243 * - Call the the constructor bodies, starting from the constructor(s) in the | 1255 * - Call the the constructor bodies, starting from the constructor(s) in the |
| 1244 * super class(es). | 1256 * super class(es). |
| 1245 * | 1257 * |
| 1246 * Invariants: [classElement] must be a declaration element, and | 1258 * Invariant: Both [classElement] and [functionElement] must be |
| 1247 * [functionElement] must be an implementation element. | 1259 * implementation elements. |
| 1248 */ | 1260 */ |
| 1249 HGraph buildFactory(ClassElement classElement, | 1261 HGraph buildFactory(ClassElement classElement, |
| 1250 FunctionElement functionElement) { | 1262 FunctionElement functionElement) { |
| 1251 assert(invariant(classElement, classElement.isDeclaration)); | 1263 assert(invariant(classElement, classElement.isImplementation)); |
| 1252 assert(invariant(functionElement, functionElement.isImplementation)); | 1264 assert(invariant(functionElement, functionElement.isImplementation)); |
| 1253 FunctionExpression function = functionElement.parseNode(compiler); | 1265 FunctionExpression function = functionElement.parseNode(compiler); |
| 1254 // Note that constructors (like any other static function) do not need | 1266 // Note that constructors (like any other static function) do not need |
| 1255 // to deal with optional arguments. It is the callers job to provide all | 1267 // to deal with optional arguments. It is the callers job to provide all |
| 1256 // arguments as if they were positional. | 1268 // arguments as if they were positional. |
| 1257 | 1269 |
| 1258 // The initializer list could contain closures. | 1270 // The initializer list could contain closures. |
| 1259 openFunction(functionElement, function); | 1271 openFunction(functionElement, function); |
| 1260 | 1272 |
| 1261 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); | 1273 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); |
| (...skipping 3065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4327 new HSubGraphBlockInformation(elseBranch.graph)); | 4339 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4328 | 4340 |
| 4329 HBasicBlock conditionStartBlock = conditionBranch.block; | 4341 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4330 conditionStartBlock.setBlockFlow(info, joinBlock); | 4342 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4331 SubGraph conditionGraph = conditionBranch.graph; | 4343 SubGraph conditionGraph = conditionBranch.graph; |
| 4332 HIf branch = conditionGraph.end.last; | 4344 HIf branch = conditionGraph.end.last; |
| 4333 assert(branch is HIf); | 4345 assert(branch is HIf); |
| 4334 branch.blockInformation = conditionStartBlock.blockFlow; | 4346 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4335 } | 4347 } |
| 4336 } | 4348 } |
| OLD | NEW |