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

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

Issue 908863003: dart2js cps: Handle optional parameters in builder. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Removed obsolete TODO Created 5 years, 10 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 part of dart2js.ir_builder; 5 part of dart2js.ir_builder;
6 6
7 /** 7 /**
8 * This task iterates through all resolved elements and builds [ir.Node]s. The 8 * This task iterates through all resolved elements and builds [ir.Node]s. The
9 * nodes are stored in the [nodes] map and accessible through [hasIr] and 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and
10 * [getIr]. 10 * [getIr].
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 /** 137 /**
138 * Builds the [ir.ExecutableDefinition] for an executable element. In case the 138 * Builds the [ir.ExecutableDefinition] for an executable element. In case the
139 * function uses features that cannot be expressed in the IR, this element 139 * function uses features that cannot be expressed in the IR, this element
140 * returns `null`. 140 * returns `null`.
141 */ 141 */
142 ir.ExecutableDefinition buildExecutable(ExecutableElement element); 142 ir.ExecutableDefinition buildExecutable(ExecutableElement element);
143 143
144 ClosureScope getClosureScopeForNode(ast.Node node); 144 ClosureScope getClosureScopeForNode(ast.Node node);
145 ClosureEnvironment getClosureEnvironment(); 145 ClosureEnvironment getClosureEnvironment();
146 146
147 /// Normalizes the argument list to a static invocation (i.e. where the target
148 /// element is known).
149 ///
150 /// For the JS backend, inserts default arguments and normalizes order of
151 /// named arguments.
152 ///
153 /// For the Dart backend, returns [arguments].
154 List<ir.Primitive> normalizeStaticArguments(
155 Selector selector,
156 FunctionElement target,
157 List<ir.Primitive> arguments);
147 158
159 /// Normalizes the argument list of a dynamic invocation (i.e. where the
160 /// target element is unknown).
161 ///
162 /// For the JS backend, normalizes order of named arguments.
163 ///
164 /// For the Dart backend, returns [arguments].
165 List<ir.Primitive> normalizeDynamicArguments(
166 Selector selector,
167 List<ir.Primitive> arguments);
148 168
149 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, 169 ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
150 ast.FunctionExpression node) { 170 ast.FunctionExpression node) {
151 FunctionSignature signature = element.functionSignature; 171 FunctionSignature signature = element.functionSignature;
152 List<ParameterElement> parameters = []; 172 List<ParameterElement> parameters = [];
153 signature.orderedForEachParameter(parameters.add); 173 signature.orderedForEachParameter(parameters.add);
154 174
155 irBuilder.buildFunctionHeader(parameters, 175 irBuilder.buildFunctionHeader(parameters,
156 closureScope: getClosureScopeForNode(node), 176 closureScope: getClosureScopeForNode(node),
157 env: getClosureEnvironment()); 177 env: getClosureEnvironment());
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 562 }
543 563
544 ir.Primitive visitNamedArgument(ast.NamedArgument node) { 564 ir.Primitive visitNamedArgument(ast.NamedArgument node) {
545 assert(irBuilder.isOpen); 565 assert(irBuilder.isOpen);
546 return visit(node.expression); 566 return visit(node.expression);
547 } 567 }
548 568
549 ir.Primitive visitClosureSend(ast.Send node) { 569 ir.Primitive visitClosureSend(ast.Send node) {
550 assert(irBuilder.isOpen); 570 assert(irBuilder.isOpen);
551 Element element = elements[node]; 571 Element element = elements[node];
552 Selector closureSelector = elements.getSelector(node); 572 Selector selector = elements.getSelector(node);
553 if (element == null) { 573 ir.Primitive receiver = (element == null)
554 ir.Primitive closureTarget = visit(node.selector); 574 ? visit(node.selector)
555 List<ir.Primitive> args = 575 : irBuilder.buildLocalGet(element);
556 node.arguments.mapToList(visit, growable:false); 576 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
557 return irBuilder.buildFunctionExpressionInvocation( 577 arguments = normalizeDynamicArguments(selector, arguments);
558 closureTarget, elements.getSelector(node), args); 578 return irBuilder.buildFunctionExpressionInvocation(
559 } else { 579 receiver, selector, arguments);
560 List<ir.Primitive> args =
561 node.arguments.mapToList(visit, growable:false);
562 return irBuilder.buildLocalInvocation(
563 element, elements.getSelector(node), args);
564 }
565 } 580 }
566 581
567 /// If [node] is null, returns this. 582 /// If [node] is null, returns this.
568 /// If [node] is super, returns null (for special handling) 583 /// If [node] is super, returns null (for special handling)
569 /// Otherwise visits [node] and returns the result. 584 /// Otherwise visits [node] and returns the result.
570 ir.Primitive visitReceiver(ast.Expression node) { 585 ir.Primitive visitReceiver(ast.Expression node) {
571 if (node == null) return irBuilder.buildThis(); 586 if (node == null) return irBuilder.buildThis();
572 if (node.isSuper()) return null; 587 if (node.isSuper()) return null;
573 return visit(node); 588 return visit(node);
574 } 589 }
575 590
576 /// Returns `true` if [node] is a super call. 591 /// Returns `true` if [node] is a super call.
577 // TODO(johnniwinther): Remove the need for this. 592 // TODO(johnniwinther): Remove the need for this.
578 bool isSuperCall(ast.Send node) { 593 bool isSuperCall(ast.Send node) {
579 return node != null && node.receiver != null && node.receiver.isSuper(); 594 return node != null && node.receiver != null && node.receiver.isSuper();
580 } 595 }
581 596
582 ir.Primitive visitDynamicSend(ast.Send node) { 597 ir.Primitive visitDynamicSend(ast.Send node) {
583 assert(irBuilder.isOpen); 598 assert(irBuilder.isOpen);
584 Selector selector = elements.getSelector(node); 599 Selector selector = elements.getSelector(node);
585 ir.Primitive receiver = visitReceiver(node.receiver); 600 ir.Primitive receiver = visitReceiver(node.receiver);
586 List<ir.Primitive> arguments = new List<ir.Primitive>(); 601 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
587 for (ast.Node n in node.arguments) { 602 arguments = normalizeDynamicArguments(selector, arguments);
588 arguments.add(visit(n));
589 }
590 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); 603 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
591 } 604 }
592 605
593 _GetterElements translateGetter(ast.Send node, Selector selector) { 606 _GetterElements translateGetter(ast.Send node, Selector selector) {
594 Element element = elements[node]; 607 Element element = elements[node];
595 ir.Primitive result; 608 ir.Primitive result;
596 ir.Primitive receiver; 609 ir.Primitive receiver;
597 ir.Primitive index; 610 ir.Primitive index;
598 611
599 if (element != null && element.isConst) { 612 if (element != null && element.isConst) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 assert(irBuilder.isOpen); 718 assert(irBuilder.isOpen);
706 Element element = elements[node]; 719 Element element = elements[node];
707 assert(!element.isConstructor); 720 assert(!element.isConstructor);
708 // TODO(lry): support foreign functions. 721 // TODO(lry): support foreign functions.
709 if (element.isForeign(compiler.backend)) { 722 if (element.isForeign(compiler.backend)) {
710 return giveup(node, 'StaticSend: foreign'); 723 return giveup(node, 'StaticSend: foreign');
711 } 724 }
712 725
713 Selector selector = elements.getSelector(node); 726 Selector selector = elements.getSelector(node);
714 727
715 // TODO(lry): support default arguments, need support for locals.
716 List<ir.Primitive> arguments = 728 List<ir.Primitive> arguments =
717 node.arguments.mapToList(visit, growable:false); 729 node.arguments.mapToList(visit, growable:false);
730 arguments = normalizeStaticArguments(selector, element, arguments);
718 return irBuilder.buildStaticInvocation(element, selector, arguments); 731 return irBuilder.buildStaticInvocation(element, selector, arguments);
719 } 732 }
720 733
721 ir.Primitive visitSuperSend(ast.Send node) { 734 ir.Primitive visitSuperSend(ast.Send node) {
722 assert(irBuilder.isOpen); 735 assert(irBuilder.isOpen);
723 if (node.isPropertyAccess) { 736 if (node.isPropertyAccess) {
724 return visitGetterSend(node); 737 return visitGetterSend(node);
725 } else { 738 } else {
726 Selector selector = elements.getSelector(node); 739 Selector selector = elements.getSelector(node);
727 Element target = elements[node]; 740 Element target = elements[node];
728 List<ir.Primitive> arguments = new List<ir.Primitive>(); 741 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
729 for (ast.Node n in node.arguments) { 742 arguments = normalizeStaticArguments(selector, target, arguments);
730 arguments.add(visit(n));
731 }
732 return irBuilder.buildSuperInvocation(target, selector, arguments); 743 return irBuilder.buildSuperInvocation(target, selector, arguments);
733 } 744 }
734 } 745 }
735 746
736 visitTypePrefixSend(ast.Send node) { 747 visitTypePrefixSend(ast.Send node) {
737 compiler.internalError(node, "visitTypePrefixSend should not be called."); 748 compiler.internalError(node, "visitTypePrefixSend should not be called.");
738 } 749 }
739 750
740 ir.Primitive visitTypeLiteralSend(ast.Send node) { 751 ir.Primitive visitTypeLiteralSend(ast.Send node) {
741 assert(irBuilder.isOpen); 752 assert(irBuilder.isOpen);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 } 865 }
855 866
856 ir.Primitive visitNewExpression(ast.NewExpression node) { 867 ir.Primitive visitNewExpression(ast.NewExpression node) {
857 if (node.isConst) { 868 if (node.isConst) {
858 return translateConstant(node); 869 return translateConstant(node);
859 } 870 }
860 FunctionElement element = elements[node.send]; 871 FunctionElement element = elements[node.send];
861 Selector selector = elements.getSelector(node.send); 872 Selector selector = elements.getSelector(node.send);
862 DartType type = elements.getType(node); 873 DartType type = elements.getType(node);
863 ast.Node selectorNode = node.send.selector; 874 ast.Node selectorNode = node.send.selector;
864 List<ir.Definition> arguments = 875 List<ir.Primitive> arguments =
865 node.send.arguments.mapToList(visit, growable:false); 876 node.send.arguments.mapToList(visit, growable:false);
877 arguments = normalizeStaticArguments(selector, element, arguments);
866 return irBuilder.buildConstructorInvocation( 878 return irBuilder.buildConstructorInvocation(
867 element, selector, type, arguments); 879 element, selector, type, arguments);
868 } 880 }
869 881
870 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { 882 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
871 assert(irBuilder.isOpen); 883 assert(irBuilder.isOpen);
872 ir.Primitive first = visit(node.first); 884 ir.Primitive first = visit(node.first);
873 ir.Primitive second = visit(node.second); 885 ir.Primitive second = visit(node.second);
874 return irBuilder.buildStringConcatenation([first, second]); 886 return irBuilder.buildStringConcatenation([first, second]);
875 } 887 }
876 888
877 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { 889 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
878 assert(irBuilder.isOpen); 890 assert(irBuilder.isOpen);
879 List<ir.Primitive> arguments = []; 891 List<ir.Primitive> arguments = [];
880 arguments.add(visitLiteralString(node.string)); 892 arguments.add(visitLiteralString(node.string));
881 var it = node.parts.iterator; 893 var it = node.parts.iterator;
882 while (it.moveNext()) { 894 while (it.moveNext()) {
883 ast.StringInterpolationPart part = it.current; 895 ast.StringInterpolationPart part = it.current;
884 arguments.add(visit(part.expression)); 896 arguments.add(visit(part.expression));
885 arguments.add(visitLiteralString(part.string)); 897 arguments.add(visitLiteralString(part.string));
886 } 898 }
887 return irBuilder.buildStringConcatenation(arguments); 899 return irBuilder.buildStringConcatenation(arguments);
888 } 900 }
889 901
890 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) { 902 ir.Primitive translateConstant(ast.Node node) {
891 assert(irBuilder.isOpen); 903 assert(irBuilder.isOpen);
892 if (constant == null) { 904 return irBuilder.buildConstantLiteral(getConstantForNode(node));
893 constant = getConstantForNode(node);
894 }
895 return irBuilder.buildConstantLiteral(constant);
896 } 905 }
897 906
898 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { 907 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) {
899 try { 908 try {
900 return action(); 909 return action();
901 } catch(e, tr) { 910 } catch(e, tr) {
902 if (e == ABORT_IRNODE_BUILDER) { 911 if (e == ABORT_IRNODE_BUILDER) {
903 return null; 912 return null;
904 } 913 }
905 rethrow; 914 rethrow;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 SynthesizedConstructorElementX constructor = element; 1109 SynthesizedConstructorElementX constructor = element;
1101 if (!constructor.isDefaultConstructor) { 1110 if (!constructor.isDefaultConstructor) {
1102 giveup(null, 'cannot handle synthetic forwarding constructors'); 1111 giveup(null, 'cannot handle synthetic forwarding constructors');
1103 } 1112 }
1104 } 1113 }
1105 1114
1106 IrBuilder builder = makeIRBuilder(node, element); 1115 IrBuilder builder = makeIRBuilder(node, element);
1107 1116
1108 return withBuilder(builder, () => _makeFunctionBody(element, node)); 1117 return withBuilder(builder, () => _makeFunctionBody(element, node));
1109 } 1118 }
1119
1120 List<ir.Primitive> normalizeStaticArguments(
1121 Selector selector,
1122 FunctionElement target,
1123 List<ir.Primitive> arguments) {
1124 return arguments;
1125 }
1126
1127 List<ir.Primitive> normalizeDynamicArguments(
1128 Selector selector,
1129 List<ir.Primitive> arguments) {
1130 return arguments;
1131 }
1110 } 1132 }
1111 1133
1112 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. 1134 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
1113 class JsIrBuilderVisitor extends IrBuilderVisitor { 1135 class JsIrBuilderVisitor extends IrBuilderVisitor {
1114 /// Promote the type of [irBuilder] to [JsIrBuilder]. 1136 /// Promote the type of [irBuilder] to [JsIrBuilder].
1115 JsIrBuilder get irBuilder => super.irBuilder; 1137 JsIrBuilder get irBuilder => super.irBuilder;
1116 1138
1117 /// Result of closure conversion for the current body of code. 1139 /// Result of closure conversion for the current body of code.
1118 /// 1140 ///
1119 /// Will be initialized upon entering the body of a function. 1141 /// Will be initialized upon entering the body of a function.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 /// Such expressions need to be compiled with a different [sourceFile] and 1257 /// Such expressions need to be compiled with a different [sourceFile] and
1236 /// [elements] mapping. 1258 /// [elements] mapping.
1237 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { 1259 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
1238 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( 1260 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
1239 context.resolvedAst.elements, 1261 context.resolvedAst.elements,
1240 compiler, 1262 compiler,
1241 elementSourceFile(context)); 1263 elementSourceFile(context));
1242 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); 1264 return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
1243 } 1265 }
1244 1266
1267 /// Builds the IR for a constant taken from a different [context].
1268 ///
1269 /// Such constants need to be compiled with a different [sourceFile] and
1270 /// [elements] mapping.
1271 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
1272 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
1273 context.resolvedAst.elements,
1274 compiler,
1275 elementSourceFile(context));
1276 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
1277 }
1278
1245 /// Builds the IR for a given constructor. 1279 /// Builds the IR for a given constructor.
1246 /// 1280 ///
1247 /// 1. Evaluates all own or inherited field initializers. 1281 /// 1. Evaluates all own or inherited field initializers.
1248 /// 2. Creates the object and assigns its fields. 1282 /// 2. Creates the object and assigns its fields.
1249 /// 3. Calls constructor body and super constructor bodies. 1283 /// 3. Calls constructor body and super constructor bodies.
1250 /// 4. Returns the created object. 1284 /// 4. Returns the created object.
1251 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { 1285 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
1252 constructor = constructor.implementation; 1286 constructor = constructor.implementation;
1253 ClassElement classElement = constructor.enclosingClass.implementation; 1287 ClassElement classElement = constructor.enclosingClass.implementation;
1254 1288
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 1572
1539 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( 1573 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping(
1540 element, 1574 element,
1541 node, 1575 node,
1542 elements); 1576 elements);
1543 IrBuilder builder = 1577 IrBuilder builder =
1544 new JsIrBuilder(compiler.backend.constantSystem, element); 1578 new JsIrBuilder(compiler.backend.constantSystem, element);
1545 return withBuilder(builder, () => _makeFunctionBody(element, node)); 1579 return withBuilder(builder, () => _makeFunctionBody(element, node));
1546 } 1580 }
1547 1581
1582 /// Creates a primitive for the default value of [parameter].
1583 ir.Primitive translateDefaultValue(ParameterElement parameter) {
1584 if (parameter.initializer == null) {
1585 return irBuilder.buildNullLiteral();
1586 } else {
1587 return inlineConstant(parameter.executableContext, parameter.initializer);
1588 }
1589 }
1590
1591 /// Inserts default arguments and normalizes order of named arguments.
1592 List<ir.Primitive> normalizeStaticArguments(
1593 Selector selector,
1594 FunctionElement target,
1595 List<ir.Primitive> arguments) {
1596 target = target.implementation;
1597 if (!target.functionSignature.optionalParametersAreNamed &&
1598 target.functionSignature.parameterCount == arguments.length) {
1599 // Optimization: don't copy the argument list for trivial cases.
1600 return arguments;
1601 }
1602 return selector.makeArgumentsList(
1603 target,
1604 arguments,
1605 translateDefaultValue);
1606 }
1607
1608 /// Normalizes order of named arguments.
1609 List<ir.Primitive> normalizeDynamicArguments(
1610 Selector selector,
1611 List<ir.Primitive> arguments) {
1612 // Optimization: don't copy the argument list for trivial cases.
1613 if (selector.namedArguments.isEmpty) return arguments;
1614 return selector.makeDynamicArgumentsList(arguments);
1615 }
1616
1548 } 1617 }
1549 1618
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698