| 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_file.dart'; | |
| 16 import '../io/source_information.dart'; | 15 import '../io/source_information.dart'; |
| 17 import '../js_backend/js_backend.dart' show JavaScriptBackend; | 16 import '../js_backend/js_backend.dart' show JavaScriptBackend; |
| 18 import '../resolution/semantic_visitor.dart'; | 17 import '../resolution/semantic_visitor.dart'; |
| 19 import '../resolution/operators.dart' as op; | 18 import '../resolution/operators.dart' as op; |
| 20 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; | 19 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; |
| 21 import '../tree/tree.dart' as ast; | 20 import '../tree/tree.dart' as ast; |
| 22 import '../universe/universe.dart' show SelectorKind, CallStructure; | 21 import '../universe/universe.dart' show SelectorKind, CallStructure; |
| 23 import 'cps_ir_nodes.dart' as ir; | 22 import 'cps_ir_nodes.dart' as ir; |
| 24 import 'cps_ir_builder.dart'; | 23 import 'cps_ir_builder.dart'; |
| 25 | 24 |
| 26 /** | 25 /** |
| 27 * This task iterates through all resolved elements and builds [ir.Node]s. The | 26 * This task iterates through all resolved elements and builds [ir.Node]s. The |
| 28 * nodes are stored in the [nodes] map and accessible through [hasIr] and | 27 * nodes are stored in the [nodes] map and accessible through [hasIr] and |
| 29 * [getIr]. | 28 * [getIr]. |
| 30 * | 29 * |
| 31 * The functionality of the IrNodes is added gradually, therefore elements might | 30 * The functionality of the IrNodes is added gradually, therefore elements might |
| 32 * have an IR or not, depending on the language features that are used. For | 31 * have an IR or not, depending on the language features that are used. For |
| 33 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not | 32 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not |
| 34 * used in the rest of the compilation. This is ensured by setting the element's | 33 * used in the rest of the compilation. This is ensured by setting the element's |
| 35 * cached tree to `null` and also breaking the token stream to crash future | 34 * cached tree to `null` and also breaking the token stream to crash future |
| 36 * attempts to parse. | 35 * attempts to parse. |
| 37 * | 36 * |
| 38 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are | 37 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are |
| 39 * then translated into the SSA form for optimizations and code generation. | 38 * then translated into the SSA form for optimizations and code generation. |
| 40 * Long-term, once the IR supports the full language, the backend can be | 39 * Long-term, once the IR supports the full language, the backend can be |
| 41 * re-implemented to work directly on the IR. | 40 * re-implemented to work directly on the IR. |
| 42 */ | 41 */ |
| 43 class IrBuilderTask extends CompilerTask { | 42 class IrBuilderTask extends CompilerTask { |
| 44 final Map<Element, ir.RootNode> nodes = <Element, ir.RootNode>{}; | 43 final Map<Element, ir.RootNode> nodes = <Element, ir.RootNode>{}; |
| 45 final bool generateSourceMap; | 44 final SourceInformationFactory sourceInformationFactory; |
| 46 | 45 |
| 47 String bailoutMessage = null; | 46 String bailoutMessage = null; |
| 48 | 47 |
| 49 IrBuilderTask(Compiler compiler, {this.generateSourceMap: true}) | 48 IrBuilderTask(Compiler compiler, this.sourceInformationFactory) |
| 50 : super(compiler); | 49 : super(compiler); |
| 51 | 50 |
| 52 String get name => 'IR builder'; | 51 String get name => 'IR builder'; |
| 53 | 52 |
| 54 bool hasIr(Element element) => nodes.containsKey(element.implementation); | 53 bool hasIr(Element element) => nodes.containsKey(element.implementation); |
| 55 | 54 |
| 56 ir.RootNode getIr(ExecutableElement element) { | 55 ir.RootNode getIr(ExecutableElement element) { |
| 57 return nodes[element.implementation]; | 56 return nodes[element.implementation]; |
| 58 } | 57 } |
| 59 | 58 |
| 60 ir.RootNode buildNode(AstElement element) { | 59 ir.RootNode buildNode(AstElement element) { |
| 61 bailoutMessage = null; | 60 bailoutMessage = null; |
| 62 if (!canBuild(element)) { | 61 if (!canBuild(element)) { |
| 63 bailoutMessage = 'unsupported element ${element.name}:${element.kind}'; | 62 bailoutMessage = 'unsupported element ${element.name}:${element.kind}'; |
| 64 return null; | 63 return null; |
| 65 } | 64 } |
| 66 | 65 |
| 67 TreeElements elementsMapping = element.resolvedAst.elements; | 66 TreeElements elementsMapping = element.resolvedAst.elements; |
| 68 element = element.implementation; | 67 element = element.implementation; |
| 69 return compiler.withCurrentElement(element, () { | 68 return compiler.withCurrentElement(element, () { |
| 70 SourceInformationBuilder sourceInformationBuilder = generateSourceMap | 69 SourceInformationBuilder sourceInformationBuilder = |
| 71 ? new PositionSourceInformationBuilder(element) | 70 sourceInformationFactory.forContext(element); |
| 72 : const SourceInformationBuilder(); | |
| 73 | 71 |
| 74 IrBuilderVisitor builder = | 72 IrBuilderVisitor builder = |
| 75 compiler.backend is JavaScriptBackend | 73 compiler.backend is JavaScriptBackend |
| 76 ? new JsIrBuilderVisitor( | 74 ? new JsIrBuilderVisitor( |
| 77 elementsMapping, compiler, sourceInformationBuilder) | 75 elementsMapping, compiler, sourceInformationBuilder) |
| 78 : new DartIrBuilderVisitor( | 76 : new DartIrBuilderVisitor( |
| 79 elementsMapping, compiler, sourceInformationBuilder); | 77 elementsMapping, compiler, sourceInformationBuilder); |
| 80 ir.RootNode irNode = builder.buildExecutable(element); | 78 ir.RootNode irNode = builder.buildExecutable(element); |
| 81 if (irNode == null) { | 79 if (irNode == null) { |
| 82 bailoutMessage = builder.bailoutMessage; | 80 bailoutMessage = builder.bailoutMessage; |
| (...skipping 2671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 arguments = normalizeStaticArguments( | 2752 arguments = normalizeStaticArguments( |
| 2755 callStructure, constructor, arguments); | 2753 callStructure, constructor, arguments); |
| 2756 return irBuilder.buildConstructorInvocation( | 2754 return irBuilder.buildConstructorInvocation( |
| 2757 constructor.effectiveTarget, | 2755 constructor.effectiveTarget, |
| 2758 callStructure, | 2756 callStructure, |
| 2759 constructor.computeEffectiveTargetType(type), | 2757 constructor.computeEffectiveTargetType(type), |
| 2760 arguments); | 2758 arguments); |
| 2761 } | 2759 } |
| 2762 } | 2760 } |
| 2763 | 2761 |
| 2764 /// Interface for generating [SourceInformation] for the CPS. | |
| 2765 class SourceInformationBuilder { | |
| 2766 const SourceInformationBuilder(); | |
| 2767 | |
| 2768 /// Create a [SourceInformationBuilder] for [element]. | |
| 2769 SourceInformationBuilder forContext(AstElement element) => this; | |
| 2770 | |
| 2771 /// Generate [SourceInformation] for the read access in [node]. | |
| 2772 SourceInformation buildGet(ast.Node node) => null; | |
| 2773 | |
| 2774 /// Generate [SourceInformation] for the invocation in [node]. | |
| 2775 SourceInformation buildCall(ast.Node node) => null; | |
| 2776 } | |
| 2777 | |
| 2778 /// [SourceInformationBuilder] that generates [PositionSourceInformation]. | |
| 2779 class PositionSourceInformationBuilder implements SourceInformationBuilder { | |
| 2780 final SourceFile sourceFile; | |
| 2781 final String name; | |
| 2782 | |
| 2783 PositionSourceInformationBuilder(AstElement element) | |
| 2784 : sourceFile = element.compilationUnit.script.file, | |
| 2785 name = element.name; | |
| 2786 | |
| 2787 @override | |
| 2788 SourceInformation buildGet(ast.Node node) { | |
| 2789 return new PositionSourceInformation( | |
| 2790 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | |
| 2791 } | |
| 2792 | |
| 2793 @override | |
| 2794 SourceInformation buildCall(ast.Node node) { | |
| 2795 return new PositionSourceInformation( | |
| 2796 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | |
| 2797 } | |
| 2798 | |
| 2799 @override | |
| 2800 SourceInformationBuilder forContext(AstElement element) { | |
| 2801 return new PositionSourceInformationBuilder(element); | |
| 2802 } | |
| 2803 } | |
| 2804 | |
| 2805 /// Perform simple post-processing on the initial CPS-translated root term. | 2762 /// Perform simple post-processing on the initial CPS-translated root term. |
| 2806 /// | 2763 /// |
| 2807 /// This pass performs backend-independent post-processing on the translated | 2764 /// This pass performs backend-independent post-processing on the translated |
| 2808 /// term. It is implemented separately from the optimization passes because | 2765 /// term. It is implemented separately from the optimization passes because |
| 2809 /// it is required for correctness of the implementation. | 2766 /// it is required for correctness of the implementation. |
| 2810 /// | 2767 /// |
| 2811 /// It performs the following translations: | 2768 /// It performs the following translations: |
| 2812 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw] | 2769 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw] |
| 2813 /// expression. | 2770 /// expression. |
| 2814 class CleanupPass extends ir.RecursiveVisitor { | 2771 class CleanupPass extends ir.RecursiveVisitor { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 node.body = replacementFor(node.body); | 2818 node.body = replacementFor(node.body); |
| 2862 } | 2819 } |
| 2863 } | 2820 } |
| 2864 | 2821 |
| 2865 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2822 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 2866 class RemovalVisitor extends ir.RecursiveVisitor { | 2823 class RemovalVisitor extends ir.RecursiveVisitor { |
| 2867 processReference(ir.Reference reference) { | 2824 processReference(ir.Reference reference) { |
| 2868 reference.unlink(); | 2825 reference.unlink(); |
| 2869 } | 2826 } |
| 2870 } | 2827 } |
| 2871 | |
| OLD | NEW |