| OLD | NEW |
| 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 library dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
| 6 | 6 |
| 7 import '../closure.dart' as closurelib; | 7 import '../closure.dart' as closurelib; |
| 8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| 11 import '../dart2jslib.dart'; | 11 import '../dart2jslib.dart'; |
| 12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
| 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX, | 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX, |
| 14 ConstructorBodyElementX, FunctionSignatureX; | 14 ConstructorBodyElementX, FunctionSignatureX; |
| 15 import '../io/source_information.dart'; | 15 import '../io/source_information.dart'; |
| 16 import '../js_backend/js_backend.dart' show JavaScriptBackend; | 16 import '../js_backend/js_backend.dart' show JavaScriptBackend; |
| 17 import '../resolution/semantic_visitor.dart'; | 17 import '../resolution/semantic_visitor.dart'; |
| 18 import '../resolution/operators.dart' as op; | 18 import '../resolution/operators.dart' as op; |
| 19 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; | 19 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; |
| 20 import '../tree/tree.dart' as ast; | 20 import '../tree/tree.dart' as ast; |
| 21 import '../universe/universe.dart' show SelectorKind, CallStructure; | 21 import '../universe/universe.dart' show SelectorKind, CallStructure; |
| 22 import 'cps_ir_nodes.dart' as ir; | 22 import 'cps_ir_nodes.dart' as ir; |
| 23 import 'cps_ir_builder.dart'; | 23 import 'cps_ir_builder.dart'; |
| 24 | 24 |
| 25 /** | 25 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); |
| 26 * This task iterates through all resolved elements and builds [ir.Node]s. The | 26 |
| 27 * nodes are stored in the [nodes] map and accessible through [hasIr] and | 27 /// This task provides the interface to build IR nodes from [ast.Node]s, which |
| 28 * [getIr]. | 28 /// is used from the [CpsFunctionCompiler] to generate code. |
| 29 * | 29 /// |
| 30 * The functionality of the IrNodes is added gradually, therefore elements might | 30 /// This class is mainly there to correctly measure how long building the IR |
| 31 * have an IR or not, depending on the language features that are used. For | 31 /// takes. |
| 32 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not | |
| 33 * used in the rest of the compilation. This is ensured by setting the element's | |
| 34 * cached tree to `null` and also breaking the token stream to crash future | |
| 35 * attempts to parse. | |
| 36 * | |
| 37 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are | |
| 38 * then translated into the SSA form for optimizations and code generation. | |
| 39 * Long-term, once the IR supports the full language, the backend can be | |
| 40 * re-implemented to work directly on the IR. | |
| 41 */ | |
| 42 class IrBuilderTask extends CompilerTask { | 32 class IrBuilderTask extends CompilerTask { |
| 43 final Map<Element, ir.FunctionDefinition> nodes = | |
| 44 <Element, ir.FunctionDefinition>{}; | |
| 45 final SourceInformationFactory sourceInformationFactory; | 33 final SourceInformationFactory sourceInformationFactory; |
| 46 | 34 |
| 47 String bailoutMessage = null; | 35 String bailoutMessage = null; |
| 48 | 36 |
| 49 IrBuilderTask(Compiler compiler, this.sourceInformationFactory) | 37 /// If not null, this function will be called with for each |
| 38 /// [ir.FunctionDefinition] node that has been built. |
| 39 IrBuilderCallback builderCallback; |
| 40 |
| 41 IrBuilderTask(Compiler compiler, this.sourceInformationFactory, |
| 42 [this.builderCallback]) |
| 50 : super(compiler); | 43 : super(compiler); |
| 51 | 44 |
| 52 String get name => 'IR builder'; | 45 String get name => 'IR builder'; |
| 53 | 46 |
| 54 bool hasIr(Element element) => nodes.containsKey(element.implementation); | 47 ir.FunctionDefinition buildNode(AstElement element) { |
| 48 return measure(() { |
| 49 bailoutMessage = null; |
| 55 | 50 |
| 56 ir.FunctionDefinition getIr(ExecutableElement element) { | 51 TreeElements elementsMapping = element.resolvedAst.elements; |
| 57 return nodes[element.implementation]; | 52 element = element.implementation; |
| 58 } | 53 return compiler.withCurrentElement(element, () { |
| 54 SourceInformationBuilder sourceInformationBuilder = |
| 55 sourceInformationFactory.forContext(element); |
| 59 | 56 |
| 60 ir.FunctionDefinition buildNode(AstElement element) { | 57 IrBuilderVisitor builder = |
| 61 return measure(() => _buildNode(element)); | 58 new JsIrBuilderVisitor( |
| 62 } | 59 elementsMapping, compiler, sourceInformationBuilder); |
| 63 | 60 ir.FunctionDefinition irNode = builder.buildExecutable(element); |
| 64 ir.FunctionDefinition _buildNode(AstElement element) { | 61 if (irNode == null) { |
| 65 bailoutMessage = null; | 62 bailoutMessage = builder.bailoutMessage; |
| 66 | 63 } else if (builderCallback != null) { |
| 67 TreeElements elementsMapping = element.resolvedAst.elements; | 64 builderCallback(element, irNode); |
| 68 element = element.implementation; | 65 } |
| 69 return compiler.withCurrentElement(element, () { | 66 return irNode; |
| 70 SourceInformationBuilder sourceInformationBuilder = | 67 }); |
| 71 sourceInformationFactory.forContext(element); | |
| 72 | |
| 73 IrBuilderVisitor builder = | |
| 74 new JsIrBuilderVisitor( | |
| 75 elementsMapping, compiler, sourceInformationBuilder); | |
| 76 ir.FunctionDefinition irNode = builder.buildExecutable(element); | |
| 77 if (irNode == null) { | |
| 78 bailoutMessage = builder.bailoutMessage; | |
| 79 } else { | |
| 80 nodes[element] = irNode; | |
| 81 } | |
| 82 return irNode; | |
| 83 }); | 68 }); |
| 84 } | 69 } |
| 85 | |
| 86 void buildNodes() { | |
| 87 measure(() { | |
| 88 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements; | |
| 89 resolved.forEach(buildNode); | |
| 90 }); | |
| 91 } | |
| 92 | |
| 93 bool get inCheckedMode { | |
| 94 bool result = false; | |
| 95 assert((result = true)); | |
| 96 return result; | |
| 97 } | |
| 98 | |
| 99 } | 70 } |
| 100 | 71 |
| 101 /** | 72 |
| 102 * A tree visitor that builds [IrNodes]. The visit methods add statements using | 73 /// A tree visitor that builds [ir.Node]s. |
| 103 * to the [builder] and return the last added statement for trees that represent | 74 /// |
| 104 * an expression. | 75 /// The visit methods add statements using the [irBuilder] and return the last |
| 105 */ | 76 /// added statement for trees that represent expressions. |
| 77 /// |
| 106 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. | 78 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. |
| 107 abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> | 79 abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| 108 with IrBuilderMixin<ast.Node>, | 80 with IrBuilderMixin<ast.Node>, |
| 109 SemanticSendResolvedMixin<ir.Primitive, dynamic>, | 81 SemanticSendResolvedMixin<ir.Primitive, dynamic>, |
| 110 SendResolverMixin, | 82 SendResolverMixin, |
| 111 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, | 83 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
| 112 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, | 84 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
| 113 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 85 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
| 114 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 86 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
| 115 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 87 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
| (...skipping 2771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2887 node.body = replacementFor(node.body); | 2859 node.body = replacementFor(node.body); |
| 2888 } | 2860 } |
| 2889 } | 2861 } |
| 2890 | 2862 |
| 2891 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2863 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 2892 class RemovalVisitor extends ir.RecursiveVisitor { | 2864 class RemovalVisitor extends ir.RecursiveVisitor { |
| 2893 processReference(ir.Reference reference) { | 2865 processReference(ir.Reference reference) { |
| 2894 reference.unlink(); | 2866 reference.unlink(); |
| 2895 } | 2867 } |
| 2896 } | 2868 } |
| OLD | NEW |