Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart

Issue 759193005: Add support for fields to the new dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 part of dart2js.ir_builder; 5 part of dart2js.ir_builder;
6 6
7 /** 7 /**
8 * This task iterates through all resolved elements and builds [ir.Node]s. The 8 * This task iterates through all resolved elements and builds [ir.Node]s. The
9 * nodes are stored in the [nodes] map and accessible through [hasIr] and 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and
10 * [getIr]. 10 * [getIr].
11 * 11 *
12 * The functionality of the IrNodes is added gradually, therefore elements might 12 * The functionality of the IrNodes is added gradually, therefore elements might
13 * have an IR or not, depending on the language features that are used. For 13 * have an IR or not, depending on the language features that are used. For
14 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not 14 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not
15 * used in the rest of the compilation. This is ensured by setting the element's 15 * used in the rest of the compilation. This is ensured by setting the element's
16 * cached tree to `null` and also breaking the token stream to crash future 16 * cached tree to `null` and also breaking the token stream to crash future
17 * attempts to parse. 17 * attempts to parse.
18 * 18 *
19 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are 19 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are
20 * then translated into the SSA form for optimizations and code generation. 20 * then translated into the SSA form for optimizations and code generation.
21 * Long-term, once the IR supports the full language, the backend can be 21 * Long-term, once the IR supports the full language, the backend can be
22 * re-implemented to work directly on the IR. 22 * re-implemented to work directly on the IR.
23 */ 23 */
24 class IrBuilderTask extends CompilerTask { 24 class IrBuilderTask extends CompilerTask {
25 final Map<Element, ir.FunctionDefinition> nodes = 25 final Map<Element, ir.ExecutableDefinition> nodes =
26 <Element, ir.FunctionDefinition>{}; 26 <Element, ir.ExecutableDefinition>{};
27 27
28 IrBuilderTask(Compiler compiler) : super(compiler); 28 IrBuilderTask(Compiler compiler) : super(compiler);
29 29
30 String get name => 'IR builder'; 30 String get name => 'IR builder';
31 31
32 bool hasIr(Element element) => nodes.containsKey(element.implementation); 32 bool hasIr(Element element) => nodes.containsKey(element.implementation);
33 33
34 ir.FunctionDefinition getIr(Element element) => nodes[element.implementation]; 34 ir.ExecutableDefinition getIr(ExecutableElement element) {
35 return nodes[element.implementation];
36 }
35 37
36 ir.FunctionDefinition buildNode(AstElement element) { 38 ir.ExecutableDefinition buildNode(AstElement element) {
37 if (!canBuild(element)) return null; 39 if (!canBuild(element)) return null;
38 TreeElements elementsMapping = element.resolvedAst.elements; 40 TreeElements elementsMapping = element.resolvedAst.elements;
39 element = element.implementation; 41 element = element.implementation;
40 return compiler.withCurrentElement(element, () { 42 return compiler.withCurrentElement(element, () {
41 SourceFile sourceFile = elementSourceFile(element); 43 SourceFile sourceFile = elementSourceFile(element);
42 IrBuilderVisitor builder = 44 IrBuilderVisitor builder =
43 new IrBuilderVisitor(elementsMapping, compiler, sourceFile); 45 new IrBuilderVisitor(elementsMapping, compiler, sourceFile);
44 return builder.buildFunction(element); 46 return builder.buildExecutable(element);
45 }); 47 });
46 } 48 }
47 49
48 void buildNodes() { 50 void buildNodes() {
49 measure(() { 51 measure(() {
50 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements; 52 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements;
51 resolved.forEach((AstElement element) { 53 resolved.forEach((AstElement element) {
52 ir.FunctionDefinition functionDefinition = buildNode(element); 54 ir.ExecutableDefinition definition = buildNode(element);
53 if (functionDefinition != null) { 55 if (definition != null) {
54 nodes[element] = functionDefinition; 56 nodes[element] = definition;
55 } 57 }
56 }); 58 });
57 }); 59 });
58 } 60 }
59 61
62 bool canBuild(Element element) {
63 if (element is TypedefElement) return false;
64 if (element is FunctionElement) {
65 // TODO(sigurdm): Support native functions for dart2js.
66 assert(invariant(element, !element.isNative));
60 67
61 bool canBuild(Element element) { 68 // TODO(kmillikin,sigurdm): Support constructors.
62 FunctionElement function = element.asFunctionElement(); 69 if (element is ConstructorElement) return false;
63 // TODO(kmillikin,sigurdm): support lazy field initializers.
64 if (function == null) return false;
65 70
66 if (!compiler.backend.shouldOutput(function)) return false; 71 } else if (element is! FieldElement) {
67 72 compiler.internalError(element, "Unexpected elementtype $element");
68 assert(invariant(element, !function.isNative)); 73 }
69 74 return compiler.backend.shouldOutput(element);
70 // TODO(kmillikin,sigurdm): Support constructors.
71 if (function is ConstructorElement) return false;
72
73 return true;
74 } 75 }
75 76
76 bool get inCheckedMode { 77 bool get inCheckedMode {
77 bool result = false; 78 bool result = false;
78 assert((result = true)); 79 assert((result = true));
79 return result; 80 return result;
80 } 81 }
81 82
82 SourceFile elementSourceFile(Element element) { 83 SourceFile elementSourceFile(Element element) {
83 if (element is FunctionElement) { 84 if (element is FunctionElement) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // assigned in the delimited subexpression to their reaching definition --- 123 // assigned in the delimited subexpression to their reaching definition ---
123 // that is, the definition in effect at the hole in 'current'. These are 124 // that is, the definition in effect at the hole in 'current'. These are
124 // used to determine if a join-point continuation needs to be passed 125 // used to determine if a join-point continuation needs to be passed
125 // arguments, and what the arguments are. 126 // arguments, and what the arguments are.
126 127
127 /// Construct a top-level visitor. 128 /// Construct a top-level visitor.
128 IrBuilderVisitor(TreeElements elements, this.compiler, this.sourceFile) 129 IrBuilderVisitor(TreeElements elements, this.compiler, this.sourceFile)
129 : super(elements); 130 : super(elements);
130 131
131 /** 132 /**
132 * Builds the [ir.FunctionDefinition] for a function element. In case the 133 * Builds the [ir.ExecutableDefinition] for an executable element. In case the
133 * function uses features that cannot be expressed in the IR, this function 134 * function uses features that cannot be expressed in the IR, this element
134 * returns `null`. 135 * returns `null`.
135 */ 136 */
136 ir.FunctionDefinition buildFunction(FunctionElement functionElement) { 137 ir.ExecutableDefinition buildExecutable(ExecutableElement element) {
137 return nullIfGiveup(() => buildFunctionInternal(functionElement)); 138 return nullIfGiveup(() {
139 if (element is FieldElement) {
140 return buildField(element);
141 } else if (element is FunctionElement) {
142 return buildFunction(element);
143 } else {
144 compiler.internalError(element, "Unexpected element type $element");
145 }
146 });
138 } 147 }
139 148
140 ir.FunctionDefinition buildFunctionInternal(FunctionElement element) { 149 /// Returns a [ir.FieldDefinition] describing the initializer of [element].
150 /// Returns `null` if [element] has no initializer.
151 ir.FieldDefinition buildField(FieldElement element) {
152 assert(invariant(element, element.isImplementation));
153 ast.VariableDefinitions definitions = element.node;
154 ast.Node fieldDefinition =
155 definitions.definitions.nodes.first;
156 if (definitions.modifiers.isConst) {
157 // TODO(sigurdm): Just return const value.
158 }
159 assert(fieldDefinition != null);
160 assert(elements[fieldDefinition] != null);
161 // This means there is no initializer.
162 // TODO(sigurdm): Avoid ever getting here. Abstract functions and fields
163 // with no initializer should not have a representation in the IR.
164 if (fieldDefinition is! ast.SendSet) return null;
165 DetectClosureVariables closureLocals =
166 new DetectClosureVariables(elements);
167 closureLocals.visit(fieldDefinition);
168
169 IrBuilder builder = new IrBuilder(compiler.backend.constantSystem,
170 element,
171 closureLocals.usedFromClosure);
172 return withBuilder(builder, () {
173 ast.SendSet sendSet = fieldDefinition;
174 ir.Primitive result = visit(sendSet.arguments.first);
175 builder.buildReturn(result);
176 return builder.makeFieldDefinition();
177 });
178 }
179
180 ir.FunctionDefinition buildFunction(FunctionElement element) {
141 assert(invariant(element, element.isImplementation)); 181 assert(invariant(element, element.isImplementation));
142 ast.FunctionExpression function = element.node; 182 ast.FunctionExpression function = element.node;
143 assert(function != null); 183 assert(function != null);
144 assert(elements[function] != null); 184 assert(elements[function] != null);
145 185
146 DetectClosureVariables closureLocals = new DetectClosureVariables(elements); 186 DetectClosureVariables closureLocals = new DetectClosureVariables(elements);
147 closureLocals.visit(function); 187 closureLocals.visit(function);
148 188
149 return withBuilder( 189 return withBuilder(
150 new IrBuilder(compiler.backend.constantSystem, 190 new IrBuilder(compiler.backend.constantSystem,
151 element, closureLocals.usedFromClosure), 191 element, closureLocals.usedFromClosure),
152 () { 192 () {
153 FunctionSignature signature = element.functionSignature; 193 FunctionSignature signature = element.functionSignature;
154 signature.orderedForEachParameter((ParameterElement parameterElement) { 194 signature.orderedForEachParameter((ParameterElement parameterElement) {
155 irBuilder.createParameter(parameterElement); 195 irBuilder.createParameter(parameterElement);
156 }); 196 });
157 197
158 List<ConstantExpression> defaults = new List<ConstantExpression>(); 198 List<ConstantExpression> defaults = new List<ConstantExpression>();
159 signature.orderedOptionalParameters.forEach((ParameterElement element) { 199 signature.orderedOptionalParameters.forEach((ParameterElement element) {
160 defaults.add(getConstantForVariable(element)); 200 defaults.add(getConstantForVariable(element));
161 }); 201 });
162 202
163 visit(function.body); 203 visit(function.body);
164 return irBuilder.buildFunctionDefinition(element, defaults); 204 return irBuilder.buildFunctionDefinition(defaults);
165 }); 205 });
166 } 206 }
167 207
168 ir.Primitive visit(ast.Node node) => node.accept(this); 208 ir.Primitive visit(ast.Node node) => node.accept(this);
169 209
170 // ==== Statements ==== 210 // ==== Statements ====
171 visitBlock(ast.Block node) { 211 visitBlock(ast.Block node) {
172 irBuilder.buildBlock(node.statements.nodes, build); 212 irBuilder.buildBlock(node.statements.nodes, build);
173 } 213 }
174 214
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 839
800 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) { 840 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) {
801 assert(irBuilder.isOpen); 841 assert(irBuilder.isOpen);
802 if (constant == null) { 842 if (constant == null) {
803 constant = getConstantForNode(node); 843 constant = getConstantForNode(node);
804 } 844 }
805 return irBuilder.buildConstantLiteral(constant); 845 return irBuilder.buildConstantLiteral(constant);
806 } 846 }
807 847
808 ir.FunctionDefinition makeSubFunction(ast.FunctionExpression node) { 848 ir.FunctionDefinition makeSubFunction(ast.FunctionExpression node) {
809 return buildFunctionInternal(elements[node]); 849 return buildFunction(elements[node]);
810 } 850 }
811 851
812 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { 852 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
813 return irBuilder.buildFunctionExpression(makeSubFunction(node)); 853 return irBuilder.buildFunctionExpression(makeSubFunction(node));
814 } 854 }
815 855
816 visitFunctionDeclaration(ast.FunctionDeclaration node) { 856 visitFunctionDeclaration(ast.FunctionDeclaration node) {
817 LocalFunctionElement element = elements[node.function]; 857 LocalFunctionElement element = elements[node.function];
818 ir.FunctionDefinition inner = makeSubFunction(node.function); 858 ir.FunctionDefinition inner = makeSubFunction(node.function);
819 irBuilder.declareLocalFunction(element, inner); 859 irBuilder.declareLocalFunction(element, inner);
820 } 860 }
821 861
822 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 862 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
823 863
824 dynamic giveup(ast.Node node, [String reason]) { 864 dynamic giveup(ast.Node node, [String reason]) {
825 throw ABORT_IRNODE_BUILDER; 865 throw ABORT_IRNODE_BUILDER;
826 } 866 }
827 867
828 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 868 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) {
829 try { 869 try {
830 return action(); 870 return action();
831 } catch(e, tr) { 871 } catch(e, tr) {
832 if (e == ABORT_IRNODE_BUILDER) { 872 if (e == ABORT_IRNODE_BUILDER) {
833 return null; 873 return null;
834 } 874 }
835 rethrow; 875 rethrow;
836 } 876 }
837 } 877 }
838 878
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 node.visitChildren(this); 915 node.visitChildren(this);
876 } 916 }
877 917
878 visitFunctionExpression(ast.FunctionExpression node) { 918 visitFunctionExpression(ast.FunctionExpression node) {
879 FunctionElement oldFunction = currentFunction; 919 FunctionElement oldFunction = currentFunction;
880 currentFunction = elements[node]; 920 currentFunction = elements[node];
881 visit(node.body); 921 visit(node.body);
882 currentFunction = oldFunction; 922 currentFunction = oldFunction;
883 } 923 }
884 } 924 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698