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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2550323002: Insert default arguments for static calls and constructor calls. (Closed)
Patch Set: Created 4 years 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 @override 1064 @override
1065 void visitLet(ir.Let let) { 1065 void visitLet(ir.Let let) {
1066 ir.VariableDeclaration variable = let.variable; 1066 ir.VariableDeclaration variable = let.variable;
1067 variable.initializer.accept(this); 1067 variable.initializer.accept(this);
1068 HInstruction initializedValue = pop(); 1068 HInstruction initializedValue = pop();
1069 // TODO(sra): Apply inferred type information. 1069 // TODO(sra): Apply inferred type information.
1070 letBindings[variable] = initializedValue; 1070 letBindings[variable] = initializedValue;
1071 let.body.accept(this); 1071 let.body.accept(this);
1072 } 1072 }
1073 1073
1074 // TODO(het): Also extract type arguments 1074 /// Extracts the list of instructions for the expressions in the list.
1075 /// Extracts the list of instructions for the expressions in the arguments. 1075 List<HInstruction> _visitList(List<ir.Expression> expressions) {
1076 List<HInstruction> _visitArguments(ir.Arguments arguments) {
1077 List<HInstruction> result = <HInstruction>[]; 1076 List<HInstruction> result = <HInstruction>[];
1078 1077 for (ir.Expression expression in expressions) {
1079 for (ir.Expression argument in arguments.positional) { 1078 expression.accept(this);
1080 argument.accept(this);
1081 result.add(pop()); 1079 result.add(pop());
1082 } 1080 }
1083 for (ir.NamedExpression argument in arguments.named) {
1084 argument.value.accept(this);
1085 result.add(pop());
1086 }
1087
1088 return result; 1081 return result;
1089 } 1082 }
1090 1083
1084 /// Builds the list of instructions for the expressions in the arguments to a
1085 /// dynamic target (member function).
Siggi Cherem (dart-lang) 2016/12/06 18:04:15 now might be a good opportunity to document why th
sra1 2016/12/06 18:27:37 Done.
1086 List<HInstruction> _visitArgumentsForDynamicTarget(
1087 Selector selector, ir.Arguments arguments) {
1088 List<HInstruction> values = _visitList(arguments.positional);
1089
1090 if (arguments.named.isEmpty) return values;
1091
1092 var namedValues = <String, HInstruction>{};
1093 for (ir.NamedExpression argument in arguments.named) {
1094 argument.value.accept(this);
1095 namedValues[argument.name] = pop();
1096 }
1097 for (String name in selector.callStructure.getOrderedNamedArguments()) {
1098 values.add(namedValues[name]);
1099 }
1100
1101 return values;
1102 }
1103
1104 /// Build argument list in canonical order for a static [target], including
1105 /// defaulted arguments.
1106 List<HInstruction> _visitArgumentsForStaticTarget(
1107 ir.FunctionNode target, ir.Arguments arguments) {
1108 // Visit arguments in source order, then re-order and fill in defaults.
1109 var values = _visitList(arguments.positional);
1110
1111 while (values.length < target.positionalParameters.length) {
1112 ir.VariableDeclaration parameter =
1113 target.positionalParameters[values.length];
1114 values.add(_defaultValueForParameter(parameter));
1115 }
1116
1117 if (arguments.named.isEmpty) return values;
1118
1119 var namedValues = <String, HInstruction>{};
1120 for (ir.NamedExpression argument in arguments.named) {
1121 argument.value.accept(this);
1122 namedValues[argument.name] = pop();
1123 }
1124
1125 // Visit named arguments in parameter-position order, selecting provided or
1126 // default value.
1127 // TODO(sra): Ensure the stored order is canonical so we don't have to
1128 // sort. The old builder uses CallStructure.makeArgumentList which depends
1129 // on the old element model.
1130 var namedParameters = target.namedParameters.toList()
1131 ..sort((ir.VariableDeclaration a, ir.VariableDeclaration b) =>
1132 a.name.compareTo(b.name));
1133 for (ir.VariableDeclaration parameter in namedParameters) {
1134 HInstruction value = namedValues[parameter.name];
1135 if (value == null) {
1136 values.add(_defaultValueForParameter(parameter));
1137 } else {
1138 values.add(value);
1139 namedValues.remove(parameter.name);
1140 }
1141 }
1142 assert(namedValues.isEmpty);
1143
1144 return values;
1145 }
1146
1147 HInstruction _defaultValueForParameter(ir.VariableDeclaration parameter) {
1148 ir.Expression initializer = parameter.initializer;
1149 if (initializer == null) return graph.addConstantNull(compiler);
1150 // TODO(sra): Evaluate constant in ir.Node domain.
Siggi Cherem (dart-lang) 2016/12/06 18:04:15 when we do - I'd like to request from kernel-ir so
sra1 2016/12/06 18:27:37 Acknowledged.
1151 ConstantValue constant =
1152 astAdapter.getConstantForParameterDefaultValue(initializer);
1153 if (constant == null) return graph.addConstantNull(compiler);
1154 return graph.addConstant(constant, compiler);
1155 }
1156
1091 @override 1157 @override
1092 void visitStaticInvocation(ir.StaticInvocation invocation) { 1158 void visitStaticInvocation(ir.StaticInvocation invocation) {
1093 ir.Procedure target = invocation.target; 1159 ir.Procedure target = invocation.target;
1094 if (astAdapter.isInForeignLibrary(target)) { 1160 if (astAdapter.isInForeignLibrary(target)) {
1095 handleInvokeStaticForeign(invocation, target); 1161 handleInvokeStaticForeign(invocation, target);
1096 return; 1162 return;
1097 } 1163 }
1098 TypeMask typeMask = astAdapter.returnTypeOf(target); 1164 TypeMask typeMask = astAdapter.returnTypeOf(target);
1099 1165
1100 List<HInstruction> arguments = _visitArguments(invocation.arguments); 1166 // TODO(sra): For JS interop external functions, use a different function to
1167 // build arguments.
1168 List<HInstruction> arguments =
1169 _visitArgumentsForStaticTarget(target.function, invocation.arguments);
1101 1170
1102 _pushStaticInvocation(target, arguments, typeMask); 1171 _pushStaticInvocation(target, arguments, typeMask);
1103 } 1172 }
1104 1173
1105 void handleInvokeStaticForeign( 1174 void handleInvokeStaticForeign(
1106 ir.StaticInvocation invocation, ir.Procedure target) { 1175 ir.StaticInvocation invocation, ir.Procedure target) {
1107 String name = target.name.name; 1176 String name = target.name.name;
1108 if (name == 'JS') { 1177 if (name == 'JS') {
1109 handleForeignJs(invocation); 1178 handleForeignJs(invocation);
1110 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { 1179 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 _pushStaticInvocation(target, <HInstruction>[], backend.dynamicType); 1306 _pushStaticInvocation(target, <HInstruction>[], backend.dynamicType);
1238 } 1307 }
1239 } 1308 }
1240 1309
1241 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) { 1310 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) {
1242 if (_unexpectedForeignArguments(invocation, 2, 2)) { 1311 if (_unexpectedForeignArguments(invocation, 2, 2)) {
1243 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. 1312 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1244 return; 1313 return;
1245 } 1314 }
1246 1315
1247 List<HInstruction> inputs = _visitArguments(invocation.arguments); 1316 List<HInstruction> inputs = _visitList(invocation.arguments.positional);
Johnni Winther 2016/12/06 08:36:37 I'd prefer calling [_visitArgumentsForStaticTarget
sra1 2016/12/06 18:27:37 The _unexpectedForeignArguments call ensures there
1248 1317
1249 if (!compiler.hasIsolateSupport) { 1318 if (!compiler.hasIsolateSupport) {
1250 // If the isolate library is not used, we ignore the isolate argument and 1319 // If the isolate library is not used, we ignore the isolate argument and
1251 // just invoke the closure. 1320 // just invoke the closure.
1252 push(new HInvokeClosure(new Selector.callClosure(0), 1321 push(new HInvokeClosure(new Selector.callClosure(0),
1253 <HInstruction>[inputs[1]], backend.dynamicType)); 1322 <HInstruction>[inputs[1]], backend.dynamicType));
1254 } else { 1323 } else {
1255 // Call a helper method from the isolate library. 1324 // Call a helper method from the isolate library.
1256 ir.Procedure callInIsolate = astAdapter.callInIsolate; 1325 ir.Procedure callInIsolate = astAdapter.callInIsolate;
1257 if (callInIsolate == null) { 1326 if (callInIsolate == null) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. 1376 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1308 return; 1377 return;
1309 } 1378 }
1310 1379
1311 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) { 1380 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) {
1312 if (_unexpectedForeignArguments(invocation, 1, 1)) { 1381 if (_unexpectedForeignArguments(invocation, 1, 1)) {
1313 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. 1382 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1314 return; 1383 return;
1315 } 1384 }
1316 1385
1317 List<HInstruction> inputs = _visitArguments(invocation.arguments); 1386 List<HInstruction> inputs = _visitList(invocation.arguments.positional);
1318 1387
1319 String isolateName = backend.namer.staticStateHolder; 1388 String isolateName = backend.namer.staticStateHolder;
1320 SideEffects sideEffects = new SideEffects.empty(); 1389 SideEffects sideEffects = new SideEffects.empty();
1321 sideEffects.setAllSideEffects(); 1390 sideEffects.setAllSideEffects();
1322 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), 1391 push(new HForeignCode(
1323 backend.dynamicType, inputs, 1392 js.js.parseForeignJS("$isolateName = #"), backend.dynamicType, inputs,
1324 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, 1393 nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
1325 effects: sideEffects)); 1394 effects: sideEffects));
1326 } 1395 }
1327 1396
1328 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) { 1397 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) {
1329 if (_unexpectedForeignArguments(invocation, 0, 0)) { 1398 if (_unexpectedForeignArguments(invocation, 0, 0)) {
1330 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. 1399 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1331 return; 1400 return;
1332 } 1401 }
1333 1402
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 isStatement: !nativeBehavior.codeTemplate.isExpression, 1580 isStatement: !nativeBehavior.codeTemplate.isExpression,
1512 effects: nativeBehavior.sideEffects, 1581 effects: nativeBehavior.sideEffects,
1513 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation); 1582 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation);
1514 } 1583 }
1515 1584
1516 void handleJsStringConcat(ir.StaticInvocation invocation) { 1585 void handleJsStringConcat(ir.StaticInvocation invocation) {
1517 if (_unexpectedForeignArguments(invocation, 2, 2)) { 1586 if (_unexpectedForeignArguments(invocation, 2, 2)) {
1518 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. 1587 stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
1519 return; 1588 return;
1520 } 1589 }
1521 List<HInstruction> inputs = _visitArguments(invocation.arguments); 1590 List<HInstruction> inputs = _visitList(invocation.arguments.positional);
1522 push(new HStringConcat(inputs[0], inputs[1], backend.stringType)); 1591 push(new HStringConcat(inputs[0], inputs[1], backend.stringType));
1523 } 1592 }
1524 1593
1525 void _pushStaticInvocation( 1594 void _pushStaticInvocation(
1526 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) { 1595 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
1527 HInvokeStatic instruction = new HInvokeStatic( 1596 HInvokeStatic instruction = new HInvokeStatic(
1528 astAdapter.getMember(target), arguments, typeMask, 1597 astAdapter.getMember(target), arguments, typeMask,
1529 targetCanThrow: astAdapter.getCanThrow(target)); 1598 targetCanThrow: astAdapter.getCanThrow(target));
1530 if (currentImplicitInstantiations.isNotEmpty) { 1599 if (currentImplicitInstantiations.isNotEmpty) {
1531 instruction.instantiatedTypes = 1600 instruction.instantiatedTypes =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 } 1632 }
1564 1633
1565 // TODO(het): Decide when to inline 1634 // TODO(het): Decide when to inline
1566 @override 1635 @override
1567 void visitMethodInvocation(ir.MethodInvocation invocation) { 1636 void visitMethodInvocation(ir.MethodInvocation invocation) {
1568 // Handle `x == null` specially. When these come from null-aware operators, 1637 // Handle `x == null` specially. When these come from null-aware operators,
1569 // there is no mapping in the astAdapter. 1638 // there is no mapping in the astAdapter.
1570 if (_handleEqualsNull(invocation)) return; 1639 if (_handleEqualsNull(invocation)) return;
1571 invocation.receiver.accept(this); 1640 invocation.receiver.accept(this);
1572 HInstruction receiver = pop(); 1641 HInstruction receiver = pop();
1573 1642 Selector selector = astAdapter.getSelector(invocation);
1574 _pushDynamicInvocation( 1643 _pushDynamicInvocation(
1575 invocation, 1644 invocation,
1576 astAdapter.typeOfInvocation(invocation), 1645 astAdapter.typeOfInvocation(invocation),
1577 <HInstruction>[receiver] 1646 <HInstruction>[receiver]
1578 ..addAll(_visitArguments(invocation.arguments))); 1647 ..addAll(
1648 _visitArgumentsForDynamicTarget(selector, invocation.arguments)));
1579 } 1649 }
1580 1650
1581 bool _handleEqualsNull(ir.MethodInvocation invocation) { 1651 bool _handleEqualsNull(ir.MethodInvocation invocation) {
1582 if (invocation.name.name == '==') { 1652 if (invocation.name.name == '==') {
1583 ir.Arguments arguments = invocation.arguments; 1653 ir.Arguments arguments = invocation.arguments;
1584 if (arguments.types.isEmpty && 1654 if (arguments.types.isEmpty &&
1585 arguments.positional.length == 1 && 1655 arguments.positional.length == 1 &&
1586 arguments.named.isEmpty) { 1656 arguments.named.isEmpty) {
1587 bool finish(ir.Expression comparand) { 1657 bool finish(ir.Expression comparand) {
1588 comparand.accept(this); 1658 comparand.accept(this);
(...skipping 20 matching lines...) Expand all
1609 static ir.Class _containingClass(ir.TreeNode node) { 1679 static ir.Class _containingClass(ir.TreeNode node) {
1610 while (node != null) { 1680 while (node != null) {
1611 if (node is ir.Class) return node; 1681 if (node is ir.Class) return node;
1612 node = node.parent; 1682 node = node.parent;
1613 } 1683 }
1614 return null; 1684 return null;
1615 } 1685 }
1616 1686
1617 @override 1687 @override
1618 void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) { 1688 void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) {
1619 List<HInstruction> arguments = _visitArguments(invocation.arguments); 1689 Selector selector = astAdapter.getSelector(invocation);
1690 List<HInstruction> arguments = _visitArgumentsForStaticTarget(
1691 invocation.interfaceTarget.function, invocation.arguments);
1620 HInstruction receiver = localsHandler.readThis(); 1692 HInstruction receiver = localsHandler.readThis();
1621 Selector selector = astAdapter.getSelector(invocation);
1622 ir.Class surroundingClass = _containingClass(invocation); 1693 ir.Class surroundingClass = _containingClass(invocation);
1623 1694
1624 List<HInstruction> inputs = <HInstruction>[]; 1695 List<HInstruction> inputs = <HInstruction>[];
1625 if (astAdapter.isIntercepted(invocation)) { 1696 if (astAdapter.isIntercepted(invocation)) {
1626 inputs.add(_interceptorFor(receiver)); 1697 inputs.add(_interceptorFor(receiver));
1627 } 1698 }
1628 inputs.add(receiver); 1699 inputs.add(receiver);
1629 inputs.addAll(arguments); 1700 inputs.addAll(arguments);
1630 1701
1631 HInstruction instruction = new HInvokeSuper( 1702 HInstruction instruction = new HInvokeSuper(
1632 astAdapter.getMethod(invocation.interfaceTarget), 1703 astAdapter.getMethod(invocation.interfaceTarget),
1633 astAdapter.getClass(surroundingClass), 1704 astAdapter.getClass(surroundingClass),
1634 selector, 1705 selector,
1635 inputs, 1706 inputs,
1636 astAdapter.returnTypeOf(invocation.interfaceTarget), 1707 astAdapter.returnTypeOf(invocation.interfaceTarget),
1637 null, 1708 null,
1638 isSetter: selector.isSetter || selector.isIndexSet); 1709 isSetter: selector.isSetter || selector.isIndexSet);
1639 instruction.sideEffects = 1710 instruction.sideEffects =
1640 compiler.closedWorld.getSideEffectsOfSelector(selector, null); 1711 compiler.closedWorld.getSideEffectsOfSelector(selector, null);
1641 push(instruction); 1712 push(instruction);
1642 } 1713 }
1643 1714
1644 @override 1715 @override
1645 void visitConstructorInvocation(ir.ConstructorInvocation invocation) { 1716 void visitConstructorInvocation(ir.ConstructorInvocation invocation) {
1646 ir.Constructor target = invocation.target; 1717 ir.Constructor target = invocation.target;
1647 List<HInstruction> arguments = _visitArguments(invocation.arguments); 1718 // TODO(sra): For JS-interop targets, process arguments differently.
1719 List<HInstruction> arguments =
1720 _visitArgumentsForStaticTarget(target.function, invocation.arguments);
1648 TypeMask typeMask = new TypeMask.nonNullExact( 1721 TypeMask typeMask = new TypeMask.nonNullExact(
1649 astAdapter.getElement(target.enclosingClass), compiler.closedWorld); 1722 astAdapter.getElement(target.enclosingClass), compiler.closedWorld);
1650 _pushStaticInvocation(target, arguments, typeMask); 1723 _pushStaticInvocation(target, arguments, typeMask);
1651 } 1724 }
1652 1725
1653 @override 1726 @override
1654 void visitIsExpression(ir.IsExpression isExpression) { 1727 void visitIsExpression(ir.IsExpression isExpression) {
1655 isExpression.operand.accept(this); 1728 isExpression.operand.accept(this);
1656 HInstruction expression = pop(); 1729 HInstruction expression = pop();
1657 1730
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 push(new HNot(popBoolified(), backend.boolType)); 1798 push(new HNot(popBoolified(), backend.boolType));
1726 } 1799 }
1727 1800
1728 @override 1801 @override
1729 void visitStringConcatenation(ir.StringConcatenation stringConcat) { 1802 void visitStringConcatenation(ir.StringConcatenation stringConcat) {
1730 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); 1803 KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
1731 stringConcat.accept(stringBuilder); 1804 stringConcat.accept(stringBuilder);
1732 stack.add(stringBuilder.result); 1805 stack.add(stringBuilder.result);
1733 } 1806 }
1734 } 1807 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/kernel_visitor.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698