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 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4158 graph.addConstant(kindConstant, compiler), | 4158 graph.addConstant(kindConstant, compiler), |
4159 argumentsInstruction, | 4159 argumentsInstruction, |
4160 argumentNamesInstruction], | 4160 argumentNamesInstruction], |
4161 backend.dynamicType); | 4161 backend.dynamicType); |
4162 | 4162 |
4163 var inputs = <HInstruction>[pop()]; | 4163 var inputs = <HInstruction>[pop()]; |
4164 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); | 4164 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); |
4165 } | 4165 } |
4166 | 4166 |
4167 visitSuperSend(ast.Send node) { | 4167 visitSuperSend(ast.Send node) { |
| 4168 internalError(node, "Unexpected super send."); |
| 4169 } |
| 4170 |
| 4171 /// Generate a call to a super method or constructor. |
| 4172 void generateSuperInvoke(ast.Send node, FunctionElement function) { |
| 4173 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 4174 // calling [makeStaticArgumentList]. |
| 4175 Selector selector = elements.getSelector(node); |
| 4176 assert(invariant(node, |
| 4177 selector.applies(function.implementation, compiler.world), |
| 4178 message: "$selector does not apply to ${function.implementation}")); |
| 4179 List<HInstruction> inputs = |
| 4180 makeStaticArgumentList(selector.callStructure, |
| 4181 node.arguments, |
| 4182 function.implementation); |
| 4183 push(buildInvokeSuper(selector, function, inputs)); |
| 4184 } |
| 4185 |
| 4186 /// Access the value from the super [element]. |
| 4187 void handleSuperGet(ast.Send node, Element element) { |
| 4188 Selector selector = elements.getSelector(node); |
| 4189 push(buildInvokeSuper(selector, element, const <HInstruction>[])); |
| 4190 } |
| 4191 |
| 4192 /// Invoke .call on the value retrieved from the super [element]. |
| 4193 void handleSuperCallInvoke(ast.Send node, Element element) { |
| 4194 Selector selector = elements.getSelector(node); |
| 4195 HInstruction target = |
| 4196 buildInvokeSuper(selector, element, const <HInstruction>[]); |
| 4197 add(target); |
| 4198 generateCallInvoke(node, target); |
| 4199 } |
| 4200 |
| 4201 /// Invoke super [method]. |
| 4202 void handleSuperMethodInvoke( |
| 4203 ast.Send node, |
| 4204 MethodElement method) { |
| 4205 generateSuperInvoke(node, method); |
| 4206 } |
| 4207 |
| 4208 /// Access an unresolved super property. |
| 4209 void handleUnresolvedSuperInvoke(ast.Send node) { |
| 4210 Selector selector = elements.getSelector(node); |
| 4211 List<HInstruction> arguments = <HInstruction>[]; |
| 4212 if (!node.isPropertyAccess) { |
| 4213 addGenericSendArgumentsToList(node.arguments, arguments); |
| 4214 } |
| 4215 generateSuperNoSuchMethodSend(node, selector, arguments); |
| 4216 } |
| 4217 |
| 4218 /// Handle super constructor invocation. |
| 4219 @override |
| 4220 void handleSuperConstructorInvoke(ast.Send node) { |
4168 Selector selector = elements.getSelector(node); | 4221 Selector selector = elements.getSelector(node); |
4169 Element element = elements[node]; | 4222 Element element = elements[node]; |
4170 if (Elements.isUnresolved(element)) { | 4223 if (selector.applies(element, compiler.world)) { |
4171 List<HInstruction> arguments = <HInstruction>[]; | 4224 generateSuperInvoke(node, element); |
4172 if (!node.isPropertyAccess) { | 4225 } else { |
4173 addGenericSendArgumentsToList(node.arguments, arguments); | 4226 generateWrongArgumentCountError(node, element, node.arguments); |
4174 } | |
4175 return generateSuperNoSuchMethodSend(node, selector, arguments); | |
4176 } | 4227 } |
| 4228 } |
| 4229 |
| 4230 @override |
| 4231 void visitUnresolvedSuperIndex( |
| 4232 ast.Send node, |
| 4233 Element element, |
| 4234 ast.Node index, |
| 4235 _) { |
| 4236 handleUnresolvedSuperInvoke(node); |
| 4237 } |
| 4238 |
| 4239 @override |
| 4240 void visitUnresolvedSuperUnary( |
| 4241 ast.Send node, |
| 4242 UnaryOperator operator, |
| 4243 Element element, |
| 4244 _) { |
| 4245 handleUnresolvedSuperInvoke(node); |
| 4246 } |
| 4247 |
| 4248 @override |
| 4249 void visitUnresolvedSuperBinary( |
| 4250 ast.Send node, |
| 4251 Element element, |
| 4252 BinaryOperator operator, |
| 4253 ast.Node argument, |
| 4254 _) { |
| 4255 handleUnresolvedSuperInvoke(node); |
| 4256 } |
| 4257 |
| 4258 @override |
| 4259 void visitUnresolvedSuperGet( |
| 4260 ast.Send node, |
| 4261 Element element, |
| 4262 _) { |
| 4263 handleUnresolvedSuperInvoke(node); |
| 4264 } |
| 4265 |
| 4266 @override |
| 4267 void visitUnresolvedSuperInvoke( |
| 4268 ast.Send node, |
| 4269 Element element, |
| 4270 ast.Node argument, |
| 4271 Selector selector, |
| 4272 _) { |
| 4273 handleUnresolvedSuperInvoke(node); |
| 4274 } |
| 4275 |
| 4276 @override |
| 4277 void visitSuperFieldGet( |
| 4278 ast.Send node, |
| 4279 FieldElement field, |
| 4280 _) { |
| 4281 handleSuperGet(node, field); |
| 4282 } |
| 4283 |
| 4284 @override |
| 4285 void visitSuperGetterGet( |
| 4286 ast.Send node, |
| 4287 MethodElement method, |
| 4288 _) { |
| 4289 handleSuperGet(node, method); |
| 4290 } |
| 4291 |
| 4292 @override |
| 4293 void visitSuperMethodGet( |
| 4294 ast.Send node, |
| 4295 MethodElement method, |
| 4296 _) { |
| 4297 handleSuperGet(node, method); |
| 4298 } |
| 4299 |
| 4300 @override |
| 4301 void visitSuperFieldInvoke( |
| 4302 ast.Send node, |
| 4303 FieldElement field, |
| 4304 ast.NodeList arguments, |
| 4305 CallStructure callStructure, |
| 4306 _) { |
| 4307 handleSuperCallInvoke(node, field); |
| 4308 } |
| 4309 |
| 4310 @override |
| 4311 void visitSuperGetterInvoke( |
| 4312 ast.Send node, |
| 4313 MethodElement getter, |
| 4314 ast.NodeList arguments, |
| 4315 CallStructure callStructure, |
| 4316 _) { |
| 4317 handleSuperCallInvoke(node, getter); |
| 4318 } |
| 4319 |
| 4320 @override |
| 4321 void visitSuperMethodInvoke( |
| 4322 ast.Send node, |
| 4323 MethodElement method, |
| 4324 ast.NodeList arguments, |
| 4325 CallStructure callStructure, |
| 4326 _) { |
| 4327 handleSuperMethodInvoke(node, method); |
| 4328 } |
| 4329 |
| 4330 @override |
| 4331 void visitSuperIndex( |
| 4332 ast.Send node, |
| 4333 MethodElement method, |
| 4334 ast.Node index, |
| 4335 _) { |
| 4336 handleSuperMethodInvoke(node, method); |
| 4337 } |
| 4338 |
| 4339 @override |
| 4340 void visitSuperEquals( |
| 4341 ast.Send node, |
| 4342 MethodElement method, |
| 4343 ast.Node argument, |
| 4344 _) { |
| 4345 handleSuperMethodInvoke(node, method); |
| 4346 } |
| 4347 |
| 4348 @override |
| 4349 void visitSuperBinary( |
| 4350 ast.Send node, |
| 4351 MethodElement method, |
| 4352 BinaryOperator operator, |
| 4353 ast.Node argument, |
| 4354 _) { |
| 4355 handleSuperMethodInvoke(node, method); |
| 4356 } |
| 4357 |
| 4358 @override |
| 4359 void visitSuperUnary( |
| 4360 ast.Send node, |
| 4361 UnaryOperator operator, |
| 4362 MethodElement method, |
| 4363 _) { |
| 4364 handleSuperMethodInvoke(node, method); |
| 4365 } |
| 4366 |
| 4367 @override |
| 4368 void visitSuperMethodIncompatibleInvoke( |
| 4369 ast.Send node, |
| 4370 MethodElement method, |
| 4371 ast.NodeList arguments, |
| 4372 CallStructure callStructure, |
| 4373 _) { |
| 4374 Selector selector = elements.getSelector(node); |
4177 List<HInstruction> inputs = <HInstruction>[]; | 4375 List<HInstruction> inputs = <HInstruction>[]; |
4178 if (node.isPropertyAccess) { | 4376 addGenericSendArgumentsToList(arguments.nodes, inputs); |
4179 push(buildInvokeSuper(selector, element, inputs)); | 4377 generateSuperNoSuchMethodSend(node, selector, inputs); |
4180 } else if (element.isFunction || element.isGenerativeConstructor) { | |
4181 if (selector.applies(element, compiler.world)) { | |
4182 // TODO(5347): Try to avoid the need for calling [implementation] before | |
4183 // calling [makeStaticArgumentList]. | |
4184 FunctionElement function = element.implementation; | |
4185 assert(selector.applies(function, compiler.world)); | |
4186 inputs = makeStaticArgumentList(selector.callStructure, | |
4187 node.arguments, | |
4188 function); | |
4189 push(buildInvokeSuper(selector, element, inputs)); | |
4190 } else if (element.isGenerativeConstructor) { | |
4191 generateWrongArgumentCountError(node, element, node.arguments); | |
4192 } else { | |
4193 addGenericSendArgumentsToList(node.arguments, inputs); | |
4194 generateSuperNoSuchMethodSend(node, selector, inputs); | |
4195 } | |
4196 } else { | |
4197 HInstruction target = buildInvokeSuper(selector, element, inputs); | |
4198 add(target); | |
4199 inputs = <HInstruction>[target]; | |
4200 addDynamicSendArgumentsToList(node, inputs); | |
4201 Selector closureSelector = new Selector.callClosureFrom(selector); | |
4202 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); | |
4203 } | |
4204 } | 4378 } |
4205 | 4379 |
4206 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { | 4380 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { |
4207 ClassWorld classWorld = compiler.world; | 4381 ClassWorld classWorld = compiler.world; |
4208 if (classWorld.isUsedAsMixin(cls)) return true; | 4382 if (classWorld.isUsedAsMixin(cls)) return true; |
4209 | 4383 |
4210 Iterable<ClassElement> subclasses = compiler.world.strictSubclassesOf(cls); | 4384 Iterable<ClassElement> subclasses = compiler.world.strictSubclassesOf(cls); |
4211 return subclasses.any((ClassElement subclass) { | 4385 return subclasses.any((ClassElement subclass) { |
4212 return !rti.isTrivialSubstitution(subclass, cls); | 4386 return !rti.isTrivialSubstitution(subclass, cls); |
4213 }); | 4387 }); |
(...skipping 3036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7250 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7424 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
7251 unaliased.accept(this, builder); | 7425 unaliased.accept(this, builder); |
7252 } | 7426 } |
7253 | 7427 |
7254 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7428 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
7255 JavaScriptBackend backend = builder.compiler.backend; | 7429 JavaScriptBackend backend = builder.compiler.backend; |
7256 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7430 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
7257 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7431 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
7258 } | 7432 } |
7259 } | 7433 } |
OLD | NEW |