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

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

Issue 879483005: Revert "dart2js cps: Handle optional parameters in builder." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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);
158 147
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);
168 148
169 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, 149 ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
170 ast.FunctionExpression node) { 150 ast.FunctionExpression node) {
171 FunctionSignature signature = element.functionSignature; 151 FunctionSignature signature = element.functionSignature;
172 List<ParameterElement> parameters = []; 152 List<ParameterElement> parameters = [];
173 signature.orderedForEachParameter(parameters.add); 153 signature.orderedForEachParameter(parameters.add);
174 154
175 irBuilder.buildFunctionHeader(parameters, 155 irBuilder.buildFunctionHeader(parameters,
176 closureScope: getClosureScopeForNode(node), 156 closureScope: getClosureScopeForNode(node),
177 env: getClosureEnvironment()); 157 env: getClosureEnvironment());
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 } 542 }
563 543
564 ir.Primitive visitNamedArgument(ast.NamedArgument node) { 544 ir.Primitive visitNamedArgument(ast.NamedArgument node) {
565 assert(irBuilder.isOpen); 545 assert(irBuilder.isOpen);
566 return visit(node.expression); 546 return visit(node.expression);
567 } 547 }
568 548
569 ir.Primitive visitClosureSend(ast.Send node) { 549 ir.Primitive visitClosureSend(ast.Send node) {
570 assert(irBuilder.isOpen); 550 assert(irBuilder.isOpen);
571 Element element = elements[node]; 551 Element element = elements[node];
572 Selector selector = elements.getSelector(node); 552 Selector closureSelector = elements.getSelector(node);
573 ir.Primitive receiver = (element == null) 553 if (element == null) {
574 ? visit(node.selector) 554 ir.Primitive closureTarget = visit(node.selector);
575 : irBuilder.buildLocalGet(element); 555 List<ir.Primitive> args =
576 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 556 node.arguments.mapToList(visit, growable:false);
577 arguments = normalizeDynamicArguments(selector, arguments); 557 return irBuilder.buildFunctionExpressionInvocation(
578 return irBuilder.buildFunctionExpressionInvocation( 558 closureTarget, elements.getSelector(node), args);
579 receiver, selector, arguments); 559 } else {
560 List<ir.Primitive> args =
561 node.arguments.mapToList(visit, growable:false);
562 return irBuilder.buildLocalInvocation(
563 element, elements.getSelector(node), args);
564 }
580 } 565 }
581 566
582 /// If [node] is null, returns this. 567 /// If [node] is null, returns this.
583 /// If [node] is super, returns null (for special handling) 568 /// If [node] is super, returns null (for special handling)
584 /// Otherwise visits [node] and returns the result. 569 /// Otherwise visits [node] and returns the result.
585 ir.Primitive visitReceiver(ast.Expression node) { 570 ir.Primitive visitReceiver(ast.Expression node) {
586 if (node == null) return irBuilder.buildThis(); 571 if (node == null) return irBuilder.buildThis();
587 if (node.isSuper()) return null; 572 if (node.isSuper()) return null;
588 return visit(node); 573 return visit(node);
589 } 574 }
590 575
591 /// Returns `true` if [node] is a super call. 576 /// Returns `true` if [node] is a super call.
592 // TODO(johnniwinther): Remove the need for this. 577 // TODO(johnniwinther): Remove the need for this.
593 bool isSuperCall(ast.Send node) { 578 bool isSuperCall(ast.Send node) {
594 return node != null && node.receiver != null && node.receiver.isSuper(); 579 return node != null && node.receiver != null && node.receiver.isSuper();
595 } 580 }
596 581
597 ir.Primitive visitDynamicSend(ast.Send node) { 582 ir.Primitive visitDynamicSend(ast.Send node) {
598 assert(irBuilder.isOpen); 583 assert(irBuilder.isOpen);
599 Selector selector = elements.getSelector(node); 584 Selector selector = elements.getSelector(node);
600 ir.Primitive receiver = visitReceiver(node.receiver); 585 ir.Primitive receiver = visitReceiver(node.receiver);
601 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 586 List<ir.Primitive> arguments = new List<ir.Primitive>();
602 arguments = normalizeDynamicArguments(selector, arguments); 587 for (ast.Node n in node.arguments) {
588 arguments.add(visit(n));
589 }
603 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); 590 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
604 } 591 }
605 592
606 _GetterElements translateGetter(ast.Send node, Selector selector) { 593 _GetterElements translateGetter(ast.Send node, Selector selector) {
607 Element element = elements[node]; 594 Element element = elements[node];
608 ir.Primitive result; 595 ir.Primitive result;
609 ir.Primitive receiver; 596 ir.Primitive receiver;
610 ir.Primitive index; 597 ir.Primitive index;
611 598
612 if (element != null && element.isConst) { 599 if (element != null && element.isConst) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 assert(irBuilder.isOpen); 705 assert(irBuilder.isOpen);
719 Element element = elements[node]; 706 Element element = elements[node];
720 assert(!element.isConstructor); 707 assert(!element.isConstructor);
721 // TODO(lry): support foreign functions. 708 // TODO(lry): support foreign functions.
722 if (element.isForeign(compiler.backend)) { 709 if (element.isForeign(compiler.backend)) {
723 return giveup(node, 'StaticSend: foreign'); 710 return giveup(node, 'StaticSend: foreign');
724 } 711 }
725 712
726 Selector selector = elements.getSelector(node); 713 Selector selector = elements.getSelector(node);
727 714
715 // TODO(lry): support default arguments, need support for locals.
728 List<ir.Primitive> arguments = 716 List<ir.Primitive> arguments =
729 node.arguments.mapToList(visit, growable:false); 717 node.arguments.mapToList(visit, growable:false);
730 arguments = normalizeStaticArguments(selector, element, arguments);
731 return irBuilder.buildStaticInvocation(element, selector, arguments); 718 return irBuilder.buildStaticInvocation(element, selector, arguments);
732 } 719 }
733 720
734 ir.Primitive visitSuperSend(ast.Send node) { 721 ir.Primitive visitSuperSend(ast.Send node) {
735 assert(irBuilder.isOpen); 722 assert(irBuilder.isOpen);
736 if (node.isPropertyAccess) { 723 if (node.isPropertyAccess) {
737 return visitGetterSend(node); 724 return visitGetterSend(node);
738 } else { 725 } else {
739 Selector selector = elements.getSelector(node); 726 Selector selector = elements.getSelector(node);
740 Element target = elements[node]; 727 Element target = elements[node];
741 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 728 List<ir.Primitive> arguments = new List<ir.Primitive>();
742 arguments = normalizeStaticArguments(selector, target, arguments); 729 for (ast.Node n in node.arguments) {
730 arguments.add(visit(n));
731 }
743 return irBuilder.buildSuperInvocation(target, selector, arguments); 732 return irBuilder.buildSuperInvocation(target, selector, arguments);
744 } 733 }
745 } 734 }
746 735
747 visitTypePrefixSend(ast.Send node) { 736 visitTypePrefixSend(ast.Send node) {
748 compiler.internalError(node, "visitTypePrefixSend should not be called."); 737 compiler.internalError(node, "visitTypePrefixSend should not be called.");
749 } 738 }
750 739
751 ir.Primitive visitTypeLiteralSend(ast.Send node) { 740 ir.Primitive visitTypeLiteralSend(ast.Send node) {
752 assert(irBuilder.isOpen); 741 assert(irBuilder.isOpen);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 } 854 }
866 855
867 ir.Primitive visitNewExpression(ast.NewExpression node) { 856 ir.Primitive visitNewExpression(ast.NewExpression node) {
868 if (node.isConst) { 857 if (node.isConst) {
869 return translateConstant(node); 858 return translateConstant(node);
870 } 859 }
871 FunctionElement element = elements[node.send]; 860 FunctionElement element = elements[node.send];
872 Selector selector = elements.getSelector(node.send); 861 Selector selector = elements.getSelector(node.send);
873 DartType type = elements.getType(node); 862 DartType type = elements.getType(node);
874 ast.Node selectorNode = node.send.selector; 863 ast.Node selectorNode = node.send.selector;
875 List<ir.Primitive> arguments = 864 List<ir.Definition> arguments =
876 node.send.arguments.mapToList(visit, growable:false); 865 node.send.arguments.mapToList(visit, growable:false);
877 arguments = normalizeStaticArguments(selector, element, arguments);
878 return irBuilder.buildConstructorInvocation( 866 return irBuilder.buildConstructorInvocation(
879 element, selector, type, arguments); 867 element, selector, type, arguments);
880 } 868 }
881 869
882 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { 870 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
883 assert(irBuilder.isOpen); 871 assert(irBuilder.isOpen);
884 ir.Primitive first = visit(node.first); 872 ir.Primitive first = visit(node.first);
885 ir.Primitive second = visit(node.second); 873 ir.Primitive second = visit(node.second);
886 return irBuilder.buildStringConcatenation([first, second]); 874 return irBuilder.buildStringConcatenation([first, second]);
887 } 875 }
888 876
889 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { 877 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
890 assert(irBuilder.isOpen); 878 assert(irBuilder.isOpen);
891 List<ir.Primitive> arguments = []; 879 List<ir.Primitive> arguments = [];
892 arguments.add(visitLiteralString(node.string)); 880 arguments.add(visitLiteralString(node.string));
893 var it = node.parts.iterator; 881 var it = node.parts.iterator;
894 while (it.moveNext()) { 882 while (it.moveNext()) {
895 ast.StringInterpolationPart part = it.current; 883 ast.StringInterpolationPart part = it.current;
896 arguments.add(visit(part.expression)); 884 arguments.add(visit(part.expression));
897 arguments.add(visitLiteralString(part.string)); 885 arguments.add(visitLiteralString(part.string));
898 } 886 }
899 return irBuilder.buildStringConcatenation(arguments); 887 return irBuilder.buildStringConcatenation(arguments);
900 } 888 }
901 889
902 ir.Primitive translateConstant(ast.Node node) { 890 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) {
903 assert(irBuilder.isOpen); 891 assert(irBuilder.isOpen);
904 return irBuilder.buildConstantLiteral(getConstantForNode(node)); 892 if (constant == null) {
893 constant = getConstantForNode(node);
894 }
895 return irBuilder.buildConstantLiteral(constant);
905 } 896 }
906 897
907 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { 898 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) {
908 try { 899 try {
909 return action(); 900 return action();
910 } catch(e, tr) { 901 } catch(e, tr) {
911 if (e == ABORT_IRNODE_BUILDER) { 902 if (e == ABORT_IRNODE_BUILDER) {
912 return null; 903 return null;
913 } 904 }
914 rethrow; 905 rethrow;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 SynthesizedConstructorElementX constructor = element; 1100 SynthesizedConstructorElementX constructor = element;
1110 if (!constructor.isDefaultConstructor) { 1101 if (!constructor.isDefaultConstructor) {
1111 giveup(null, 'cannot handle synthetic forwarding constructors'); 1102 giveup(null, 'cannot handle synthetic forwarding constructors');
1112 } 1103 }
1113 } 1104 }
1114 1105
1115 IrBuilder builder = makeIRBuilder(node, element); 1106 IrBuilder builder = makeIRBuilder(node, element);
1116 1107
1117 return withBuilder(builder, () => _makeFunctionBody(element, node)); 1108 return withBuilder(builder, () => _makeFunctionBody(element, node));
1118 } 1109 }
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 }
1132 } 1110 }
1133 1111
1134 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. 1112 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
1135 class JsIrBuilderVisitor extends IrBuilderVisitor { 1113 class JsIrBuilderVisitor extends IrBuilderVisitor {
1136 /// Promote the type of [irBuilder] to [JsIrBuilder]. 1114 /// Promote the type of [irBuilder] to [JsIrBuilder].
1137 JsIrBuilder get irBuilder => super.irBuilder; 1115 JsIrBuilder get irBuilder => super.irBuilder;
1138 1116
1139 /// Result of closure conversion for the current body of code. 1117 /// Result of closure conversion for the current body of code.
1140 /// 1118 ///
1141 /// Will be initialized upon entering the body of a function. 1119 /// Will be initialized upon entering the body of a function.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 /// Such expressions need to be compiled with a different [sourceFile] and 1235 /// Such expressions need to be compiled with a different [sourceFile] and
1258 /// [elements] mapping. 1236 /// [elements] mapping.
1259 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { 1237 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
1260 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( 1238 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
1261 context.resolvedAst.elements, 1239 context.resolvedAst.elements,
1262 compiler, 1240 compiler,
1263 elementSourceFile(context)); 1241 elementSourceFile(context));
1264 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); 1242 return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
1265 } 1243 }
1266 1244
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
1279 /// Builds the IR for a given constructor. 1245 /// Builds the IR for a given constructor.
1280 /// 1246 ///
1281 /// 1. Evaluates all own or inherited field initializers. 1247 /// 1. Evaluates all own or inherited field initializers.
1282 /// 2. Creates the object and assigns its fields. 1248 /// 2. Creates the object and assigns its fields.
1283 /// 3. Calls constructor body and super constructor bodies. 1249 /// 3. Calls constructor body and super constructor bodies.
1284 /// 4. Returns the created object. 1250 /// 4. Returns the created object.
1285 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { 1251 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
1286 constructor = constructor.implementation; 1252 constructor = constructor.implementation;
1287 ClassElement classElement = constructor.enclosingClass.implementation; 1253 ClassElement classElement = constructor.enclosingClass.implementation;
1288 1254
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 1539
1574 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( 1540 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping(
1575 element, 1541 element,
1576 node, 1542 node,
1577 elements); 1543 elements);
1578 IrBuilder builder = 1544 IrBuilder builder =
1579 new JsIrBuilder(compiler.backend.constantSystem, element); 1545 new JsIrBuilder(compiler.backend.constantSystem, element);
1580 return withBuilder(builder, () => _makeFunctionBody(element, node)); 1546 return withBuilder(builder, () => _makeFunctionBody(element, node));
1581 } 1547 }
1582 1548
1583 /// Creates a primitive for the default value of [parameter].
1584 ir.Primitive translateDefaultValue(ParameterElement parameter) {
1585 if (parameter.initializer == null) {
1586 return irBuilder.buildNullLiteral();
1587 } else {
1588 return inlineConstant(parameter.executableContext, parameter.initializer);
1589 }
1590 }
1591
1592 /// Inserts default arguments and normalizes order of named arguments.
1593 List<ir.Primitive> normalizeStaticArguments(
1594 Selector selector,
1595 FunctionElement target,
1596 List<ir.Primitive> arguments) {
1597 target = target.implementation;
1598 FunctionSignature signature = target.functionSignature;
1599 if (!signature.optionalParametersAreNamed &&
1600 signature.parameterCount == arguments.length) {
1601 // Optimization: don't copy the argument list for trivial cases.
1602 return arguments;
1603 }
1604
1605 List<ir.Primitive> result = <ir.Primitive>[];
1606 int i = 0;
1607 signature.forEachRequiredParameter((ParameterElement element) {
1608 result.add(arguments[i]);
1609 ++i;
1610 });
1611
1612 if (!signature.optionalParametersAreNamed) {
1613 signature.forEachOptionalParameter((ParameterElement element) {
1614 if (i < arguments.length) {
1615 result.add(arguments[i]);
1616 ++i;
1617 } else {
1618 result.add(translateDefaultValue(element));
1619 }
1620 });
1621 } else {
1622 int offset = i;
1623 // Iterate over the optional parameters of the signature, and try to
1624 // find them in [compiledNamedArguments]. If found, we use the
1625 // value in the temporary list, otherwise the default value.
1626 signature.orderedOptionalParameters.forEach((ParameterElement element) {
1627 int nameIndex = selector.namedArguments.indexOf(element.name);
1628 if (nameIndex != -1) {
1629 int translatedIndex = offset + nameIndex;
1630 result.add(arguments[translatedIndex]);
1631 } else {
1632 result.add(translateDefaultValue(element));
1633 }
1634 });
1635 }
1636 return result;
1637 }
1638
1639 /// Normalizes order of named arguments.
1640 List<ir.Primitive> normalizeDynamicArguments(
1641 Selector selector,
1642 List<ir.Primitive> arguments) {
1643 assert(arguments.length == selector.argumentCount);
1644 // Optimization: don't copy the argument list for trivial cases.
1645 if (selector.namedArguments.isEmpty) return arguments;
1646 List<ir.Primitive> result = <ir.Primitive>[];
1647 for (int i=0; i < selector.positionalArgumentCount; i++) {
1648 result.add(arguments[i]);
1649 }
1650 for (String argName in selector.getOrderedNamedArguments()) {
1651 int nameIndex = selector.namedArguments.indexOf(argName);
1652 int translatedIndex = selector.positionalArgumentCount + nameIndex;
1653 result.add(arguments[translatedIndex]);
1654 }
1655 return result;
1656 }
1657
1658 } 1549 }
1659 1550
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698