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

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: 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 Selector selector, 188 Selector selector,
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 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 arguments.add(visitLiteralString(part.string)); 1735 arguments.add(visitLiteralString(part.string));
1738 } 1736 }
1739 return irBuilder.buildStringConcatenation(arguments); 1737 return irBuilder.buildStringConcatenation(arguments);
1740 } 1738 }
1741 1739
1742 ir.Primitive translateConstant(ast.Node node) { 1740 ir.Primitive translateConstant(ast.Node node) {
1743 assert(irBuilder.isOpen); 1741 assert(irBuilder.isOpen);
1744 return irBuilder.buildConstantLiteral(getConstantForNode(node)); 1742 return irBuilder.buildConstantLiteral(getConstantForNode(node));
1745 } 1743 }
1746 1744
1747 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { 1745 ir.RootNode nullIfGiveup(ir.RootNode action()) {
1748 try { 1746 try {
1749 return action(); 1747 return action();
1750 } catch(e, tr) { 1748 } catch(e, tr) {
1751 if (e == ABORT_IRNODE_BUILDER) { 1749 if (e == ABORT_IRNODE_BUILDER) {
1752 return null; 1750 return null;
1753 } 1751 }
1754 rethrow; 1752 rethrow;
1755 } 1753 }
1756 } 1754 }
1757 1755
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 1945
1948 visitFunctionDeclaration(ast.FunctionDeclaration node) { 1946 visitFunctionDeclaration(ast.FunctionDeclaration node) {
1949 LocalFunctionElement element = elements[node.function]; 1947 LocalFunctionElement element = elements[node.function];
1950 Object inner = makeSubFunction(node.function); 1948 Object inner = makeSubFunction(node.function);
1951 irBuilder.declareLocalFunction(element, inner); 1949 irBuilder.declareLocalFunction(element, inner);
1952 } 1950 }
1953 1951
1954 ClosureScope getClosureScopeForNode(ast.Node node) => null; 1952 ClosureScope getClosureScopeForNode(ast.Node node) => null;
1955 ClosureEnvironment getClosureEnvironment() => null; 1953 ClosureEnvironment getClosureEnvironment() => null;
1956 1954
1957 ir.ExecutableDefinition buildExecutable(ExecutableElement element) { 1955 ir.RootNode buildExecutable(ExecutableElement element) {
1958 return nullIfGiveup(() { 1956 return nullIfGiveup(() {
1959 if (element is FieldElement) { 1957 if (element is FieldElement) {
1960 return buildField(element); 1958 return buildField(element);
1961 } else if (element is FunctionElement) { 1959 } else if (element is FunctionElement || element is ConstructorElement) {
1962 return buildFunction(element); 1960 return buildFunction(element);
1963 } else { 1961 } else {
1964 compiler.internalError(element, "Unexpected element type $element"); 1962 compiler.internalError(element, "Unexpected element type $element");
1965 } 1963 }
1966 }); 1964 });
1967 } 1965 }
1968 1966
1969 /// Returns a [ir.FieldDefinition] describing the initializer of [element]. 1967 /// Returns a [ir.FieldDefinition] describing the initializer of [element].
1970 ir.FieldDefinition buildField(FieldElement element) { 1968 ir.FieldDefinition buildField(FieldElement element) {
1971 assert(invariant(element, element.isImplementation)); 1969 assert(invariant(element, element.isImplementation));
(...skipping 12 matching lines...) Expand all
1984 closureScope: getClosureScopeForNode(fieldDefinition)); 1982 closureScope: getClosureScopeForNode(fieldDefinition));
1985 ir.Primitive initializer; 1983 ir.Primitive initializer;
1986 if (fieldDefinition is ast.SendSet) { 1984 if (fieldDefinition is ast.SendSet) {
1987 ast.SendSet sendSet = fieldDefinition; 1985 ast.SendSet sendSet = fieldDefinition;
1988 initializer = visit(sendSet.arguments.first); 1986 initializer = visit(sendSet.arguments.first);
1989 } 1987 }
1990 return builder.makeFieldDefinition(initializer); 1988 return builder.makeFieldDefinition(initializer);
1991 }); 1989 });
1992 } 1990 }
1993 1991
1994 ir.FunctionDefinition buildFunction(FunctionElement element) { 1992 ir.RootNode buildFunction(FunctionElement element) {
1995 assert(invariant(element, element.isImplementation)); 1993 assert(invariant(element, element.isImplementation));
1996 ast.FunctionExpression node = element.node; 1994 ast.FunctionExpression node = element.node;
1997 if (element.asyncMarker != AsyncMarker.SYNC) { 1995 if (element.asyncMarker != AsyncMarker.SYNC) {
1998 giveup(null, 'cannot handle async-await'); 1996 giveup(null, 'cannot handle async-await');
1999 } 1997 }
2000 1998
2001 if (!element.isSynthesized) { 1999 if (!element.isSynthesized) {
2002 assert(node != null); 2000 assert(node != null);
2003 assert(elements[node] != null); 2001 assert(elements[node] != null);
2004 } else { 2002 } else {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 function, 2143 function,
2146 function.node, 2144 function.node,
2147 elements); 2145 elements);
2148 closurelib.ClosureScope scope = map.capturingScopes[function.node]; 2146 closurelib.ClosureScope scope = map.capturingScopes[function.node];
2149 if (scope == null) return null; 2147 if (scope == null) return null;
2150 return new ClosureScope(scope.boxElement, 2148 return new ClosureScope(scope.boxElement,
2151 mapValues(scope.capturedVariables, getLocation), 2149 mapValues(scope.capturedVariables, getLocation),
2152 scope.boxedLoopVariables); 2150 scope.boxedLoopVariables);
2153 } 2151 }
2154 2152
2155 ir.ExecutableDefinition buildExecutable(ExecutableElement element) { 2153 ir.RootNode buildExecutable(ExecutableElement element) {
2156 return nullIfGiveup(() { 2154 return nullIfGiveup(() {
2157 switch (element.kind) { 2155 switch (element.kind) {
2158 case ElementKind.GENERATIVE_CONSTRUCTOR: 2156 case ElementKind.GENERATIVE_CONSTRUCTOR:
2159 return buildConstructor(element); 2157 return buildConstructor(element);
2160 2158
2161 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY: 2159 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
2162 return buildConstructorBody(element); 2160 return buildConstructorBody(element);
2163 2161
2164 case ElementKind.FUNCTION: 2162 case ElementKind.FUNCTION:
2165 case ElementKind.GETTER: 2163 case ElementKind.GETTER:
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
2654 SourceInformation buildCall(ast.Node node) { 2652 SourceInformation buildCall(ast.Node node) {
2655 return new PositionSourceInformation( 2653 return new PositionSourceInformation(
2656 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2654 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
2657 } 2655 }
2658 2656
2659 @override 2657 @override
2660 SourceInformationBuilder forContext(AstElement element) { 2658 SourceInformationBuilder forContext(AstElement element) {
2661 return new PositionSourceInformationBuilder(element); 2659 return new PositionSourceInformationBuilder(element);
2662 } 2660 }
2663 } 2661 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698