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 |