Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1004683002: Refactor IrBuilder to use SemanticVisitor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Handle local/static constants and index prefix/postfix. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder_task; 5 library dart2js.ir_builder_task;
6 6
7 import '../closure.dart' as closurelib; 7 import '../closure.dart' as closurelib;
8 import '../closure.dart' hide ClosureScope; 8 import '../closure.dart' hide ClosureScope;
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../dart2jslib.dart'; 11 import '../dart2jslib.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../elements/modelx.dart' show SynthesizedConstructorElementX, 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX,
14 ConstructorBodyElementX, FunctionSignatureX; 14 ConstructorBodyElementX, FunctionSignatureX;
15 import '../io/source_file.dart'; 15 import '../io/source_file.dart';
16 import '../io/source_information.dart'; 16 import '../io/source_information.dart';
17 import '../js_backend/js_backend.dart' show JavaScriptBackend; 17 import '../js_backend/js_backend.dart' show JavaScriptBackend;
18 import '../resolution/semantic_visitor.dart';
19 import '../resolution/operators.dart' as op;
18 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; 20 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
19 import '../tree/tree.dart' as ast; 21 import '../tree/tree.dart' as ast;
20 import '../universe/universe.dart' show SelectorKind; 22 import '../universe/universe.dart' show SelectorKind;
21 import 'cps_ir_nodes.dart' as ir; 23 import 'cps_ir_nodes.dart' as ir;
22 import 'cps_ir_builder.dart'; 24 import 'cps_ir_builder.dart';
23 25
24 /** 26 /**
25 * This task iterates through all resolved elements and builds [ir.Node]s. The 27 * This task iterates through all resolved elements and builds [ir.Node]s. The
26 * nodes are stored in the [nodes] map and accessible through [hasIr] and 28 * nodes are stored in the [nodes] map and accessible through [hasIr] and
27 * [getIr]. 29 * [getIr].
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 111 }
110 112
111 bool get inCheckedMode { 113 bool get inCheckedMode {
112 bool result = false; 114 bool result = false;
113 assert((result = true)); 115 assert((result = true));
114 return result; 116 return result;
115 } 117 }
116 118
117 } 119 }
118 120
119 class _GetterElements {
120 ir.Primitive result;
121 ir.Primitive index;
122 ir.Primitive receiver;
123
124 _GetterElements({this.result, this.index, this.receiver}) ;
125 }
126
127 /** 121 /**
128 * A tree visitor that builds [IrNodes]. The visit methods add statements using 122 * A tree visitor that builds [IrNodes]. The visit methods add statements using
129 * to the [builder] and return the last added statement for trees that represent 123 * to the [builder] and return the last added statement for trees that represent
130 * an expression. 124 * an expression.
131 */ 125 */
132 abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> 126 abstract class IrBuilderVisitor extends SemanticVisitor<ir.Primitive, dynamic>
133 with IrBuilderMixin<ast.Node> { 127 with IrBuilderMixin<ast.Node>,
128 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>,
129 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
130 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>,
131 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>,
132 BaseImplementationOfSuperIncDecsMixin<ir.Primitive, dynamic>,
133 ErrorBulkMixin<ir.Primitive, dynamic>
134 implements SemanticSendVisitor<ir.Primitive, dynamic> {
134 final Compiler compiler; 135 final Compiler compiler;
135 final SourceInformationBuilder sourceInformationBuilder; 136 final SourceInformationBuilder sourceInformationBuilder;
136 137
137 // In SSA terms, join-point continuation parameters are the phis and the 138 // In SSA terms, join-point continuation parameters are the phis and the
138 // continuation invocation arguments are the corresponding phi inputs. To 139 // continuation invocation arguments are the corresponding phi inputs. To
139 // support name introduction and renaming for source level variables, we use 140 // support name introduction and renaming for source level variables, we use
140 // nested (delimited) visitors for constructing subparts of the IR that will 141 // nested (delimited) visitors for constructing subparts of the IR that will
141 // need renaming. Each source variable is assigned an index. 142 // need renaming. Each source variable is assigned an index.
142 // 143 //
143 // Each nested visitor maintains a list of free variable uses in the body. 144 // Each nested visitor maintains a list of free variable uses in the body.
144 // These are implemented as a list of parameters, each with their own use 145 // These are implemented as a list of parameters, each with their own use
145 // list of references. When the delimited subexpression is plugged into the 146 // list of references. When the delimited subexpression is plugged into the
146 // surrounding context, the free occurrences can be captured or become free 147 // surrounding context, the free occurrences can be captured or become free
147 // occurrences in the next outer delimited subexpression. 148 // occurrences in the next outer delimited subexpression.
148 // 149 //
149 // Each nested visitor maintains a list that maps indexes of variables 150 // Each nested visitor maintains a list that maps indexes of variables
150 // assigned in the delimited subexpression to their reaching definition --- 151 // assigned in the delimited subexpression to their reaching definition ---
151 // that is, the definition in effect at the hole in 'current'. These are 152 // that is, the definition in effect at the hole in 'current'. These are
152 // used to determine if a join-point continuation needs to be passed 153 // used to determine if a join-point continuation needs to be passed
153 // arguments, and what the arguments are. 154 // arguments, and what the arguments are.
154 155
155 /// Construct a top-level visitor. 156 /// Construct a top-level visitor.
156 IrBuilderVisitor(TreeElements elements, 157 IrBuilderVisitor(TreeElements elements,
157 this.compiler, 158 this.compiler,
158 this.sourceInformationBuilder) 159 this.sourceInformationBuilder)
159 : super(elements); 160 : super(elements);
160 161
162 @override
163 bulkHandleNode(ast.Node node, String message) => giveup(node, message);
164
165 @override
166 ir.Primitive apply(ast.Node node, _) => node.accept(this);
167
168 @override
169 SemanticSendVisitor get sendVisitor => this;
170
161 /** 171 /**
162 * Builds the [ir.ExecutableDefinition] for an executable element. In case the 172 * Builds the [ir.ExecutableDefinition] for an executable element. In case the
163 * function uses features that cannot be expressed in the IR, this element 173 * function uses features that cannot be expressed in the IR, this element
164 * returns `null`. 174 * returns `null`.
165 */ 175 */
166 ir.ExecutableDefinition buildExecutable(ExecutableElement element); 176 ir.ExecutableDefinition buildExecutable(ExecutableElement element);
167 177
168 ClosureScope getClosureScopeForNode(ast.Node node); 178 ClosureScope getClosureScopeForNode(ast.Node node);
169 ClosureEnvironment getClosureEnvironment(); 179 ClosureEnvironment getClosureEnvironment();
170 180
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 result.add(irBuilder.makeSuperInitializer(target, 304 result.add(irBuilder.makeSuperInitializer(target,
295 <ir.RunnableBody>[], 305 <ir.RunnableBody>[],
296 selector)); 306 selector));
297 } 307 }
298 } 308 }
299 return result; 309 return result;
300 } 310 }
301 311
302 ir.Primitive visit(ast.Node node) => node.accept(this); 312 ir.Primitive visit(ast.Node node) => node.accept(this);
303 313
304 // ==== Statements ==== 314 // ## Statements ##
305 visitBlock(ast.Block node) { 315 visitBlock(ast.Block node) {
306 irBuilder.buildBlock(node.statements.nodes, build); 316 irBuilder.buildBlock(node.statements.nodes, build);
307 } 317 }
308 318
309 ir.Primitive visitBreakStatement(ast.BreakStatement node) { 319 ir.Primitive visitBreakStatement(ast.BreakStatement node) {
310 if (!irBuilder.buildBreak(elements.getTargetOf(node))) { 320 if (!irBuilder.buildBreak(elements.getTargetOf(node))) {
311 compiler.internalError(node, "'break' target not found"); 321 compiler.internalError(node, "'break' target not found");
312 } 322 }
313 return null; 323 return null;
314 } 324 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 stackTraceVariable: stackTraceVariable, 492 stackTraceVariable: stackTraceVariable,
483 buildCatchBlock: subbuild(catchClause.block))); 493 buildCatchBlock: subbuild(catchClause.block)));
484 } 494 }
485 495
486 irBuilder.buildTry( 496 irBuilder.buildTry(
487 tryStatementInfo: irBuilder.tryStatements[node], 497 tryStatementInfo: irBuilder.tryStatements[node],
488 buildTryBlock: subbuild(node.tryBlock), 498 buildTryBlock: subbuild(node.tryBlock),
489 catchClauseInfos: catchClauseInfos); 499 catchClauseInfos: catchClauseInfos);
490 } 500 }
491 501
492 // ==== Expressions ==== 502 // ## Expressions ##
493 ir.Primitive visitConditional(ast.Conditional node) { 503 ir.Primitive visitConditional(ast.Conditional node) {
494 return irBuilder.buildConditional( 504 return irBuilder.buildConditional(
495 build(node.condition), 505 build(node.condition),
496 subbuild(node.thenExpression), 506 subbuild(node.thenExpression),
497 subbuild(node.elseExpression)); 507 subbuild(node.elseExpression));
498 } 508 }
499 509
500 // For all simple literals: 510 // For all simple literals:
501 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] 511 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x]
502 ir.Primitive visitLiteralBool(ast.LiteralBool node) { 512 ir.Primitive visitLiteralBool(ast.LiteralBool node) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 assert(irBuilder.isOpen); 601 assert(irBuilder.isOpen);
592 var oldCascadeReceiver = _currentCascadeReceiver; 602 var oldCascadeReceiver = _currentCascadeReceiver;
593 // Throw away the result of visiting the expression. 603 // Throw away the result of visiting the expression.
594 // Instead we return the result of visiting the CascadeReceiver. 604 // Instead we return the result of visiting the CascadeReceiver.
595 this.visit(node.expression); 605 this.visit(node.expression);
596 ir.Primitive receiver = _currentCascadeReceiver; 606 ir.Primitive receiver = _currentCascadeReceiver;
597 _currentCascadeReceiver = oldCascadeReceiver; 607 _currentCascadeReceiver = oldCascadeReceiver;
598 return receiver; 608 return receiver;
599 } 609 }
600 610
601 // ==== Sends ==== 611 // ## Sends ##
602 ir.Primitive visitAssert(ast.Send node) { 612 @override
613 ir.Primitive visitAssert(
614 ast.Send node,
615 ast.Node condition,
616 _) {
603 assert(irBuilder.isOpen); 617 assert(irBuilder.isOpen);
604 return giveup(node, 'Assert'); 618 return giveup(node, 'Assert');
605 } 619 }
606 620
607 ir.Primitive visitNamedArgument(ast.NamedArgument node) { 621 ir.Primitive visitNamedArgument(ast.NamedArgument node) {
608 assert(irBuilder.isOpen); 622 assert(irBuilder.isOpen);
609 return visit(node.expression); 623 return visit(node.expression);
610 } 624 }
611 625
612 ir.Primitive visitClosureSend(ast.Send node) { 626 @override
613 assert(irBuilder.isOpen); 627 ir.Primitive visitExpressionInvoke(ast.Send node,
614 Element element = elements[node]; 628 ast.Node expression,
615 Selector selector = elements.getSelector(node); 629 ast.NodeList arguments,
616 ir.Primitive receiver = (element == null) 630 Selector selector, _) {
617 ? visit(node.selector) 631 ir.Primitive receiver = visit(expression);
618 : irBuilder.buildLocalGet(element);
619 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 632 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
620 arguments = normalizeDynamicArguments(selector, arguments); 633 arguments = normalizeDynamicArguments(selector, arguments);
621 return irBuilder.buildCallInvocation(receiver, selector, arguments); 634 return irBuilder.buildCallInvocation(receiver, selector, arguments);
622 } 635 }
623 636
624 /// If [node] is null, returns this.
625 /// If [node] is super, returns null (for special handling)
626 /// Otherwise visits [node] and returns the result.
627 ir.Primitive visitReceiver(ast.Expression node) {
628 if (node == null) return irBuilder.buildThis();
629 if (node.isSuper()) return null;
630 return visit(node);
631 }
632
633 /// Returns `true` if [node] is a super call. 637 /// Returns `true` if [node] is a super call.
634 // TODO(johnniwinther): Remove the need for this. 638 // TODO(johnniwinther): Remove the need for this.
635 bool isSuperCall(ast.Send node) { 639 bool isSuperCall(ast.Send node) {
636 return node != null && node.receiver != null && node.receiver.isSuper(); 640 return node != null && node.receiver != null && node.receiver.isSuper();
637 } 641 }
638 642
639 ir.Primitive visitDynamicSend(ast.Send node) { 643 @override
640 assert(irBuilder.isOpen); 644 ir.Primitive handleConstantGet(ast.Send node,
641 Selector selector = elements.getSelector(node); 645 ConstantExpression constant, _) {
642 ir.Primitive receiver = visitReceiver(node.receiver); 646 return irBuilder.buildConstantLiteral(constant);
643 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
644 arguments = normalizeDynamicArguments(selector, arguments);
645 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
646 } 647 }
647 648
648 _GetterElements translateGetter(ast.Send node, Selector selector) { 649 /// If [node] is null, returns this.
649 Element element = elements[node]; 650 /// Otherwise visits [node] and returns the result.
650 ir.Primitive result; 651 ir.Primitive translateReceiver(ast.Expression node) {
651 ir.Primitive receiver; 652 return node != null ? visit(node) : irBuilder.buildThis();
652 ir.Primitive index;
653
654 if (element != null && element.isConst) {
655 // Reference to constant local, top-level or static field
656 result = translateConstant(node);
657 } else if (Elements.isLocal(element)) {
658 // Reference to local variable
659 result = irBuilder.buildLocalGet(element);
660 } else if (element == null ||
661 Elements.isInstanceField(element) ||
662 Elements.isInstanceMethod(element) ||
663 selector.isIndex ||
664 // TODO(johnniwinther): clean up semantics of resolution.
665 node.isSuperCall) {
666 // Dynamic dispatch to a getter. Sometimes resolution will suggest a
667 // target element, but in these cases we must still emit a dynamic
668 // dispatch. The target element may be an instance method in case we are
669 // converting a method to a function object.
670
671 receiver = visitReceiver(node.receiver);
672 List<ir.Primitive> arguments = new List<ir.Primitive>();
673 if (selector.isIndex) {
674 index = visit(node.arguments.head);
675 arguments.add(index);
676 }
677
678 assert(selector.kind == SelectorKind.GETTER ||
679 selector.kind == SelectorKind.INDEX);
680 if (isSuperCall(node)) {
681 result = irBuilder.buildSuperInvocation(element, selector, arguments);
682 } else {
683 result =
684 irBuilder.buildDynamicInvocation(receiver, selector, arguments);
685 }
686 } else if (element.isField || element.isGetter || element.isErroneous ||
687 element.isSetter) {
688 // TODO(johnniwinther): Change handling of setter selectors.
689 // Access to a static field or getter (non-static case handled above).
690 // Even if there is only a setter, we compile as if it was a getter,
691 // so the vm can fail at runtime.
692 assert(selector.kind == SelectorKind.GETTER ||
693 selector.kind == SelectorKind.SETTER);
694 result = irBuilder.buildStaticGet(element, selector,
695 sourceInformation: sourceInformationBuilder.buildGet(node));
696 } else if (Elements.isStaticOrTopLevelFunction(element)) {
697 // Convert a top-level or static function to a function object.
698 result = translateConstant(node);
699 } else {
700 throw "Unexpected SendSet getter: $node, $element";
701 }
702 return new _GetterElements(
703 result: result,index: index, receiver: receiver);
704 } 653 }
705 654
706 ir.Primitive visitGetterSend(ast.Send node) { 655 @override
707 assert(irBuilder.isOpen); 656 ir.Primitive handleDynamicGet(
708 return translateGetter(node, elements.getSelector(node)).result; 657 ast.Send node,
709 658 ast.Node receiver,
659 Selector selector,
660 _) {
661 return irBuilder.buildDynamicGet(
662 translateReceiver(receiver),
663 selector);
710 } 664 }
711 665
712 ir.Primitive translateLogicalOperator(ast.Operator op, 666 @override
713 ast.Expression left, 667 ir.Primitive visitDynamicTypeLiteralGet(
714 ast.Expression right) { 668 ast.Send node,
669 ConstantExpression constant,
670 _) {
671 return irBuilder.buildConstantLiteral(constant);
672 }
673
674 @override
675 ir.Primitive handleLocalGet(
676 ast.Send node,
677 LocalElement element,
678 _) {
679 if (element.isConst) {
680 return translateConstant(node);
681 }
682 return irBuilder.buildLocalGet(element);
683 }
684
685 @override
686 ir.Primitive handleStaticFieldGet(
687 ast.Send node,
688 FieldElement field,
689 _) {
690 if (field.isConst) {
691 return translateConstant(node);
692 }
693 return irBuilder.buildStaticGet(field,
694 sourceInformation: sourceInformationBuilder.buildGet(node));
695 }
696
697 @override
698 ir.Primitive handleStaticFunctionGet(
699 ast.Send node,
700 MethodElement function,
701 _) {
702 // TODO(karlklose): support foreign functions.
703 if (function.isForeign(compiler.backend)) {
704 return giveup(node, 'handleStaticFunctionGet: foreign: $function');
705 }
706 return translateConstant(node);
707 }
708
709 @override
710 ir.Primitive handleStaticGetterGet(
711 ast.Send node,
712 FunctionElement getter,
713 _) {
714 return irBuilder.buildStaticInvocation(getter,
715 new Selector.getter(getter.name, getter.library), const []);
716 }
717
718 @override
719 ir.Primitive visitSuperFieldGet(
720 ast.Send node,
721 FieldElement field,
722 _) {
723 return irBuilder.buildSuperGet(field);
724 }
725
726 @override
727 ir.Primitive visitSuperGetterGet(
728 ast.Send node,
729 FunctionElement getter,
730 _) {
731 return irBuilder.buildSuperGet(getter);
732 }
733
734 @override
735 ir.Primitive visitSuperMethodGet(
736 ast.Send node,
737 MethodElement method,
738 _) {
739 return irBuilder.buildSuperGet(method);
740 }
741
742 @override
743 ir.Primitive visitThisGet(ast.Identifier node, _) {
744 return irBuilder.buildThis();
745 }
746
747 ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) {
748 return buildReifyTypeVariable(irBuilder.buildThis(), element.type);
749 }
750
751 @override
752 ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node,
753 TypeVariableElement element, _) {
754 return translateTypeVariableTypeLiteral(element);
755 }
756
757 ir.Primitive translateLogicalOperator(ast.Expression left,
758 ast.Expression right,
759 {bool isLazyOr}) {
715 ir.Primitive leftValue = visit(left); 760 ir.Primitive leftValue = visit(left);
716 761
717 ir.Primitive buildRightValue(IrBuilder rightBuilder) { 762 ir.Primitive buildRightValue(IrBuilder rightBuilder) {
718 return withBuilder(rightBuilder, () => visit(right)); 763 return withBuilder(rightBuilder, () => visit(right));
719 } 764 }
720 765
721 return irBuilder.buildLogicalOperator( 766 return irBuilder.buildLogicalOperator(
722 leftValue, buildRightValue, isLazyOr: op.source == '||'); 767 leftValue, buildRightValue, isLazyOr: isLazyOr);
723 } 768 }
724 769
725 ir.Primitive visitOperatorSend(ast.Send node) { 770 @override
726 assert(irBuilder.isOpen); 771 ir.Primitive visitLogicalAnd(
727 ast.Operator op = node.selector; 772 ast.Send node, ast.Node left, ast.Node right, _) {
728 if (isUserDefinableOperator(op.source)) { 773 return translateLogicalOperator(left, right, isLazyOr: false);
729 return visitDynamicSend(node); 774 }
730 } 775
731 if (op.source == '&&' || op.source == '||') { 776 @override
732 assert(node.receiver != null); 777 ir.Primitive visitLogicalOr(
733 assert(!node.arguments.isEmpty); 778 ast.Send node, ast.Node left, ast.Node right, _) {
734 assert(node.arguments.tail.isEmpty); 779 return translateLogicalOperator(left, right, isLazyOr: true);
735 return translateLogicalOperator(op, node.receiver, node.arguments.head); 780 }
736 } 781
737 if (op.source == "!") { 782 @override
738 assert(node.receiver != null); 783 ir.Primitive visitAs(
739 assert(node.arguments.isEmpty); 784 ast.Send node,
740 return irBuilder.buildNegation(visit(node.receiver)); 785 ast.Node expression,
741 } 786 DartType type,
742 if (op.source == "!=") { 787 _) {
743 assert(node.receiver != null); 788 ir.Primitive receiver = visit(expression);
744 assert(!node.arguments.isEmpty); 789 return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false);
745 assert(node.arguments.tail.isEmpty); 790 }
746 return irBuilder.buildNegation(visitDynamicSend(node)); 791
747 } 792 @override
748 assert(invariant(node, op.source == "is" || op.source == "as", 793 ir.Primitive visitIs(
749 message: "unexpected operator $op")); 794 ast.Send node,
750 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 795 ast.Node expression,
751 ir.Primitive receiver = visit(node.receiver); 796 DartType type,
797 _) {
798 ir.Primitive receiver = visit(expression);
752 return irBuilder.buildTypeOperator( 799 return irBuilder.buildTypeOperator(
753 receiver, type, 800 receiver, type,
754 isTypeTest: op.source == "is", 801 isTypeTest: true,
755 isNotCheck: node.isIsNotCheck); 802 isNotCheck: false);
756 } 803 }
757 804
758 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] 805 @override
759 // where (C', xs) = arguments.fold(Build, C) 806 ir.Primitive visitIsNot(ast.Send node,
760 ir.Primitive visitStaticSend(ast.Send node) { 807 ast.Node expression, DartType type, _) {
761 assert(irBuilder.isOpen); 808 ir.Primitive receiver = visit(expression);
762 Element element = elements[node]; 809 return irBuilder.buildTypeOperator(
763 assert(!element.isConstructor); 810 receiver, type,
764 // TODO(lry): support foreign functions. 811 isTypeTest: true,
765 if (element.isForeign(compiler.backend)) { 812 isNotCheck: true);
766 return giveup(node, 'StaticSend: foreign'); 813 }
814
815 ir.Primitive translateBinary(ast.Node left,
816 op.BinaryOperator operator,
817 ast.Node right) {
818 Selector selector = new Selector.binaryOperator(operator.selectorName);
819 ir.Primitive receiver = visit(left);
820 List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
821 arguments = normalizeDynamicArguments(selector, arguments);
822 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
823 }
824
825 @override
826 ir.Primitive visitBinary(ast.Send node,
827 ast.Node left,
828 op.BinaryOperator operator,
829 ast.Node right, _) {
830 return translateBinary(left, operator, right);
831 }
832
833 @override
834 ir.Primitive visitIndex(ast.Send node,
835 ast.Node receiver,
836 ast.Node index, _) {
837 Selector selector = new Selector.index();
838 ir.Primitive target = visit(receiver);
839 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
840 arguments = normalizeDynamicArguments(selector, arguments);
841 return irBuilder.buildDynamicInvocation(target, selector, arguments);
842 }
843
844 ir.Primitive translateSuperBinary(FunctionElement function,
845 op.BinaryOperator operator,
846 ast.Node argument) {
847 Selector selector = new Selector.binaryOperator(operator.selectorName);
848 List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
849 arguments = normalizeDynamicArguments(selector, arguments);
850 return irBuilder.buildSuperInvocation(function, selector, arguments);
851 }
852
853 @override
854 ir.Primitive visitSuperBinary(
855 ast.Send node,
856 FunctionElement function,
857 op.BinaryOperator operator,
858 ast.Node argument,
859 _) {
860 return translateSuperBinary(function, operator, argument);
861 }
862
863 @override
864 ir.Primitive visitSuperIndex(
865 ast.Send node,
866 FunctionElement function,
867 ast.Node index,
868 _) {
869 Selector selector = new Selector.index();
870 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
871 arguments = normalizeDynamicArguments(selector, arguments);
872 return irBuilder.buildSuperInvocation(function, selector, arguments);
873 }
874
875 @override
876 ir.Primitive visitEquals(
877 ast.Send node,
878 ast.Node left,
879 ast.Node right,
880 _) {
881 return translateBinary(left, op.BinaryOperator.EQ, right);
882 }
883
884 @override
885 ir.Primitive visitSuperEquals(
886 ast.Send node,
887 FunctionElement function,
888 ast.Node argument,
889 _) {
890 return translateSuperBinary(function, op.BinaryOperator.EQ, argument);
891 }
892
893 @override
894 ir.Primitive visitNot(
895 ast.Send node,
896 ast.Node expression,
897 _) {
898 return irBuilder.buildNegation(visit(expression));
899 }
900
901 @override
902 ir.Primitive visitNotEquals(
903 ast.Send node,
904 ast.Node left,
905 ast.Node right,
906 _) {
907 return irBuilder.buildNegation(
908 translateBinary(left, op.BinaryOperator.NOT_EQ, right));
909 }
910
911 @override
912 ir.Primitive visitSuperNotEquals(
913 ast.Send node,
914 FunctionElement function,
915 ast.Node argument,
916 _) {
917 return irBuilder.buildNegation(
918 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument));
919 }
920
921 @override
922 ir.Primitive visitUnary(ast.Send node,
923 op.UnaryOperator operator, ast.Node expression, _) {
924 // TODO(johnniwinther): Clean up the creation of selectors.
925 Selector selector =
926 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
927 ir.Primitive receiver = translateReceiver(expression);
928 return irBuilder.buildDynamicInvocation(receiver, selector, const []);
929 }
930
931 @override
932 ir.Primitive visitSuperUnary(
933 ast.Send node,
934 op.UnaryOperator operator,
935 FunctionElement function,
936 _) {
937 // TODO(johnniwinther): Clean up the creation of selectors.
938 Selector selector =
939 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
940 return irBuilder.buildSuperInvocation(function, selector, const []);
941 }
942
943 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
944 // semantic correlation between arguments and invocation.
945 List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
946 Selector selector) {
947 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
948 return normalizeDynamicArguments(selector, arguments);
949 }
950
951 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
952 // semantic correlation between arguments and invocation.
953 List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
954 Element element,
955 Selector selector) {
956 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
957 return normalizeStaticArguments(selector, element, arguments);
958 }
959
960 ir.Primitive translateCallInvoke(ir.Primitive target,
961 ast.NodeList arguments,
962 Selector selector) {
963
964 return irBuilder.buildCallInvocation(target, selector,
965 translateDynamicArguments(arguments, selector));
966 }
967
968 ir.Primitive translateConstantInvoke(ConstantExpression constant,
969 ast.NodeList arguments,
970 Selector selector) {
971 return translateCallInvoke(
972 irBuilder.buildConstantLiteral(constant),
973 arguments,
974 selector);
975 }
976
977 @override
978 ir.Primitive handleConstantInvoke(
979 ast.Send node,
980 ConstantExpression constant,
981 ast.NodeList arguments,
982 Selector selector,
983 _) {
984 return translateConstantInvoke(constant, arguments, selector);
985 }
986
987 @override
988 ir.Primitive handleDynamicInvoke(
989 ast.Send node,
990 ast.Node receiver,
991 ast.NodeList arguments,
992 Selector selector,
993 _) {
994 return irBuilder.buildDynamicInvocation(
995 translateReceiver(receiver), selector,
996 translateDynamicArguments(arguments, selector));
997 }
998
999 ir.Primitive handleLocalInvoke(
1000 ast.Send node,
1001 LocalElement element,
1002 ast.NodeList arguments,
1003 Selector selector,
1004 _) {
1005 return irBuilder.buildLocalInvocation(element, selector,
1006 translateDynamicArguments(arguments, selector));
1007 }
1008
1009 @override
1010 ir.Primitive handleStaticFieldInvoke(
1011 ast.Send node,
1012 FieldElement field,
1013 ast.NodeList arguments,
1014 Selector selector,
1015 _) {
1016 return translateCallInvoke(
1017 irBuilder.buildStaticGet(field),
1018 arguments, selector);
1019 }
1020
1021 @override
1022 ir.Primitive handleStaticFunctionInvoke(
1023 ast.Send node,
1024 MethodElement function,
1025 ast.NodeList arguments,
1026 Selector selector,
1027 _) {
1028 // TODO(karlklose): support foreign functions.
1029 if (function.isForeign(compiler.backend)) {
1030 return giveup(node, 'handleStaticFunctionInvoke: foreign: $function');
767 } 1031 }
768 1032 return irBuilder.buildStaticInvocation(function, selector,
769 Selector selector = elements.getSelector(node); 1033 translateStaticArguments(arguments, function, selector),
770 1034 sourceInformation: sourceInformationBuilder.buildCall(node));
771 if (selector.isCall && (element.isGetter || element.isField)) { 1035 }
772 // We are invoking a static field or getter as if it was a method, e.g: 1036
773 // 1037 @override
774 // get foo => {..} 1038 ir.Primitive handleStaticGetterInvoke(
775 // main() { foo(1, 2, 3); } 1039 ast.Send node,
776 // 1040 FunctionElement getter,
777 // We invoke the getter of 'foo' and then invoke the 'call' method 1041 ast.NodeList arguments,
778 // on the result, using the given arguments. 1042 Selector selector,
779 Selector getter = new Selector.getterFrom(selector); 1043 _) {
780 Selector call = new Selector.callClosureFrom(selector); 1044 return translateCallInvoke(
781 ir.Primitive receiver = irBuilder.buildStaticGet(element, getter); 1045 irBuilder.buildStaticGet(getter),
782 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1046 arguments, selector);
783 arguments = normalizeDynamicArguments(selector, arguments); 1047 }
784 return irBuilder.buildCallInvocation(receiver, call, arguments); 1048
785 } else if (selector.isGetter) { 1049 @override
786 // We are reading a static field or invoking a static getter. 1050 ir.Primitive visitSuperFieldInvoke(
787 return irBuilder.buildStaticGet(element, selector); 1051 ast.Send node,
788 } else { 1052 FieldElement field,
789 // We are invoking a static method. 1053 ast.NodeList arguments,
790 assert(selector.isCall); 1054 Selector selector,
791 assert(element is FunctionElement); 1055 _) {
792 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1056 return translateCallInvoke(
793 arguments = normalizeStaticArguments(selector, element, arguments); 1057 irBuilder.buildSuperGet(field),
794 return irBuilder.buildStaticInvocation(element, selector, arguments, 1058 arguments, selector);
795 sourceInformation: sourceInformationBuilder.buildCall(node)); 1059 }
796 } 1060
797 } 1061 @override
798 1062 ir.Primitive visitSuperGetterInvoke(
799 ir.Primitive visitSuperSend(ast.Send node) { 1063 ast.Send node,
800 assert(irBuilder.isOpen); 1064 FunctionElement getter,
801 Selector selector = elements.getSelector(node); 1065 ast.NodeList arguments,
802 Element target = elements[node]; 1066 Selector selector,
803 1067 _) {
804 if (selector.isCall && (target.isGetter || target.isField)) { 1068 return translateCallInvoke(
805 // We are invoking a field or getter as if it was a method, e.g: 1069 irBuilder.buildSuperGet(getter),
806 // 1070 arguments, selector);
807 // class A { get foo => {..} } 1071 }
808 // class B extends A { 1072
809 // m() { 1073 @override
810 // super.foo(1, 2, 3); } 1074 ir.Primitive visitSuperMethodInvoke(
811 // } 1075 ast.Send node,
812 // } 1076 MethodElement method,
813 // 1077 ast.NodeList arguments,
814 // We invoke the getter of 'foo' and then invoke the 'call' method on 1078 Selector selector,
815 // the result, using the given arguments. 1079 _) {
816 Selector getter = new Selector.getterFrom(selector); 1080 return irBuilder.buildSuperInvocation(method, selector,
817 Selector call = new Selector.callClosureFrom(selector); 1081 translateDynamicArguments(arguments, selector));
818 ir.Primitive receiver = 1082 }
819 irBuilder.buildSuperInvocation(target, getter, []); 1083
820 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1084 @override
821 arguments = normalizeDynamicArguments(selector, arguments); 1085 ir.Primitive visitThisInvoke(
822 return irBuilder.buildCallInvocation(receiver, call, arguments); 1086 ast.Send node,
823 } else if (selector.isCall) { 1087 ast.NodeList arguments,
824 // We are invoking a method. 1088 Selector selector,
825 assert(target is FunctionElement); 1089 _) {
826 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1090 return translateCallInvoke(irBuilder.buildThis(), arguments, selector);
827 arguments = normalizeStaticArguments(selector, target, arguments); 1091 }
828 return irBuilder.buildSuperInvocation(target, selector, arguments); 1092
829 } else { 1093 @override
830 // We are invoking a getter, operator, indexer, etc. 1094 ir.Primitive visitTypeVariableTypeLiteralInvoke(
831 List<ir.Primitive> arguments = node.argumentsNode == null 1095 ast.Send node,
832 ? <ir.Primitive>[] 1096 TypeVariableElement element,
833 : node.arguments.mapToList(visit); 1097 ast.NodeList arguments,
834 return irBuilder.buildSuperInvocation(target, selector, arguments); 1098 Selector selector,
835 } 1099 _) {
836 } 1100 return translateCallInvoke(
837 1101 translateTypeVariableTypeLiteral(element),
838 visitTypePrefixSend(ast.Send node) { 1102 arguments,
839 compiler.internalError(node, "visitTypePrefixSend should not be called."); 1103 selector);
840 } 1104 }
841 1105
842 ir.Primitive visitTypeLiteralSend(ast.Send node) { 1106 @override
843 assert(irBuilder.isOpen); 1107 ir.Primitive visitTypedefTypeLiteralInvoke(
844 // If the user is trying to invoke the type literal or variable, 1108 ast.Send node,
845 // it must be treated as a function call. 1109 TypeConstantExpression constant,
846 if (node.argumentsNode != null) { 1110 ast.NodeList arguments,
847 // TODO(sigurdm): Handle this to match proposed semantics of issue #19725. 1111 Selector selector, _) {
848 return giveup(node, 'Type literal invoked as function'); 1112 return translateConstantInvoke(constant, arguments, selector);
849 } 1113 }
850 1114
851 DartType type = elements.getTypeLiteralType(node); 1115 // TODO(johnniwinther): This should be a method on [IrBuilder].
852 if (type is TypeVariableType) {
853 return buildReifyTypeVariable(irBuilder.buildThis(), type);
854 } else {
855 return translateConstant(node);
856 }
857 }
858
859 ir.Primitive buildReifyTypeVariable(ir.Primitive target, 1116 ir.Primitive buildReifyTypeVariable(ir.Primitive target,
860 TypeVariableType variable); 1117 TypeVariableType variable);
861 1118
862 ir.Primitive visitSendSet(ast.SendSet node) { 1119 @override
863 assert(irBuilder.isOpen); 1120 ir.Primitive visitIndexSet(
864 Element element = elements[node]; 1121 ast.SendSet node,
865 ast.Operator op = node.assignmentOperator; 1122 ast.Node receiver,
866 // For complex operators, this is the result of getting (before assigning) 1123 ast.Node index,
867 ir.Primitive originalValue; 1124 ast.Node rhs,
868 // For []+= style operators, this saves the index. 1125 _) {
869 ir.Primitive index; 1126 return irBuilder.buildDynamicIndexSet(
870 ir.Primitive receiver; 1127 visit(receiver), visit(index), visit(rhs));
871 // This is what gets assigned. 1128 }
872 ir.Primitive valueToStore; 1129
873 Selector selector = elements.getSelector(node); 1130 @override
1131 ir.Primitive visitSuperIndexSet(
1132 ast.SendSet node,
1133 FunctionElement function,
1134 ast.Node index,
1135 ast.Node rhs,
1136 _) {
1137 return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs));
1138 }
1139
1140 @override
1141 ir.Primitive visitCompoundIndexSet(
1142 ast.SendSet node,
1143 ast.Node receiver,
1144 ast.Node index,
1145 op.AssignmentOperator operator,
1146 ast.Node rhs,
1147 _) {
1148 ir.Primitive target = visit(receiver);
1149 ir.Primitive indexValue = visit(index);
1150 return translateCompound(
1151 getValue: () {
1152 Selector selector = new Selector.index();
1153 List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
1154 arguments = normalizeDynamicArguments(selector, arguments);
1155 return irBuilder.buildDynamicInvocation(target, selector, arguments);
1156 },
1157 operator: operator,
1158 rhs: rhs,
1159 setValue: (ir.Primitive result) {
1160 irBuilder.buildDynamicIndexSet(target, indexValue, result);
1161 });
1162 }
1163
1164 @override
1165 ir.Primitive visitSuperCompoundIndexSet(
1166 ast.SendSet node,
1167 FunctionElement getter,
1168 FunctionElement setter,
1169 ast.Node index,
1170 op.AssignmentOperator operator,
1171 ast.Node rhs,
1172 _) {
1173 ir.Primitive indexValue = visit(index);
1174 return translateCompound(
1175 getValue: () {
1176 Selector selector = new Selector.index();
1177 List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
1178 arguments = normalizeDynamicArguments(selector, arguments);
1179 return irBuilder.buildSuperInvocation(getter, selector, arguments);
1180 },
1181 operator: operator,
1182 rhs: rhs,
1183 setValue: (ir.Primitive result) {
1184 irBuilder.buildSuperIndexSet(setter, indexValue, result);
1185 });
1186 }
1187
1188 ir.Primitive translatePrefixPostfix(
1189 {ir.Primitive getValue(),
1190 op.IncDecOperator operator,
1191 void setValue(ir.Primitive value),
1192 bool isPrefix}) {
1193 ir.Primitive value = getValue();
874 Selector operatorSelector = 1194 Selector operatorSelector =
875 elements.getOperatorSelectorInComplexSendSet(node); 1195 new Selector.binaryOperator(operator.selectorName);
876 Selector getterSelector = 1196 List<ir.Primitive> arguments =
877 elements.getGetterSelectorInComplexSendSet(node); 1197 <ir.Primitive>[irBuilder.buildIntegerLiteral(1)];
878 assert( 1198 arguments = normalizeDynamicArguments(operatorSelector, arguments);
879 // Indexing send-sets have an argument for the index. 1199 ir.Primitive result =
880 (selector.isIndexSet ? 1 : 0) + 1200 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
881 // Non-increment send-sets have one more argument. 1201 setValue(result);
882 (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1) 1202 return isPrefix ? result : value;
883 == node.argumentCount()); 1203 }
884 1204
885 ast.Node getAssignArgument() { 1205 ir.Primitive translateCompound(
886 assert(invariant(node, !node.arguments.isEmpty, 1206 {ir.Primitive getValue(),
887 message: "argument expected")); 1207 op.AssignmentOperator operator,
888 return selector.isIndexSet 1208 ast.Node rhs,
889 ? node.arguments.tail.head 1209 void setValue(ir.Primitive value)}) {
890 : node.arguments.head; 1210 ir.Primitive value = getValue();
891 } 1211 Selector operatorSelector =
892 1212 new Selector.binaryOperator(operator.selectorName);
893 // Get the value into valueToStore 1213 List<ir.Primitive> arguments = <ir.Primitive>[visit(rhs)];
894 if (op.source == "=") { 1214 arguments = normalizeDynamicArguments(operatorSelector, arguments);
895 if (selector.isIndexSet) { 1215 ir.Primitive result =
896 receiver = visitReceiver(node.receiver); 1216 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
897 index = visit(node.arguments.head); 1217 setValue(result);
898 } else if (element == null || Elements.isInstanceField(element)) { 1218 return result;
899 receiver = visitReceiver(node.receiver); 1219 }
900 } 1220
901 valueToStore = visit(getAssignArgument()); 1221 @override
902 } else { 1222 ir.Primitive handleDynamicCompound(
903 // Get the original value into getter 1223 ast.Send node,
904 assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source)); 1224 ast.Node receiver,
905 1225 op.AssignmentOperator operator,
906 _GetterElements getterResult = translateGetter(node, getterSelector); 1226 ast.Node rhs,
907 index = getterResult.index; 1227 Selector getterSelector,
908 receiver = getterResult.receiver; 1228 Selector setterSelector,
909 originalValue = getterResult.result; 1229 _) {
910 1230 ir.Primitive target = translateReceiver(receiver);
911 // Do the modification of the value in getter. 1231 return translateCompound(
912 ir.Primitive arg; 1232 getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
913 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1233 operator: operator,
914 arg = irBuilder.buildIntegerLiteral(1); 1234 rhs: rhs,
915 } else { 1235 setValue: (ir.Primitive result) {
916 arg = visit(getAssignArgument()); 1236 irBuilder.buildDynamicSet(target, setterSelector, result);
917 } 1237 });
918 valueToStore = new ir.Parameter(null); 1238 }
919 ir.Continuation k = new ir.Continuation([valueToStore]); 1239
920 ir.Expression invoke = 1240 @override
921 new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]); 1241 ir.Primitive handleDynamicPostfixPrefix(
922 irBuilder.add(new ir.LetCont(k, invoke)); 1242 ast.Send node,
923 } 1243 ast.Node receiver,
924 1244 op.IncDecOperator operator,
925 if (Elements.isLocal(element)) { 1245 Selector getterSelector,
926 irBuilder.buildLocalSet(element, valueToStore); 1246 Selector setterSelector,
927 } else if ((!node.isSuperCall && Elements.isErroneous(element)) || 1247 arg,
928 Elements.isStaticOrTopLevel(element)) { 1248 {bool isPrefix}) {
929 irBuilder.buildStaticSet( 1249 ir.Primitive target = translateReceiver(receiver);
930 element, elements.getSelector(node), valueToStore); 1250 return translatePrefixPostfix(
931 } else { 1251 getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
932 // Setter or index-setter invocation 1252 operator: operator,
933 Selector selector = elements.getSelector(node); 1253 setValue: (ir.Primitive result) {
934 assert(selector.kind == SelectorKind.SETTER || 1254 irBuilder.buildDynamicSet(target, setterSelector, result);
935 selector.kind == SelectorKind.INDEX); 1255 },
936 if (selector.isIndexSet) { 1256 isPrefix: isPrefix);
937 if (isSuperCall(node)) { 1257 }
938 irBuilder.buildSuperIndexSet(element, index, valueToStore); 1258
939 } else { 1259 @override
940 irBuilder.buildDynamicIndexSet(receiver, index, valueToStore); 1260 ir.Primitive handleDynamicSet(
941 } 1261 ast.SendSet node,
942 } else { 1262 ast.Node receiver,
943 if (isSuperCall(node)) { 1263 Selector selector,
944 irBuilder.buildSuperSet(element, selector, valueToStore); 1264 ast.Node rhs,
945 } else { 1265 _) {
946 irBuilder.buildDynamicSet(receiver, selector, valueToStore); 1266 return irBuilder.buildDynamicSet(
947 } 1267 translateReceiver(receiver),
948 } 1268 selector,
949 } 1269 visit(rhs));
950 1270 }
951 if (node.isPostfix) { 1271
952 assert(originalValue != null); 1272 @override
953 return originalValue; 1273 ir.Primitive handleLocalCompound(
954 } else { 1274 ast.Send node,
955 return valueToStore; 1275 LocalElement element,
956 } 1276 op.AssignmentOperator operator,
1277 ast.Node rhs,
1278 _) {
1279 return translateCompound(
1280 getValue: () => irBuilder.buildLocalGet(element),
1281 operator: operator,
1282 rhs: rhs,
1283 setValue: (ir.Primitive result) {
1284 irBuilder.buildLocalSet(element, result);
1285 });
1286 }
1287
1288 @override
1289 ir.Primitive handleLocalPostfixPrefix(
1290 ast.Send node,
1291 LocalElement element,
1292 op.IncDecOperator operator,
1293 arg,
1294 {bool isPrefix}) {
1295 return translatePrefixPostfix(
1296 getValue: () => irBuilder.buildLocalGet(element),
1297 operator: operator,
1298 setValue: (ir.Primitive result) {
1299 irBuilder.buildLocalSet(element, result);
1300 },
1301 isPrefix: isPrefix);
1302 }
1303
1304 @override
1305 ir.Primitive handleLocalSet(
1306 ast.SendSet node,
1307 LocalElement element,
1308 ast.Node rhs,
1309 _) {
1310 return irBuilder.buildLocalSet(element, visit(rhs));
1311 }
1312
1313 @override
1314 ir.Primitive handleStaticFieldCompound(
1315 ast.Send node,
1316 FieldElement field,
1317 op.AssignmentOperator operator,
1318 ast.Node rhs,
1319 _) {
1320 return translateCompound(
1321 getValue: () => irBuilder.buildStaticGet(field),
1322 operator: operator,
1323 rhs: rhs,
1324 setValue: (ir.Primitive result) {
1325 irBuilder.buildStaticSet(field, result);
1326 });
1327 }
1328
1329 @override
1330 ir.Primitive handleStaticFieldPostfixPrefix(
1331 ast.Send node,
1332 FieldElement field,
1333 op.IncDecOperator operator,
1334 arg,
1335 {bool isPrefix}) {
1336 return translatePrefixPostfix(
1337 getValue: () => irBuilder.buildStaticGet(field),
1338 operator: operator,
1339 setValue: (ir.Primitive result) {
1340 irBuilder.buildStaticSet(field, result);
1341 },
1342 isPrefix: isPrefix);
1343 }
1344
1345 @override
1346 ir.Primitive handleStaticFieldSet(
1347 ast.SendSet node,
1348 FieldElement field,
1349 ast.Node rhs,
1350 _) {
1351 return irBuilder.buildStaticSet(field, visit(rhs));
1352 }
1353
1354 @override
1355 ir.Primitive visitSuperFieldSet(
1356 ast.SendSet node,
1357 FieldElement field,
1358 ast.Node rhs,
1359 _) {
1360 return irBuilder.buildSuperSet(field, visit(rhs));
1361 }
1362
1363 @override
1364 ir.Primitive visitSuperSetterSet(
1365 ast.SendSet node,
1366 FunctionElement setter,
1367 ast.Node rhs,
1368 _) {
1369 return irBuilder.buildSuperSet(setter, visit(rhs));
1370 }
1371
1372 @override
1373 ir.Primitive handleStaticGetterSetterCompound(
1374 ast.Send node,
1375 FunctionElement getter,
1376 FunctionElement setter,
1377 op.AssignmentOperator operator,
1378 ast.Node rhs,
1379 _) {
1380 return translateCompound(
1381 getValue: () => irBuilder.buildStaticGet(getter),
1382 operator: operator,
1383 rhs: rhs,
1384 setValue: (ir.Primitive result) {
1385 irBuilder.buildStaticSet(setter, result);
1386 });
1387 }
1388
1389 @override
1390 ir.Primitive handleSuperFieldFieldPostfixPrefix(
1391 ast.Send node,
1392 FieldElement readField,
1393 FieldElement writtenField,
1394 op.IncDecOperator operator,
1395 arg,
1396 {bool isPrefix}) {
1397 return translatePrefixPostfix(
1398 getValue: () => irBuilder.buildSuperGet(readField),
1399 operator: operator,
1400 setValue: (ir.Primitive result) {
1401 irBuilder.buildSuperSet(writtenField, result);
1402 },
1403 isPrefix: isPrefix);
1404 }
1405
1406 @override
1407 ir.Primitive handleSuperFieldSetterPostfixPrefix(
1408 ast.Send node,
1409 FieldElement field,
1410 FunctionElement setter,
1411 op.IncDecOperator operator,
1412 arg,
1413 {bool isPrefix}) {
1414 return translatePrefixPostfix(
1415 getValue: () => irBuilder.buildSuperGet(field),
1416 operator: operator,
1417 setValue: (ir.Primitive result) {
1418 irBuilder.buildSuperSet(setter, result);
1419 },
1420 isPrefix: isPrefix);
1421 }
1422
1423 @override
1424 ir.Primitive handleSuperGetterFieldPostfixPrefix(
1425 ast.Send node,
1426 FunctionElement getter,
1427 FieldElement field,
1428 op.IncDecOperator operator,
1429 arg,
1430 {bool isPrefix}) {
1431 return translatePrefixPostfix(
1432 getValue: () => irBuilder.buildSuperGet(getter),
1433 operator: operator,
1434 setValue: (ir.Primitive result) {
1435 irBuilder.buildSuperSet(field, result);
1436 },
1437 isPrefix: isPrefix);
1438 }
1439
1440 @override
1441 ir.Primitive handleSuperGetterSetterPostfixPrefix(
1442 ast.Send node,
1443 FunctionElement getter,
1444 FunctionElement setter,
1445 op.IncDecOperator operator,
1446 arg,
1447 {bool isPrefix}) {
1448 return translatePrefixPostfix(
1449 getValue: () => irBuilder.buildSuperGet(getter),
1450 operator: operator,
1451 setValue: (ir.Primitive result) {
1452 irBuilder.buildSuperSet(setter, result);
1453 },
1454 isPrefix: isPrefix);
1455 }
1456
1457 @override
1458 ir.Primitive handleSuperMethodSetterPostfixPrefix(
1459 ast.Send node,
1460 FunctionElement method,
1461 FunctionElement setter,
1462 op.IncDecOperator operator,
1463 arg,
1464 {bool isPrefix}) {
1465 return translatePrefixPostfix(
1466 getValue: () => irBuilder.buildSuperGet(method),
1467 operator: operator,
1468 setValue: (ir.Primitive result) {
1469 irBuilder.buildSuperSet(setter, result);
1470 },
1471 isPrefix: isPrefix);
1472 }
1473
1474 @override
1475 ir.Primitive handleStaticGetterSetterPostfixPrefix(
1476 ast.Send node,
1477 FunctionElement getter,
1478 FunctionElement setter,
1479 op.IncDecOperator operator,
1480 arg,
1481 {bool isPrefix}) {
1482 return translatePrefixPostfix(
1483 getValue: () => irBuilder.buildStaticGet(getter),
1484 operator: operator,
1485 setValue: (ir.Primitive result) {
1486 irBuilder.buildStaticSet(setter, result);
1487 },
1488 isPrefix: isPrefix);
1489 }
1490
1491 @override
1492 ir.Primitive handleStaticMethodSetterCompound(
1493 ast.Send node,
1494 FunctionElement method,
1495 FunctionElement setter,
1496 op.AssignmentOperator operator,
1497 ast.Node rhs,
1498 _) {
1499 return translateCompound(
1500 getValue: () => irBuilder.buildStaticGet(method),
1501 operator: operator,
1502 rhs: rhs,
1503 setValue: (ir.Primitive result) {
1504 irBuilder.buildStaticSet(setter, result);
1505 });
1506 }
1507
1508 @override
1509 ir.Primitive handleStaticMethodSetterPostfixPrefix(
1510 ast.Send node,
1511 FunctionElement getter,
1512 FunctionElement setter,
1513 op.IncDecOperator operator,
1514 arg,
1515 {bool isPrefix}) {
1516 return translatePrefixPostfix(
1517 getValue: () => irBuilder.buildStaticGet(getter),
1518 operator: operator,
1519 setValue: (ir.Primitive result) {
1520 irBuilder.buildStaticSet(setter, result);
1521 },
1522 isPrefix: isPrefix);
1523 }
1524
1525 @override
1526 ir.Primitive handleDynamicIndexPostfixPrefix(
1527 ast.Send node,
1528 ast.Node receiver,
1529 ast.Node index,
1530 op.IncDecOperator operator,
1531 arg,
1532 {bool isPrefix}) {
1533 ir.Primitive target = visit(receiver);
1534 ir.Primitive indexValue = visit(index);
1535 return translatePrefixPostfix(
1536 getValue: () {
1537 Selector selector = new Selector.index();
1538 List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
1539 arguments = normalizeDynamicArguments(selector, arguments);
1540 return irBuilder.buildDynamicInvocation(target, selector, arguments);
1541 },
1542 operator: operator,
1543 setValue: (ir.Primitive result) {
1544 Selector selector = new Selector.indexSet();
1545 List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result];
1546 arguments = normalizeDynamicArguments(selector, arguments);
1547 irBuilder.buildDynamicInvocation(target, selector, arguments);
1548 },
1549 isPrefix: isPrefix);
1550 }
1551
1552 @override
1553 ir.Primitive handleSuperIndexPostfixPrefix(
1554 ast.Send node,
1555 FunctionElement indexFunction,
1556 FunctionElement indexSetFunction,
1557 ast.Node index,
1558 op.IncDecOperator operator,
1559 arg,
1560 {bool isPrefix}) {
1561 ir.Primitive indexValue = visit(index);
1562 return translatePrefixPostfix(
1563 getValue: () {
1564 Selector selector = new Selector.index();
1565 List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
1566 arguments = normalizeDynamicArguments(selector, arguments);
1567 return irBuilder.buildSuperInvocation(
1568 indexFunction, selector, arguments);
1569 },
1570 operator: operator,
1571 setValue: (ir.Primitive result) {
1572 Selector selector = new Selector.indexSet();
1573 List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result];
1574 arguments = normalizeDynamicArguments(selector, arguments);
1575 irBuilder.buildSuperInvocation(
1576 indexSetFunction, selector, arguments);
1577 },
1578 isPrefix: isPrefix);
1579 }
1580
1581 @override
1582 ir.Primitive handleStaticSetterSet(
1583 ast.SendSet node,
1584 FunctionElement setter,
1585 ast.Node rhs,
1586 _) {
1587 return irBuilder.buildStaticSet(setter, visit(rhs));
1588 }
1589
1590 @override
1591 ir.Primitive visitSuperFieldCompound(
1592 ast.Send node,
1593 FieldElement field,
1594 op.AssignmentOperator operator,
1595 ast.Node rhs,
1596 _) {
1597 return translateCompound(
1598 getValue: () => irBuilder.buildSuperGet(field),
1599 operator: operator,
1600 rhs: rhs,
1601 setValue: (ir.Primitive result) {
1602 irBuilder.buildSuperSet(field, result);
1603 });
1604 }
1605
1606 @override
1607 ir.Primitive visitSuperFieldFieldPostfix(
1608 ast.Send node,
1609 FieldElement readField,
1610 FieldElement writtenField,
1611 op.IncDecOperator operator,
1612 _) {
1613 return translatePrefixPostfix(
1614 getValue: () => irBuilder.buildSuperGet(readField),
1615 operator: operator,
1616 setValue: (ir.Primitive result) {
1617 irBuilder.buildSuperSet(writtenField, result);
1618 },
1619 isPrefix: false);
1620 }
1621
1622 @override
1623 ir.Primitive visitSuperFieldFieldPrefix(
1624 ast.Send node,
1625 FieldElement readField,
1626 FieldElement writtenField,
1627 op.IncDecOperator operator,
1628 _) {
1629 return translatePrefixPostfix(
1630 getValue: () => irBuilder.buildSuperGet(readField),
1631 operator: operator,
1632 setValue: (ir.Primitive result) {
1633 irBuilder.buildSuperSet(writtenField, result);
1634 },
1635 isPrefix: true);
1636 }
1637
1638 @override
1639 ir.Primitive visitSuperFieldSetterCompound(
1640 ast.Send node,
1641 FieldElement field,
1642 FunctionElement setter,
1643 op.AssignmentOperator operator,
1644 ast.Node rhs,
1645 _) {
1646 return translateCompound(
1647 getValue: () => irBuilder.buildSuperGet(field),
1648 operator: operator,
1649 rhs: rhs,
1650 setValue: (ir.Primitive result) {
1651 irBuilder.buildSuperSet(setter, result);
1652 });
1653 }
1654
1655 @override
1656 ir.Primitive visitSuperGetterFieldCompound(
1657 ast.Send node,
1658 FunctionElement getter,
1659 FieldElement field,
1660 op.AssignmentOperator operator,
1661 ast.Node rhs,
1662 _) {
1663 return translateCompound(
1664 getValue: () => irBuilder.buildSuperGet(getter),
1665 operator: operator,
1666 rhs: rhs,
1667 setValue: (ir.Primitive result) {
1668 irBuilder.buildSuperSet(field, result);
1669 });
1670 }
1671
1672 @override
1673 ir.Primitive visitSuperGetterSetterCompound(
1674 ast.Send node,
1675 FunctionElement getter,
1676 FunctionElement setter,
1677 op.AssignmentOperator operator,
1678 ast.Node rhs,
1679 _) {
1680 return translateCompound(
1681 getValue: () => irBuilder.buildSuperGet(getter),
1682 operator: operator,
1683 rhs: rhs,
1684 setValue: (ir.Primitive result) {
1685 irBuilder.buildSuperSet(setter, result);
1686 });
1687 }
1688
1689 @override
1690 ir.Primitive visitSuperMethodSetterCompound(
1691 ast.Send node,
1692 FunctionElement method,
1693 FunctionElement setter,
1694 op.AssignmentOperator operator,
1695 ast.Node rhs,
1696 _) {
1697 return translateCompound(
1698 getValue: () => irBuilder.buildSuperGet(method),
1699 operator: operator,
1700 rhs: rhs,
1701 setValue: (ir.Primitive result) {
1702 irBuilder.buildSuperSet(setter, result);
1703 });
957 } 1704 }
958 1705
959 ir.Primitive visitNewExpression(ast.NewExpression node) { 1706 ir.Primitive visitNewExpression(ast.NewExpression node) {
960 if (node.isConst) { 1707 if (node.isConst) {
961 return translateConstant(node); 1708 return translateConstant(node);
962 } 1709 }
963 FunctionElement element = elements[node.send]; 1710 FunctionElement element = elements[node.send];
964 Selector selector = elements.getSelector(node.send); 1711 Selector selector = elements.getSelector(node.send);
965 DartType type = elements.getType(node); 1712 DartType type = elements.getType(node);
966 ast.Node selectorNode = node.send.selector; 1713 ast.Node selectorNode = node.send.selector;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 try { 1747 try {
1001 return action(); 1748 return action();
1002 } catch(e, tr) { 1749 } catch(e, tr) {
1003 if (e == ABORT_IRNODE_BUILDER) { 1750 if (e == ABORT_IRNODE_BUILDER) {
1004 return null; 1751 return null;
1005 } 1752 }
1006 rethrow; 1753 rethrow;
1007 } 1754 }
1008 } 1755 }
1009 1756
1010 void internalError(String reason, {ast.Node node}) { 1757 void internalError(ast.Node node, String message) {
1011 giveup(node); 1758 giveup(node);
1012 } 1759 }
1760
1761 @override
1762 visitNode(ast.Node node) {
1763 internalError(node, "Unhandled node");
1764 }
1013 } 1765 }
1014 1766
1015 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 1767 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
1016 1768
1017 dynamic giveup(ast.Node node, [String reason]) { 1769 dynamic giveup(ast.Node node, [String reason]) {
1018 throw ABORT_IRNODE_BUILDER; 1770 throw ABORT_IRNODE_BUILDER;
1019 } 1771 }
1020 1772
1021 /// Classifies local variables and local functions as captured, if they 1773 /// Classifies local variables and local functions as captured, if they
1022 /// are accessed from within a nested function. 1774 /// are accessed from within a nested function.
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 SourceInformation buildCall(ast.Node node) { 2603 SourceInformation buildCall(ast.Node node) {
1852 return new PositionSourceInformation( 2604 return new PositionSourceInformation(
1853 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2605 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
1854 } 2606 }
1855 2607
1856 @override 2608 @override
1857 SourceInformationBuilder forContext(AstElement element) { 2609 SourceInformationBuilder forContext(AstElement element) {
1858 return new PositionSourceInformationBuilder(element); 2610 return new PositionSourceInformationBuilder(element);
1859 } 2611 }
1860 } 2612 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/resolution/semantic_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698