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

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

Issue 1068243002: Overhaul tree IR visitor and rename IR classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add dummy use for RootVisitor and InitializerVisitor without arguments Created 5 years, 8 months 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 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';
(...skipping 23 matching lines...) Expand all
34 * used in the rest of the compilation. This is ensured by setting the element's 34 * 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 35 * cached tree to `null` and also breaking the token stream to crash future
36 * attempts to parse. 36 * attempts to parse.
37 * 37 *
38 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are 38 * 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. 39 * 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 40 * Long-term, once the IR supports the full language, the backend can be
41 * re-implemented to work directly on the IR. 41 * re-implemented to work directly on the IR.
42 */ 42 */
43 class IrBuilderTask extends CompilerTask { 43 class IrBuilderTask extends CompilerTask {
44 final Map<Element, ir.ExecutableDefinition> nodes = 44 final Map<Element, ir.RootNode> nodes = <Element, ir.RootNode>{};
45 <Element, ir.ExecutableDefinition>{};
46 final bool generateSourceMap; 45 final bool generateSourceMap;
47 46
48 IrBuilderTask(Compiler compiler, {this.generateSourceMap: true}) 47 IrBuilderTask(Compiler compiler, {this.generateSourceMap: true})
49 : super(compiler); 48 : super(compiler);
50 49
51 String get name => 'IR builder'; 50 String get name => 'IR builder';
52 51
53 bool hasIr(Element element) => nodes.containsKey(element.implementation); 52 bool hasIr(Element element) => nodes.containsKey(element.implementation);
54 53
55 ir.ExecutableDefinition getIr(ExecutableElement element) { 54 ir.RootNode getIr(ExecutableElement element) {
56 return nodes[element.implementation]; 55 return nodes[element.implementation];
57 } 56 }
58 57
59 ir.ExecutableDefinition buildNode(AstElement element) { 58 ir.RootNode buildNode(AstElement element) {
60 if (!canBuild(element)) return null; 59 if (!canBuild(element)) return null;
61 60
62 TreeElements elementsMapping = element.resolvedAst.elements; 61 TreeElements elementsMapping = element.resolvedAst.elements;
63 element = element.implementation; 62 element = element.implementation;
64 return compiler.withCurrentElement(element, () { 63 return compiler.withCurrentElement(element, () {
65 SourceInformationBuilder sourceInformationBuilder = generateSourceMap 64 SourceInformationBuilder sourceInformationBuilder = generateSourceMap
66 ? new PositionSourceInformationBuilder(element) 65 ? new PositionSourceInformationBuilder(element)
67 : const SourceInformationBuilder(); 66 : const SourceInformationBuilder();
68 67
69 IrBuilderVisitor builder = 68 IrBuilderVisitor builder =
70 compiler.backend is JavaScriptBackend 69 compiler.backend is JavaScriptBackend
71 ? new JsIrBuilderVisitor( 70 ? new JsIrBuilderVisitor(
72 elementsMapping, compiler, sourceInformationBuilder) 71 elementsMapping, compiler, sourceInformationBuilder)
73 : new DartIrBuilderVisitor( 72 : new DartIrBuilderVisitor(
74 elementsMapping, compiler, sourceInformationBuilder); 73 elementsMapping, compiler, sourceInformationBuilder);
75 ir.ExecutableDefinition definition = 74 ir.RootNode irNode = builder.buildExecutable(element);
76 builder.buildExecutable(element); 75 if (irNode != null) {
77 if (definition != null) { 76 nodes[element] = irNode;
78 nodes[element] = definition;
79 } 77 }
80 return definition; 78 return irNode;
81 }); 79 });
82 } 80 }
83 81
84 void buildNodes() { 82 void buildNodes() {
85 measure(() { 83 measure(() {
86 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements; 84 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements;
87 resolved.forEach(buildNode); 85 resolved.forEach(buildNode);
88 }); 86 });
89 } 87 }
90 88
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 @override 161 @override
164 bulkHandleNode(ast.Node node, String message, _) => giveup(node, message); 162 bulkHandleNode(ast.Node node, String message, _) => giveup(node, message);
165 163
166 @override 164 @override
167 ir.Primitive apply(ast.Node node, _) => node.accept(this); 165 ir.Primitive apply(ast.Node node, _) => node.accept(this);
168 166
169 @override 167 @override
170 SemanticSendVisitor get sendVisitor => this; 168 SemanticSendVisitor get sendVisitor => this;
171 169
172 /** 170 /**
173 * Builds the [ir.ExecutableDefinition] for an executable element. In case the 171 * Builds the [ir.RootNode] for an executable element. In case the
174 * function uses features that cannot be expressed in the IR, this element 172 * function uses features that cannot be expressed in the IR, this element
175 * returns `null`. 173 * returns `null`.
176 */ 174 */
177 ir.ExecutableDefinition buildExecutable(ExecutableElement element); 175 ir.RootNode buildExecutable(ExecutableElement element);
178 176
179 ClosureScope getClosureScopeForNode(ast.Node node); 177 ClosureScope getClosureScopeForNode(ast.Node node);
180 ClosureEnvironment getClosureEnvironment(); 178 ClosureEnvironment getClosureEnvironment();
181 179
182 /// Normalizes the argument list to a static invocation (i.e. where the target 180 /// Normalizes the argument list to a static invocation (i.e. where the target
183 /// element is known). 181 /// element is known).
184 /// 182 ///
185 /// For the JS backend, inserts default arguments and normalizes order of 183 /// For the JS backend, inserts default arguments and normalizes order of
186 /// named arguments. 184 /// named arguments.
187 /// 185 ///
188 /// For the Dart backend, returns [arguments]. 186 /// For the Dart backend, returns [arguments].
189 List<ir.Primitive> normalizeStaticArguments( 187 List<ir.Primitive> normalizeStaticArguments(
190 CallStructure callStructure, 188 CallStructure callStructure,
191 FunctionElement target, 189 FunctionElement target,
192 List<ir.Primitive> arguments); 190 List<ir.Primitive> arguments);
193 191
194 /// Normalizes the argument list of a dynamic invocation (i.e. where the 192 /// Normalizes the argument list of a dynamic invocation (i.e. where the
195 /// target element is unknown). 193 /// target element is unknown).
196 /// 194 ///
197 /// For the JS backend, normalizes order of named arguments. 195 /// For the JS backend, normalizes order of named arguments.
198 /// 196 ///
199 /// For the Dart backend, returns [arguments]. 197 /// For the Dart backend, returns [arguments].
200 List<ir.Primitive> normalizeDynamicArguments( 198 List<ir.Primitive> normalizeDynamicArguments(
201 Selector selector, 199 Selector selector,
202 List<ir.Primitive> arguments); 200 List<ir.Primitive> arguments);
203 201
204 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, 202 ir.RootNode _makeFunctionBody(FunctionElement element,
205 ast.FunctionExpression node) { 203 ast.FunctionExpression node) {
206 FunctionSignature signature = element.functionSignature; 204 FunctionSignature signature = element.functionSignature;
207 List<ParameterElement> parameters = []; 205 List<ParameterElement> parameters = [];
208 signature.orderedForEachParameter(parameters.add); 206 signature.orderedForEachParameter(parameters.add);
209 207
210 irBuilder.buildFunctionHeader(parameters, 208 irBuilder.buildFunctionHeader(parameters,
211 closureScope: getClosureScopeForNode(node), 209 closureScope: getClosureScopeForNode(node),
212 env: getClosureEnvironment()); 210 env: getClosureEnvironment());
213 211
214 List<ConstantExpression> defaults = new List<ConstantExpression>(); 212 List<ConstantExpression> defaults = new List<ConstantExpression>();
215 signature.orderedOptionalParameters.forEach((ParameterElement element) { 213 signature.orderedOptionalParameters.forEach((ParameterElement element) {
(...skipping 24 matching lines...) Expand all
240 List<ir.Initializer> result = <ir.Initializer>[]; 238 List<ir.Initializer> result = <ir.Initializer>[];
241 FunctionSignature signature = element.functionSignature; 239 FunctionSignature signature = element.functionSignature;
242 240
243 void tryAddInitializingFormal(ParameterElement parameterElement) { 241 void tryAddInitializingFormal(ParameterElement parameterElement) {
244 if (parameterElement.isInitializingFormal) { 242 if (parameterElement.isInitializingFormal) {
245 InitializingFormalElement initializingFormal = parameterElement; 243 InitializingFormalElement initializingFormal = parameterElement;
246 withBuilder(irBuilder.makeInitializerBuilder(), () { 244 withBuilder(irBuilder.makeInitializerBuilder(), () {
247 ir.Primitive value = irBuilder.buildLocalGet(parameterElement); 245 ir.Primitive value = irBuilder.buildLocalGet(parameterElement);
248 result.add(irBuilder.makeFieldInitializer( 246 result.add(irBuilder.makeFieldInitializer(
249 initializingFormal.fieldElement, 247 initializingFormal.fieldElement,
250 irBuilder.makeRunnableBody(value))); 248 irBuilder.makeBody(value)));
251 }); 249 });
252 } 250 }
253 } 251 }
254 252
255 // TODO(sigurdm): Preserve initializing formals as initializing formals. 253 // TODO(sigurdm): Preserve initializing formals as initializing formals.
256 signature.orderedForEachParameter(tryAddInitializingFormal); 254 signature.orderedForEachParameter(tryAddInitializingFormal);
257 255
258 if (function.initializers == null) return result; 256 if (function.initializers == null) return result;
259 bool explicitSuperInitializer = false; 257 bool explicitSuperInitializer = false;
260 for(ast.Node initializer in function.initializers) { 258 for(ast.Node initializer in function.initializers) {
261 if (initializer is ast.SendSet) { 259 if (initializer is ast.SendSet) {
262 // Field initializer. 260 // Field initializer.
263 FieldElement field = elements[initializer]; 261 FieldElement field = elements[initializer];
264 withBuilder(irBuilder.makeInitializerBuilder(), () { 262 withBuilder(irBuilder.makeInitializerBuilder(), () {
265 ir.Primitive value = visit(initializer.arguments.head); 263 ir.Primitive value = visit(initializer.arguments.head);
266 ir.RunnableBody body = irBuilder.makeRunnableBody(value); 264 ir.Body body = irBuilder.makeBody(value);
267 result.add(irBuilder.makeFieldInitializer(field, body)); 265 result.add(irBuilder.makeFieldInitializer(field, body));
268 }); 266 });
269 } else if (initializer is ast.Send) { 267 } else if (initializer is ast.Send) {
270 // Super or this initializer. 268 // Super or this initializer.
271 if (ast.Initializers.isConstructorRedirect(initializer)) { 269 if (ast.Initializers.isConstructorRedirect(initializer)) {
272 giveup(initializer, "constructor redirect (this) initializer"); 270 giveup(initializer, "constructor redirect (this) initializer");
273 } 271 }
274 ConstructorElement constructor = elements[initializer].implementation; 272 ConstructorElement constructor = elements[initializer].implementation;
275 Selector selector = elements.getSelector(initializer); 273 Selector selector = elements.getSelector(initializer);
276 List<ir.RunnableBody> arguments = 274 List<ir.Body> arguments =
277 initializer.arguments.mapToList((ast.Node argument) { 275 initializer.arguments.mapToList((ast.Node argument) {
278 return withBuilder(irBuilder.makeInitializerBuilder(), () { 276 return withBuilder(irBuilder.makeInitializerBuilder(), () {
279 ir.Primitive value = visit(argument); 277 ir.Primitive value = visit(argument);
280 return irBuilder.makeRunnableBody(value); 278 return irBuilder.makeBody(value);
281 }); 279 });
282 }); 280 });
283 result.add(irBuilder.makeSuperInitializer(constructor, 281 result.add(irBuilder.makeSuperInitializer(constructor,
284 arguments, 282 arguments,
285 selector)); 283 selector));
286 explicitSuperInitializer = true; 284 explicitSuperInitializer = true;
287 } else { 285 } else {
288 compiler.internalError(initializer, 286 compiler.internalError(initializer,
289 "Unexpected initializer type $initializer"); 287 "Unexpected initializer type $initializer");
290 } 288 }
291 289
292 } 290 }
293 if (!explicitSuperInitializer) { 291 if (!explicitSuperInitializer) {
294 // No super initializer found. Try to find the default constructor if 292 // No super initializer found. Try to find the default constructor if
295 // the class is not Object. 293 // the class is not Object.
296 ClassElement enclosingClass = element.enclosingClass; 294 ClassElement enclosingClass = element.enclosingClass;
297 if (!enclosingClass.isObject) { 295 if (!enclosingClass.isObject) {
298 ClassElement superClass = enclosingClass.superclass; 296 ClassElement superClass = enclosingClass.superclass;
299 FunctionElement target = superClass.lookupDefaultConstructor(); 297 FunctionElement target = superClass.lookupDefaultConstructor();
300 if (target == null) { 298 if (target == null) {
301 compiler.internalError(superClass, 299 compiler.internalError(superClass,
302 "No default constructor available."); 300 "No default constructor available.");
303 } 301 }
304 Selector selector = new Selector.callDefaultConstructor(); 302 Selector selector = new Selector.callDefaultConstructor();
305 result.add(irBuilder.makeSuperInitializer(target, 303 result.add(irBuilder.makeSuperInitializer(target,
306 <ir.RunnableBody>[], 304 <ir.Body>[],
307 selector)); 305 selector));
308 } 306 }
309 } 307 }
310 return result; 308 return result;
311 } 309 }
312 310
313 ir.Primitive visit(ast.Node node) => node.accept(this); 311 ir.Primitive visit(ast.Node node) => node.accept(this);
314 312
315 // ## Statements ## 313 // ## Statements ##
316 visitBlock(ast.Block node) { 314 visitBlock(ast.Block node) {
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 arguments.add(visitLiteralString(part.string)); 1740 arguments.add(visitLiteralString(part.string));
1743 } 1741 }
1744 return irBuilder.buildStringConcatenation(arguments); 1742 return irBuilder.buildStringConcatenation(arguments);
1745 } 1743 }
1746 1744
1747 ir.Primitive translateConstant(ast.Node node) { 1745 ir.Primitive translateConstant(ast.Node node) {
1748 assert(irBuilder.isOpen); 1746 assert(irBuilder.isOpen);
1749 return irBuilder.buildConstantLiteral(getConstantForNode(node)); 1747 return irBuilder.buildConstantLiteral(getConstantForNode(node));
1750 } 1748 }
1751 1749
1752 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { 1750 ir.RootNode nullIfGiveup(ir.RootNode action()) {
1753 try { 1751 try {
1754 return action(); 1752 return action();
1755 } catch(e, tr) { 1753 } catch(e, tr) {
1756 if (e == ABORT_IRNODE_BUILDER) { 1754 if (e == ABORT_IRNODE_BUILDER) {
1757 return null; 1755 return null;
1758 } 1756 }
1759 rethrow; 1757 rethrow;
1760 } 1758 }
1761 } 1759 }
1762 1760
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 1950
1953 visitFunctionDeclaration(ast.FunctionDeclaration node) { 1951 visitFunctionDeclaration(ast.FunctionDeclaration node) {
1954 LocalFunctionElement element = elements[node.function]; 1952 LocalFunctionElement element = elements[node.function];
1955 Object inner = makeSubFunction(node.function); 1953 Object inner = makeSubFunction(node.function);
1956 irBuilder.declareLocalFunction(element, inner); 1954 irBuilder.declareLocalFunction(element, inner);
1957 } 1955 }
1958 1956
1959 ClosureScope getClosureScopeForNode(ast.Node node) => null; 1957 ClosureScope getClosureScopeForNode(ast.Node node) => null;
1960 ClosureEnvironment getClosureEnvironment() => null; 1958 ClosureEnvironment getClosureEnvironment() => null;
1961 1959
1962 ir.ExecutableDefinition buildExecutable(ExecutableElement element) { 1960 ir.RootNode buildExecutable(ExecutableElement element) {
1963 return nullIfGiveup(() { 1961 return nullIfGiveup(() {
1964 if (element is FieldElement) { 1962 if (element is FieldElement) {
1965 return buildField(element); 1963 return buildField(element);
1966 } else if (element is FunctionElement) { 1964 } else if (element is FunctionElement || element is ConstructorElement) {
1967 return buildFunction(element); 1965 return buildFunction(element);
1968 } else { 1966 } else {
1969 compiler.internalError(element, "Unexpected element type $element"); 1967 compiler.internalError(element, "Unexpected element type $element");
1970 } 1968 }
1971 }); 1969 });
1972 } 1970 }
1973 1971
1974 /// Returns a [ir.FieldDefinition] describing the initializer of [element]. 1972 /// Returns a [ir.FieldDefinition] describing the initializer of [element].
1975 ir.FieldDefinition buildField(FieldElement element) { 1973 ir.FieldDefinition buildField(FieldElement element) {
1976 assert(invariant(element, element.isImplementation)); 1974 assert(invariant(element, element.isImplementation));
(...skipping 12 matching lines...) Expand all
1989 closureScope: getClosureScopeForNode(fieldDefinition)); 1987 closureScope: getClosureScopeForNode(fieldDefinition));
1990 ir.Primitive initializer; 1988 ir.Primitive initializer;
1991 if (fieldDefinition is ast.SendSet) { 1989 if (fieldDefinition is ast.SendSet) {
1992 ast.SendSet sendSet = fieldDefinition; 1990 ast.SendSet sendSet = fieldDefinition;
1993 initializer = visit(sendSet.arguments.first); 1991 initializer = visit(sendSet.arguments.first);
1994 } 1992 }
1995 return builder.makeFieldDefinition(initializer); 1993 return builder.makeFieldDefinition(initializer);
1996 }); 1994 });
1997 } 1995 }
1998 1996
1999 ir.FunctionDefinition buildFunction(FunctionElement element) { 1997 ir.RootNode buildFunction(FunctionElement element) {
2000 assert(invariant(element, element.isImplementation)); 1998 assert(invariant(element, element.isImplementation));
2001 ast.FunctionExpression node = element.node; 1999 ast.FunctionExpression node = element.node;
2002 if (element.asyncMarker != AsyncMarker.SYNC) { 2000 if (element.asyncMarker != AsyncMarker.SYNC) {
2003 giveup(null, 'cannot handle async-await'); 2001 giveup(null, 'cannot handle async-await');
2004 } 2002 }
2005 2003
2006 if (!element.isSynthesized) { 2004 if (!element.isSynthesized) {
2007 assert(node != null); 2005 assert(node != null);
2008 assert(elements[node] != null); 2006 assert(elements[node] != null);
2009 } else { 2007 } else {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2150 function, 2148 function,
2151 function.node, 2149 function.node,
2152 elements); 2150 elements);
2153 closurelib.ClosureScope scope = map.capturingScopes[function.node]; 2151 closurelib.ClosureScope scope = map.capturingScopes[function.node];
2154 if (scope == null) return null; 2152 if (scope == null) return null;
2155 return new ClosureScope(scope.boxElement, 2153 return new ClosureScope(scope.boxElement,
2156 mapValues(scope.capturedVariables, getLocation), 2154 mapValues(scope.capturedVariables, getLocation),
2157 scope.boxedLoopVariables); 2155 scope.boxedLoopVariables);
2158 } 2156 }
2159 2157
2160 ir.ExecutableDefinition buildExecutable(ExecutableElement element) { 2158 ir.RootNode buildExecutable(ExecutableElement element) {
2161 return nullIfGiveup(() { 2159 return nullIfGiveup(() {
2162 switch (element.kind) { 2160 switch (element.kind) {
2163 case ElementKind.GENERATIVE_CONSTRUCTOR: 2161 case ElementKind.GENERATIVE_CONSTRUCTOR:
2164 return buildConstructor(element); 2162 return buildConstructor(element);
2165 2163
2166 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY: 2164 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
2167 return buildConstructorBody(element); 2165 return buildConstructorBody(element);
2168 2166
2169 case ElementKind.FUNCTION: 2167 case ElementKind.FUNCTION:
2170 case ElementKind.GETTER: 2168 case ElementKind.GETTER:
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 SourceInformation buildCall(ast.Node node) { 2658 SourceInformation buildCall(ast.Node node) {
2661 return new PositionSourceInformation( 2659 return new PositionSourceInformation(
2662 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2660 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
2663 } 2661 }
2664 2662
2665 @override 2663 @override
2666 SourceInformationBuilder forContext(AstElement element) { 2664 SourceInformationBuilder forContext(AstElement element) {
2667 return new PositionSourceInformationBuilder(element); 2665 return new PositionSourceInformationBuilder(element);
2668 } 2666 }
2669 } 2667 }
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_integrity.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698