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 final SsaCodeGeneratorTask generator; | 8 final SsaCodeGeneratorTask generator; |
9 final SsaBuilderTask builder; | 9 final SsaBuilderTask builder; |
10 final SsaOptimizerTask optimizer; | 10 final SsaOptimizerTask optimizer; |
(...skipping 3595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3606 assert(send != null); | 3606 assert(send != null); |
3607 location = send; | 3607 location = send; |
3608 } | 3608 } |
3609 assert(selector.isSetter); | 3609 assert(selector.isSetter); |
3610 pushInvokeDynamic(location, selector, mask, [receiver, value], | 3610 pushInvokeDynamic(location, selector, mask, [receiver, value], |
3611 sourceInformation: sourceInformationBuilder.buildAssignment(location)); | 3611 sourceInformation: sourceInformationBuilder.buildAssignment(location)); |
3612 pop(); | 3612 pop(); |
3613 stack.add(value); | 3613 stack.add(value); |
3614 } | 3614 } |
3615 | 3615 |
| 3616 void generateNoSuchSetter(ast.Node location, |
| 3617 Element element, |
| 3618 HInstruction value) { |
| 3619 List<HInstruction> arguments = |
| 3620 value == null ? const <HInstruction>[] : <HInstruction>[value]; |
| 3621 // An erroneous element indicates an unresolved static setter. |
| 3622 generateThrowNoSuchMethod( |
| 3623 location, noSuchMethodTargetSymbolString(element, 'set'), |
| 3624 argumentValues: arguments); |
| 3625 } |
| 3626 |
3616 void generateNonInstanceSetter(ast.SendSet send, | 3627 void generateNonInstanceSetter(ast.SendSet send, |
3617 Element element, | 3628 Element element, |
3618 HInstruction value, | 3629 HInstruction value, |
3619 {ast.Node location}) { | 3630 {ast.Node location}) { |
3620 assert(send == null || !Elements.isInstanceSend(send, elements)); | 3631 assert(send == null || !Elements.isInstanceSend(send, elements)); |
3621 if (location == null) { | 3632 if (location == null) { |
3622 assert(send != null); | 3633 assert(send != null); |
3623 location = send; | 3634 location = send; |
3624 } | 3635 } |
3625 if (Elements.isStaticOrTopLevelField(element)) { | 3636 if (Elements.isStaticOrTopLevelField(element)) { |
3626 if (element.isSetter) { | 3637 if (element.isSetter) { |
3627 pushInvokeStatic(location, element, <HInstruction>[value]); | 3638 pushInvokeStatic(location, element, <HInstruction>[value]); |
3628 pop(); | 3639 pop(); |
3629 } else { | 3640 } else { |
3630 VariableElement field = element; | 3641 VariableElement field = element; |
3631 value = potentiallyCheckOrTrustType(value, field.type); | 3642 value = potentiallyCheckOrTrustType(value, field.type); |
3632 addWithPosition(new HStaticStore(element, value), location); | 3643 addWithPosition(new HStaticStore(element, value), location); |
3633 } | 3644 } |
3634 stack.add(value); | 3645 stack.add(value); |
3635 } else if (Elements.isErroneous(element)) { | 3646 } else if (Elements.isErroneous(element)) { |
3636 if (element is ErroneousElement) { | 3647 if (element is ErroneousElement) { |
3637 List<HInstruction> arguments = | 3648 generateNoSuchSetter(location, element, send == null ? null : value); |
3638 send == null ? const <HInstruction>[] : <HInstruction>[value]; | |
3639 // An erroneous element indicates an unresolved static setter. | |
3640 generateThrowNoSuchMethod( | |
3641 location, noSuchMethodTargetSymbolString(element, 'set'), | |
3642 argumentValues: arguments); | |
3643 } else { | 3649 } else { |
3644 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 3650 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
3645 stack.add(graph.addConstantNull(compiler)); | 3651 stack.add(graph.addConstantNull(compiler)); |
3646 } | 3652 } |
3647 } else { | 3653 } else { |
3648 stack.add(value); | 3654 stack.add(value); |
3649 LocalElement local = element; | 3655 LocalElement local = element; |
3650 // If the value does not already have a name, give it here. | 3656 // If the value does not already have a name, give it here. |
3651 if (value.sourceElement == null) { | 3657 if (value.sourceElement == null) { |
3652 value.sourceElement = local; | 3658 value.sourceElement = local; |
(...skipping 2745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6398 _) { | 6404 _) { |
6399 generateNonInstanceSetter(node, parameter, visitAndPop(rhs)); | 6405 generateNonInstanceSetter(node, parameter, visitAndPop(rhs)); |
6400 } | 6406 } |
6401 | 6407 |
6402 @override | 6408 @override |
6403 void visitFinalParameterSet( | 6409 void visitFinalParameterSet( |
6404 ast.SendSet node, | 6410 ast.SendSet node, |
6405 ParameterElement parameter, | 6411 ParameterElement parameter, |
6406 ast.Node rhs, | 6412 ast.Node rhs, |
6407 _) { | 6413 _) { |
6408 generateNonInstanceSetter(node, parameter, visitAndPop(rhs)); | 6414 generateNoSuchSetter(node, parameter, visitAndPop(rhs)); |
6409 } | 6415 } |
6410 | 6416 |
6411 @override | 6417 @override |
6412 void visitLocalVariableSet( | 6418 void visitLocalVariableSet( |
6413 ast.SendSet node, | 6419 ast.SendSet node, |
6414 LocalVariableElement variable, | 6420 LocalVariableElement variable, |
6415 ast.Node rhs, | 6421 ast.Node rhs, |
6416 _) { | 6422 _) { |
6417 generateNonInstanceSetter(node, variable, visitAndPop(rhs)); | 6423 generateNonInstanceSetter(node, variable, visitAndPop(rhs)); |
6418 } | 6424 } |
6419 | 6425 |
6420 @override | 6426 @override |
6421 void visitFinalLocalVariableSet( | 6427 void visitFinalLocalVariableSet( |
6422 ast.SendSet node, | 6428 ast.SendSet node, |
6423 LocalVariableElement variable, | 6429 LocalVariableElement variable, |
6424 ast.Node rhs, | 6430 ast.Node rhs, |
6425 _) { | 6431 _) { |
6426 generateNonInstanceSetter(node, variable, visitAndPop(rhs)); | 6432 generateNoSuchSetter(node, variable, visitAndPop(rhs)); |
6427 } | 6433 } |
6428 | 6434 |
6429 @override | 6435 @override |
6430 void visitLocalFunctionSet( | 6436 void visitLocalFunctionSet( |
6431 ast.SendSet node, | 6437 ast.SendSet node, |
6432 LocalFunctionElement function, | 6438 LocalFunctionElement function, |
6433 ast.Node rhs, | 6439 ast.Node rhs, |
6434 _) { | 6440 _) { |
6435 generateNonInstanceSetter(node, function, visitAndPop(rhs)); | 6441 generateNoSuchSetter(node, function, visitAndPop(rhs)); |
6436 } | 6442 } |
6437 | 6443 |
6438 @override | 6444 @override |
6439 void visitTopLevelFieldSet( | 6445 void visitTopLevelFieldSet( |
6440 ast.SendSet node, | 6446 ast.SendSet node, |
6441 FieldElement field, | 6447 FieldElement field, |
6442 ast.Node rhs, | 6448 ast.Node rhs, |
6443 _) { | 6449 _) { |
6444 generateIsDeferredLoadedCheckOfSend(node); | 6450 generateIsDeferredLoadedCheckOfSend(node); |
6445 generateNonInstanceSetter(node, field, visitAndPop(rhs)); | 6451 generateNonInstanceSetter(node, field, visitAndPop(rhs)); |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6926 compiler.internalError(node, | 6932 compiler.internalError(node, |
6927 'Visiting type annotation in SSA builder.'); | 6933 'Visiting type annotation in SSA builder.'); |
6928 } | 6934 } |
6929 | 6935 |
6930 visitVariableDefinitions(ast.VariableDefinitions node) { | 6936 visitVariableDefinitions(ast.VariableDefinitions node) { |
6931 assert(isReachable); | 6937 assert(isReachable); |
6932 for (Link<ast.Node> link = node.definitions.nodes; | 6938 for (Link<ast.Node> link = node.definitions.nodes; |
6933 !link.isEmpty; | 6939 !link.isEmpty; |
6934 link = link.tail) { | 6940 link = link.tail) { |
6935 ast.Node definition = link.head; | 6941 ast.Node definition = link.head; |
| 6942 LocalElement local = elements[definition]; |
6936 if (definition is ast.Identifier) { | 6943 if (definition is ast.Identifier) { |
6937 HInstruction initialValue = graph.addConstantNull(compiler); | 6944 HInstruction initialValue = graph.addConstantNull(compiler); |
6938 LocalElement local = elements[definition]; | |
6939 localsHandler.updateLocal(local, initialValue); | 6945 localsHandler.updateLocal(local, initialValue); |
6940 } else { | 6946 } else { |
6941 assert(definition is ast.SendSet); | 6947 ast.SendSet node = definition; |
6942 visitSendSet(definition); | 6948 generateNonInstanceSetter( |
| 6949 node, local, visitAndPop(node.arguments.first)); |
6943 pop(); // Discard value. | 6950 pop(); // Discard value. |
6944 } | 6951 } |
6945 } | 6952 } |
6946 } | 6953 } |
6947 | 6954 |
6948 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { | 6955 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { |
6949 InterfaceType type = localsHandler.substInContext(elements.getType(node)); | 6956 InterfaceType type = localsHandler.substInContext(elements.getType(node)); |
6950 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 6957 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
6951 return object; | 6958 return object; |
6952 } | 6959 } |
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8853 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 8860 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
8854 unaliased.accept(this, builder); | 8861 unaliased.accept(this, builder); |
8855 } | 8862 } |
8856 | 8863 |
8857 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 8864 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
8858 JavaScriptBackend backend = builder.compiler.backend; | 8865 JavaScriptBackend backend = builder.compiler.backend; |
8859 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 8866 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
8860 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 8867 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
8861 } | 8868 } |
8862 } | 8869 } |
OLD | NEW |