| OLD | NEW |
| 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 '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 }); | 61 }); |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { | 65 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
| 66 ir.Node target; | 66 ir.Node target; |
| 67 final AstElement targetElement; | 67 final AstElement targetElement; |
| 68 final ResolvedAst resolvedAst; | 68 final ResolvedAst resolvedAst; |
| 69 final CodegenRegistry registry; | 69 final CodegenRegistry registry; |
| 70 | 70 |
| 71 /// Helper accessor for all kernel function-like targets (Procedure, |
| 72 /// FunctionExpression, FunctionDeclaration) of the inner FunctionNode itself. |
| 73 /// If the current target is not a function-like target, _targetFunction will |
| 74 /// be null. |
| 75 ir.FunctionNode _targetFunction; |
| 76 |
| 71 /// A stack of [DartType]s that have been seen during inlining of factory | 77 /// A stack of [DartType]s that have been seen during inlining of factory |
| 72 /// constructors. These types are preserved in [HInvokeStatic]s and | 78 /// constructors. These types are preserved in [HInvokeStatic]s and |
| 73 /// [HCreate]s inside the inline code and registered during code generation | 79 /// [HCreate]s inside the inline code and registered during code generation |
| 74 /// for these nodes. | 80 /// for these nodes. |
| 75 // TODO(karlklose): consider removing this and keeping the (substituted) types | 81 // TODO(karlklose): consider removing this and keeping the (substituted) types |
| 76 // of the type variables in an environment (like the [LocalsHandler]). | 82 // of the type variables in an environment (like the [LocalsHandler]). |
| 77 final List<DartType> currentImplicitInstantiations = <DartType>[]; | 83 final List<DartType> currentImplicitInstantiations = <DartType>[]; |
| 78 | 84 |
| 79 @override | 85 @override |
| 80 JavaScriptBackend get backend => compiler.backend; | 86 JavaScriptBackend get backend => compiler.backend; |
| 81 | 87 |
| 82 @override | 88 @override |
| 83 TreeElements get elements => resolvedAst.elements; | 89 TreeElements get elements => resolvedAst.elements; |
| 84 | 90 |
| 91 |
| 85 SourceInformationBuilder sourceInformationBuilder; | 92 SourceInformationBuilder sourceInformationBuilder; |
| 86 KernelAstAdapter astAdapter; | 93 KernelAstAdapter astAdapter; |
| 87 LoopHandler<ir.Node> loopHandler; | 94 LoopHandler<ir.Node> loopHandler; |
| 88 TypeBuilder typeBuilder; | 95 TypeBuilder typeBuilder; |
| 89 | 96 |
| 90 final Map<ir.VariableDeclaration, HInstruction> letBindings = | 97 final Map<ir.VariableDeclaration, HInstruction> letBindings = |
| 91 <ir.VariableDeclaration, HInstruction>{}; | 98 <ir.VariableDeclaration, HInstruction>{}; |
| 92 | 99 |
| 93 KernelSsaBuilder( | 100 KernelSsaBuilder( |
| 94 this.targetElement, | 101 this.targetElement, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 125 } | 132 } |
| 126 } else if (originTarget is FieldElement) { | 133 } else if (originTarget is FieldElement) { |
| 127 target = kernel.fields[originTarget]; | 134 target = kernel.fields[originTarget]; |
| 128 } | 135 } |
| 129 } | 136 } |
| 130 | 137 |
| 131 HGraph build() { | 138 HGraph build() { |
| 132 // TODO(het): no reason to do this here... | 139 // TODO(het): no reason to do this here... |
| 133 HInstruction.idCounter = 0; | 140 HInstruction.idCounter = 0; |
| 134 if (target is ir.Procedure) { | 141 if (target is ir.Procedure) { |
| 135 target = (target as ir.Procedure).function; | 142 _targetFunction = (target as ir.Procedure).function; |
| 136 buildFunctionNode(target); | 143 buildFunctionNode(_targetFunction); |
| 137 } else if (target is ir.Field) { | 144 } else if (target is ir.Field) { |
| 138 buildField(target); | 145 buildField(target); |
| 139 } else if (target is ir.Constructor) { | 146 } else if (target is ir.Constructor) { |
| 140 buildConstructor(target); | 147 buildConstructor(target); |
| 141 } else if (target is ir.FunctionExpression) { | 148 } else if (target is ir.FunctionExpression) { |
| 142 target = (target as ir.FunctionExpression).function; | 149 _targetFunction = (target as ir.FunctionExpression).function; |
| 143 buildFunctionNode(target); | 150 buildFunctionNode(_targetFunction); |
| 151 } else if (target is ir.FunctionDeclaration) { |
| 152 _targetFunction = (target as ir.FunctionDeclaration).function; |
| 153 buildFunctionNode(_targetFunction); |
| 144 } else { | 154 } else { |
| 145 throw 'No case implemented to handle $target'; | 155 throw 'No case implemented to handle $target'; |
| 146 } | 156 } |
| 147 assert(graph.isValid()); | 157 assert(graph.isValid()); |
| 148 return graph; | 158 return graph; |
| 149 } | 159 } |
| 150 | 160 |
| 151 void buildField(ir.Field field) { | 161 void buildField(ir.Field field) { |
| 152 openFunction(); | 162 openFunction(); |
| 153 if (field.initializer != null) { | 163 if (field.initializer != null) { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 exprStatement.expression.accept(this); | 452 exprStatement.expression.accept(this); |
| 443 pop(); | 453 pop(); |
| 444 } | 454 } |
| 445 | 455 |
| 446 @override | 456 @override |
| 447 void visitReturnStatement(ir.ReturnStatement returnStatement) { | 457 void visitReturnStatement(ir.ReturnStatement returnStatement) { |
| 448 HInstruction value; | 458 HInstruction value; |
| 449 if (returnStatement.expression == null) { | 459 if (returnStatement.expression == null) { |
| 450 value = graph.addConstantNull(compiler); | 460 value = graph.addConstantNull(compiler); |
| 451 } else { | 461 } else { |
| 452 assert(target is ir.FunctionNode); | 462 assert(_targetFunction != null && _targetFunction is ir.FunctionNode); |
| 453 returnStatement.expression.accept(this); | 463 returnStatement.expression.accept(this); |
| 454 value = typeBuilder.potentiallyCheckOrTrustType(pop(), | 464 value = typeBuilder.potentiallyCheckOrTrustType(pop(), |
| 455 astAdapter.getFunctionReturnType(target)); | 465 astAdapter.getFunctionReturnType(_targetFunction)); |
| 456 } | 466 } |
| 457 // TODO(het): Add source information | 467 // TODO(het): Add source information |
| 458 // TODO(het): Set a return value instead of closing the function when we | 468 // TODO(het): Set a return value instead of closing the function when we |
| 459 // support inlining. | 469 // support inlining. |
| 460 closeAndGotoExit(new HReturn(value, null)); | 470 closeAndGotoExit(new HReturn(value, null)); |
| 461 } | 471 } |
| 462 | 472 |
| 463 @override | 473 @override |
| 464 void visitForStatement(ir.ForStatement forStatement) { | 474 void visitForStatement(ir.ForStatement forStatement) { |
| 465 assert(isReachable); | 475 assert(isReachable); |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type)); | 1653 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type)); |
| 1644 } else if (selector.isSetter) { | 1654 } else if (selector.isSetter) { |
| 1645 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); | 1655 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); |
| 1646 } else { | 1656 } else { |
| 1647 push(new HInvokeDynamicMethod( | 1657 push(new HInvokeDynamicMethod( |
| 1648 selector, mask, inputs, type, isIntercepted)); | 1658 selector, mask, inputs, type, isIntercepted)); |
| 1649 } | 1659 } |
| 1650 } | 1660 } |
| 1651 | 1661 |
| 1652 @override | 1662 @override |
| 1653 void visitFunctionExpression(ir.FunctionExpression funcExpression) { | 1663 visitFunctionNode(ir.FunctionNode node) { |
| 1654 LocalFunctionElement methodElement = astAdapter.getElement(funcExpression); | 1664 LocalFunctionElement methodElement = astAdapter.getElement(node); |
| 1655 ClosureClassMap nestedClosureData = compiler.closureToClassMapper | 1665 ClosureClassMap nestedClosureData = compiler.closureToClassMapper |
| 1656 .getClosureToClassMapping(methodElement.resolvedAst); | 1666 .getClosureToClassMapping(methodElement.resolvedAst); |
| 1657 assert(nestedClosureData != null); | 1667 assert(nestedClosureData != null); |
| 1658 assert(nestedClosureData.closureClassElement != null); | 1668 assert(nestedClosureData.closureClassElement != null); |
| 1659 ClosureClassElement closureClassElement = | 1669 ClosureClassElement closureClassElement = |
| 1660 nestedClosureData.closureClassElement; | 1670 nestedClosureData.closureClassElement; |
| 1661 FunctionElement callElement = nestedClosureData.callElement; | 1671 FunctionElement callElement = nestedClosureData.callElement; |
| 1662 // TODO(ahe): This should be registered in codegen, not here. | 1672 // TODO(ahe): This should be registered in codegen, not here. |
| 1663 // TODO(johnniwinther): Is [registerStaticUse] equivalent to | 1673 // TODO(johnniwinther): Is [registerStaticUse] equivalent to |
| 1664 // [addToWorkList]? | 1674 // [addToWorkList]? |
| 1665 registry?.registerStaticUse(new StaticUse.foreignUse(callElement)); | 1675 registry?.registerStaticUse(new StaticUse.foreignUse(callElement)); |
| 1666 | 1676 |
| 1667 List<HInstruction> capturedVariables = <HInstruction>[]; | 1677 List<HInstruction> capturedVariables = <HInstruction>[]; |
| 1668 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 1678 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
| 1669 Local capturedLocal = | 1679 Local capturedLocal = |
| 1670 nestedClosureData.getLocalVariableForClosureField(field); | 1680 nestedClosureData.getLocalVariableForClosureField(field); |
| 1671 assert(capturedLocal != null); | 1681 assert(capturedLocal != null); |
| 1672 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 1682 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 1673 }); | 1683 }); |
| 1674 | 1684 |
| 1675 TypeMask type = | 1685 TypeMask type = |
| 1676 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld); | 1686 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld); |
| 1677 // TODO(efortuna): Add source information here. | 1687 // TODO(efortuna): Add source information here. |
| 1678 push(new HCreate(closureClassElement, capturedVariables, type)); | 1688 push(new HCreate(closureClassElement, capturedVariables, type)); |
| 1679 | 1689 |
| 1680 registry?.registerInstantiatedClosure(methodElement); | 1690 registry?.registerInstantiatedClosure(methodElement); |
| 1681 } | 1691 } |
| 1682 | 1692 |
| 1693 @override |
| 1694 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { |
| 1695 assert(isReachable); |
| 1696 declaration.function.accept(this); |
| 1697 LocalFunctionElement localFunction = astAdapter.getElement( |
| 1698 declaration.function); |
| 1699 localsHandler.updateLocal(localFunction, pop()); |
| 1700 } |
| 1701 |
| 1702 @override |
| 1703 void visitFunctionExpression(ir.FunctionExpression funcExpression) { |
| 1704 funcExpression.function.accept(this); |
| 1705 } |
| 1706 |
| 1683 // TODO(het): Decide when to inline | 1707 // TODO(het): Decide when to inline |
| 1684 @override | 1708 @override |
| 1685 void visitMethodInvocation(ir.MethodInvocation invocation) { | 1709 void visitMethodInvocation(ir.MethodInvocation invocation) { |
| 1686 // Handle `x == null` specially. When these come from null-aware operators, | 1710 // Handle `x == null` specially. When these come from null-aware operators, |
| 1687 // there is no mapping in the astAdapter. | 1711 // there is no mapping in the astAdapter. |
| 1688 if (_handleEqualsNull(invocation)) return; | 1712 if (_handleEqualsNull(invocation)) return; |
| 1689 invocation.receiver.accept(this); | 1713 invocation.receiver.accept(this); |
| 1690 HInstruction receiver = pop(); | 1714 HInstruction receiver = pop(); |
| 1691 Selector selector = astAdapter.getSelector(invocation); | 1715 Selector selector = astAdapter.getSelector(invocation); |
| 1692 _pushDynamicInvocation( | 1716 _pushDynamicInvocation( |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1847 push(new HNot(popBoolified(), backend.boolType)); | 1871 push(new HNot(popBoolified(), backend.boolType)); |
| 1848 } | 1872 } |
| 1849 | 1873 |
| 1850 @override | 1874 @override |
| 1851 void visitStringConcatenation(ir.StringConcatenation stringConcat) { | 1875 void visitStringConcatenation(ir.StringConcatenation stringConcat) { |
| 1852 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); | 1876 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); |
| 1853 stringConcat.accept(stringBuilder); | 1877 stringConcat.accept(stringBuilder); |
| 1854 stack.add(stringBuilder.result); | 1878 stack.add(stringBuilder.result); |
| 1855 } | 1879 } |
| 1856 } | 1880 } |
| OLD | NEW |