| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) | 50 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) |
| 51 : backend = backend, | 51 : backend = backend, |
| 52 super(backend.compiler.measurer); | 52 super(backend.compiler.measurer); |
| 53 | 53 |
| 54 HGraph build(CodegenWorkItem work) { | 54 HGraph build(CodegenWorkItem work) { |
| 55 return measure(() { | 55 return measure(() { |
| 56 AstElement element = work.element.implementation; | 56 AstElement element = work.element.implementation; |
| 57 Kernel kernel = backend.kernelTask.kernel; | 57 Kernel kernel = backend.kernelTask.kernel; |
| 58 KernelSsaBuilder builder = new KernelSsaBuilder(element, work.resolvedAst, | 58 KernelSsaBuilder builder = new KernelSsaBuilder(element, work.resolvedAst, |
| 59 backend.compiler, work.registry, sourceInformationFactory, kernel); | 59 backend.compiler, work.registry, sourceInformationFactory, kernel); |
| 60 return builder.build(); | 60 HGraph graph = builder.build(); |
| 61 |
| 62 if (backend.compiler.tracer.isEnabled) { |
| 63 String name; |
| 64 if (element.isClassMember) { |
| 65 String className = element.enclosingClass.name; |
| 66 String memberName = element.name; |
| 67 name = "$className.$memberName"; |
| 68 if (element.isGenerativeConstructorBody) { |
| 69 name = "$name (body)"; |
| 70 } |
| 71 } else { |
| 72 name = "${element.name}"; |
| 73 } |
| 74 backend.compiler.tracer.traceCompilation(name); |
| 75 backend.compiler.tracer.traceGraph('builder', graph); |
| 76 } |
| 77 |
| 78 return graph; |
| 61 }); | 79 }); |
| 62 } | 80 } |
| 63 } | 81 } |
| 64 | 82 |
| 65 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { | 83 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
| 66 ir.Node target; | 84 ir.Node target; |
| 67 final AstElement targetElement; | 85 final AstElement targetElement; |
| 68 final ResolvedAst resolvedAst; | 86 final ResolvedAst resolvedAst; |
| 69 final CodegenRegistry registry; | 87 final CodegenRegistry registry; |
| 70 | 88 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 81 // TODO(karlklose): consider removing this and keeping the (substituted) types | 99 // TODO(karlklose): consider removing this and keeping the (substituted) types |
| 82 // of the type variables in an environment (like the [LocalsHandler]). | 100 // of the type variables in an environment (like the [LocalsHandler]). |
| 83 final List<DartType> currentImplicitInstantiations = <DartType>[]; | 101 final List<DartType> currentImplicitInstantiations = <DartType>[]; |
| 84 | 102 |
| 85 @override | 103 @override |
| 86 JavaScriptBackend get backend => compiler.backend; | 104 JavaScriptBackend get backend => compiler.backend; |
| 87 | 105 |
| 88 @override | 106 @override |
| 89 TreeElements get elements => resolvedAst.elements; | 107 TreeElements get elements => resolvedAst.elements; |
| 90 | 108 |
| 91 | |
| 92 SourceInformationBuilder sourceInformationBuilder; | 109 SourceInformationBuilder sourceInformationBuilder; |
| 93 KernelAstAdapter astAdapter; | 110 KernelAstAdapter astAdapter; |
| 94 LoopHandler<ir.Node> loopHandler; | 111 LoopHandler<ir.Node> loopHandler; |
| 95 TypeBuilder typeBuilder; | 112 TypeBuilder typeBuilder; |
| 96 | 113 |
| 97 final Map<ir.VariableDeclaration, HInstruction> letBindings = | 114 final Map<ir.VariableDeclaration, HInstruction> letBindings = |
| 98 <ir.VariableDeclaration, HInstruction>{}; | 115 <ir.VariableDeclaration, HInstruction>{}; |
| 99 | 116 |
| 117 /// True if we are visiting the expression of a throw statement; we assume |
| 118 /// this is a slow path. |
| 119 bool _inExpressionOfThrow = false; |
| 120 |
| 100 KernelSsaBuilder( | 121 KernelSsaBuilder( |
| 101 this.targetElement, | 122 this.targetElement, |
| 102 this.resolvedAst, | 123 this.resolvedAst, |
| 103 Compiler compiler, | 124 Compiler compiler, |
| 104 this.registry, | 125 this.registry, |
| 105 SourceInformationStrategy sourceInformationFactory, | 126 SourceInformationStrategy sourceInformationFactory, |
| 106 Kernel kernel) { | 127 Kernel kernel) { |
| 107 this.compiler = compiler; | 128 this.compiler = compiler; |
| 108 this.loopHandler = new KernelLoopHandler(this); | 129 this.loopHandler = new KernelLoopHandler(this); |
| 109 typeBuilder = new TypeBuilder(this); | 130 typeBuilder = new TypeBuilder(this); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } | 467 } |
| 447 assert(!current.isClosed()); | 468 assert(!current.isClosed()); |
| 448 if (stack.isNotEmpty) { | 469 if (stack.isNotEmpty) { |
| 449 compiler.reporter | 470 compiler.reporter |
| 450 .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack'); | 471 .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack'); |
| 451 } | 472 } |
| 452 } | 473 } |
| 453 | 474 |
| 454 @override | 475 @override |
| 455 void visitExpressionStatement(ir.ExpressionStatement exprStatement) { | 476 void visitExpressionStatement(ir.ExpressionStatement exprStatement) { |
| 456 exprStatement.expression.accept(this); | 477 if (!isReachable) return; |
| 457 pop(); | 478 ir.Expression expression = exprStatement.expression; |
| 479 if (expression is ir.Throw) { |
| 480 // TODO(sra): Prevent generating a statement when inlining. |
| 481 _visitThrowExpression(expression.expression); |
| 482 closeAndGotoExit(new HThrow(pop(), null)); |
| 483 } else { |
| 484 expression.accept(this); |
| 485 pop(); |
| 486 } |
| 458 } | 487 } |
| 459 | 488 |
| 460 @override | 489 @override |
| 461 void visitReturnStatement(ir.ReturnStatement returnStatement) { | 490 void visitReturnStatement(ir.ReturnStatement returnStatement) { |
| 462 HInstruction value; | 491 HInstruction value; |
| 463 if (returnStatement.expression == null) { | 492 if (returnStatement.expression == null) { |
| 464 value = graph.addConstantNull(compiler); | 493 value = graph.addConstantNull(compiler); |
| 465 } else { | 494 } else { |
| 466 assert(_targetFunction != null && _targetFunction is ir.FunctionNode); | 495 assert(_targetFunction != null && _targetFunction is ir.FunctionNode); |
| 467 returnStatement.expression.accept(this); | 496 returnStatement.expression.accept(this); |
| 468 value = typeBuilder.potentiallyCheckOrTrustType(pop(), | 497 value = typeBuilder.potentiallyCheckOrTrustType( |
| 469 astAdapter.getFunctionReturnType(_targetFunction)); | 498 pop(), astAdapter.getFunctionReturnType(_targetFunction)); |
| 470 } | 499 } |
| 471 // TODO(het): Add source information | 500 // TODO(het): Add source information |
| 472 // TODO(het): Set a return value instead of closing the function when we | 501 // TODO(het): Set a return value instead of closing the function when we |
| 473 // support inlining. | 502 // support inlining. |
| 474 closeAndGotoExit(new HReturn(value, null)); | 503 closeAndGotoExit(new HReturn(value, null)); |
| 475 } | 504 } |
| 476 | 505 |
| 477 @override | 506 @override |
| 478 void visitForStatement(ir.ForStatement forStatement) { | 507 void visitForStatement(ir.ForStatement forStatement) { |
| 479 assert(isReachable); | 508 assert(isReachable); |
| (...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 // TODO(efortuna): Add source information here. | 1718 // TODO(efortuna): Add source information here. |
| 1690 push(new HCreate(closureClassElement, capturedVariables, type)); | 1719 push(new HCreate(closureClassElement, capturedVariables, type)); |
| 1691 | 1720 |
| 1692 registry?.registerInstantiatedClosure(methodElement); | 1721 registry?.registerInstantiatedClosure(methodElement); |
| 1693 } | 1722 } |
| 1694 | 1723 |
| 1695 @override | 1724 @override |
| 1696 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { | 1725 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { |
| 1697 assert(isReachable); | 1726 assert(isReachable); |
| 1698 declaration.function.accept(this); | 1727 declaration.function.accept(this); |
| 1699 LocalFunctionElement localFunction = astAdapter.getElement( | 1728 LocalFunctionElement localFunction = |
| 1700 declaration.function); | 1729 astAdapter.getElement(declaration.function); |
| 1701 localsHandler.updateLocal(localFunction, pop()); | 1730 localsHandler.updateLocal(localFunction, pop()); |
| 1702 } | 1731 } |
| 1703 | 1732 |
| 1704 @override | 1733 @override |
| 1705 void visitFunctionExpression(ir.FunctionExpression funcExpression) { | 1734 void visitFunctionExpression(ir.FunctionExpression funcExpression) { |
| 1706 funcExpression.function.accept(this); | 1735 funcExpression.function.accept(this); |
| 1707 } | 1736 } |
| 1708 | 1737 |
| 1709 // TODO(het): Decide when to inline | 1738 // TODO(het): Decide when to inline |
| 1710 @override | 1739 @override |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1847 } | 1876 } |
| 1848 | 1877 |
| 1849 // The interceptor is not always needed. It is removed by optimization | 1878 // The interceptor is not always needed. It is removed by optimization |
| 1850 // when the receiver type or tested type permit. | 1879 // when the receiver type or tested type permit. |
| 1851 HInterceptor interceptor = _interceptorFor(expression); | 1880 HInterceptor interceptor = _interceptorFor(expression); |
| 1852 push(new HIs.raw(type, expression, interceptor, backend.boolType)); | 1881 push(new HIs.raw(type, expression, interceptor, backend.boolType)); |
| 1853 } | 1882 } |
| 1854 | 1883 |
| 1855 @override | 1884 @override |
| 1856 void visitThrow(ir.Throw throwNode) { | 1885 void visitThrow(ir.Throw throwNode) { |
| 1857 throwNode.expression.accept(this); | 1886 _visitThrowExpression(throwNode.expression); |
| 1858 HInstruction expression = pop(); | |
| 1859 if (isReachable) { | 1887 if (isReachable) { |
| 1860 push(new HThrowExpression(expression, null)); | 1888 push(new HThrowExpression(pop(), null)); |
| 1861 isReachable = false; | 1889 isReachable = false; |
| 1862 } | 1890 } |
| 1863 } | 1891 } |
| 1864 | 1892 |
| 1893 void _visitThrowExpression(ir.Expression expression) { |
| 1894 bool old = _inExpressionOfThrow; |
| 1895 try { |
| 1896 _inExpressionOfThrow = true; |
| 1897 expression.accept(this); |
| 1898 } finally { |
| 1899 _inExpressionOfThrow = old; |
| 1900 } |
| 1901 } |
| 1902 |
| 1865 @override | 1903 @override |
| 1866 void visitThisExpression(ir.ThisExpression thisExpression) { | 1904 void visitThisExpression(ir.ThisExpression thisExpression) { |
| 1867 stack.add(localsHandler.readThis()); | 1905 stack.add(localsHandler.readThis()); |
| 1868 } | 1906 } |
| 1869 | 1907 |
| 1870 @override | 1908 @override |
| 1871 void visitNot(ir.Not not) { | 1909 void visitNot(ir.Not not) { |
| 1872 not.operand.accept(this); | 1910 not.operand.accept(this); |
| 1873 push(new HNot(popBoolified(), backend.boolType)); | 1911 push(new HNot(popBoolified(), backend.boolType)); |
| 1874 } | 1912 } |
| 1875 | 1913 |
| 1876 @override | 1914 @override |
| 1877 void visitStringConcatenation(ir.StringConcatenation stringConcat) { | 1915 void visitStringConcatenation(ir.StringConcatenation stringConcat) { |
| 1878 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); | 1916 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); |
| 1879 stringConcat.accept(stringBuilder); | 1917 stringConcat.accept(stringBuilder); |
| 1880 stack.add(stringBuilder.result); | 1918 stack.add(stringBuilder.result); |
| 1881 } | 1919 } |
| 1882 } | 1920 } |
| OLD | NEW |