OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
7 import '../closure.dart'; | 7 import '../closure.dart'; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/codegen.dart' show CodegenRegistry; | 9 import '../common/codegen.dart' show CodegenRegistry; |
10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
(...skipping 13 matching lines...) Expand all Loading... | |
24 import '../js/js.dart' as js; | 24 import '../js/js.dart' as js; |
25 import '../js_backend/backend.dart' show JavaScriptBackend; | 25 import '../js_backend/backend.dart' show JavaScriptBackend; |
26 import '../kernel/element_map.dart'; | 26 import '../kernel/element_map.dart'; |
27 import '../native/native.dart' as native; | 27 import '../native/native.dart' as native; |
28 import '../resolution/tree_elements.dart'; | 28 import '../resolution/tree_elements.dart'; |
29 import '../tree/nodes.dart' show Node; | 29 import '../tree/nodes.dart' show Node; |
30 import '../types/masks.dart'; | 30 import '../types/masks.dart'; |
31 import '../universe/selector.dart'; | 31 import '../universe/selector.dart'; |
32 import '../universe/side_effects.dart' show SideEffects; | 32 import '../universe/side_effects.dart' show SideEffects; |
33 import '../universe/use.dart' show DynamicUse; | 33 import '../universe/use.dart' show DynamicUse; |
34 import '../universe/world_builder.dart' show CodegenWorldBuilder; | |
34 import '../world.dart'; | 35 import '../world.dart'; |
35 import 'graph_builder.dart'; | 36 import 'graph_builder.dart'; |
36 import 'jump_handler.dart'; | 37 import 'jump_handler.dart'; |
37 import 'kernel_ast_adapter.dart'; | 38 import 'kernel_ast_adapter.dart'; |
38 import 'kernel_string_builder.dart'; | 39 import 'kernel_string_builder.dart'; |
39 import 'locals_handler.dart'; | 40 import 'locals_handler.dart'; |
40 import 'loop_handler.dart'; | 41 import 'loop_handler.dart'; |
41 import 'nodes.dart'; | 42 import 'nodes.dart'; |
42 import 'ssa_branch_builder.dart'; | 43 import 'ssa_branch_builder.dart'; |
43 import 'switch_continue_analysis.dart'; | 44 import 'switch_continue_analysis.dart'; |
44 import 'type_builder.dart'; | 45 import 'type_builder.dart'; |
45 | 46 |
46 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { | 47 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
47 final ir.Node target; | 48 final ir.Node target; |
48 final bool _targetIsConstructorBody; | 49 final bool _targetIsConstructorBody; |
49 final MemberEntity targetElement; | 50 final MemberEntity targetElement; |
50 | 51 |
51 /// The root node of [targetElement]. This is used as the key into the | 52 /// The root node of [targetElement]. This is used as the key into the |
52 /// [startFunction] of the locals handler. | 53 /// [startFunction] of the locals handler. |
53 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals | 54 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals |
54 // handler. | 55 // handler. |
55 final Node functionNode; | 56 final Node functionNode; |
56 final ClosedWorld closedWorld; | 57 final ClosedWorld closedWorld; |
58 final CodegenWorldBuilder _worldBuilder; | |
57 final CodegenRegistry registry; | 59 final CodegenRegistry registry; |
58 final ClosureClassMaps closureToClassMapper; | 60 final ClosureClassMaps closureToClassMapper; |
59 | 61 |
60 /// Helper accessor for all kernel function-like targets (Procedure, | 62 /// Helper accessor for all kernel function-like targets (Procedure, |
61 /// FunctionExpression, FunctionDeclaration) of the inner FunctionNode itself. | 63 /// FunctionExpression, FunctionDeclaration) of the inner FunctionNode itself. |
62 /// If the current target is not a function-like target, _targetFunction will | 64 /// If the current target is not a function-like target, _targetFunction will |
63 /// be null. | 65 /// be null. |
64 ir.FunctionNode _targetFunction; | 66 ir.FunctionNode _targetFunction; |
65 | 67 |
66 /// A stack of [ResolutionDartType]s that have been seen during inlining of | 68 /// A stack of [ResolutionDartType]s that have been seen during inlining of |
(...skipping 30 matching lines...) Expand all Loading... | |
97 | 99 |
98 KernelSsaBuilder( | 100 KernelSsaBuilder( |
99 this.targetElement, | 101 this.targetElement, |
100 ClassEntity contextClass, | 102 ClassEntity contextClass, |
101 this.target, | 103 this.target, |
102 this.compiler, | 104 this.compiler, |
103 this._elementMap, | 105 this._elementMap, |
104 this._typeInferenceMap, | 106 this._typeInferenceMap, |
105 this._localsMap, | 107 this._localsMap, |
106 this.closedWorld, | 108 this.closedWorld, |
109 this._worldBuilder, | |
107 this.registry, | 110 this.registry, |
108 this.closureToClassMapper, | 111 this.closureToClassMapper, |
109 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? | 112 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? |
110 this.sourceInformationBuilder, | 113 this.sourceInformationBuilder, |
111 this.functionNode, | 114 this.functionNode, |
112 {bool targetIsConstructorBody: false}) | 115 {bool targetIsConstructorBody: false}) |
113 : this._targetIsConstructorBody = targetIsConstructorBody { | 116 : this._targetIsConstructorBody = targetIsConstructorBody { |
114 this.loopHandler = new KernelLoopHandler(this); | 117 this.loopHandler = new KernelLoopHandler(this); |
115 typeBuilder = new TypeBuilder(this); | 118 typeBuilder = new TypeBuilder(this); |
116 graph.element = targetElement; | 119 graph.element = targetElement; |
117 graph.sourceInformation = | 120 graph.sourceInformation = |
118 sourceInformationBuilder.buildVariableDeclaration(); | 121 sourceInformationBuilder.buildVariableDeclaration(); |
119 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, | 122 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, |
120 contextClass, null, nativeData, interceptorData); | 123 contextClass, null, nativeData, interceptorData); |
121 _targetStack.add(targetElement); | 124 _targetStack.add(targetElement); |
122 } | 125 } |
123 | 126 |
124 @deprecated // Use [_elementMap] instead. | 127 @deprecated // Use [_elementMap] instead. |
125 KernelAstAdapter get astAdapter => _elementMap; | 128 KernelAstAdapter get astAdapter => _elementMap; |
126 | 129 |
127 CommonElements get _commonElements => _elementMap.commonElements; | 130 CommonElements get _commonElements => _elementMap.commonElements; |
128 | 131 |
129 HGraph build() { | 132 HGraph build() { |
130 // TODO(het): no reason to do this here... | 133 return reporter.withCurrentElement(_localsMap.currentMember, () { |
131 HInstruction.idCounter = 0; | 134 // TODO(het): no reason to do this here... |
132 if (target is ir.Procedure) { | 135 HInstruction.idCounter = 0; |
133 _targetFunction = (target as ir.Procedure).function; | 136 if (target is ir.Procedure) { |
134 buildFunctionNode(_targetFunction); | 137 _targetFunction = (target as ir.Procedure).function; |
135 } else if (target is ir.Field) { | 138 buildFunctionNode(_targetFunction); |
136 buildField(target); | 139 } else if (target is ir.Field) { |
137 } else if (target is ir.Constructor) { | 140 buildField(target); |
138 if (_targetIsConstructorBody) { | 141 } else if (target is ir.Constructor) { |
139 buildConstructorBody(target); | 142 if (_targetIsConstructorBody) { |
143 buildConstructorBody(target); | |
144 } else { | |
145 buildConstructor(target); | |
146 } | |
147 } else if (target is ir.FunctionExpression) { | |
148 _targetFunction = (target as ir.FunctionExpression).function; | |
149 buildFunctionNode(_targetFunction); | |
150 } else if (target is ir.FunctionDeclaration) { | |
151 _targetFunction = (target as ir.FunctionDeclaration).function; | |
152 buildFunctionNode(_targetFunction); | |
140 } else { | 153 } else { |
141 buildConstructor(target); | 154 throw 'No case implemented to handle target: $target for $targetElement' ; |
Siggi Cherem (dart-lang)
2017/06/08 18:01:46
nit: reword to fit under 80?
Johnni Winther
2017/06/09 09:28:49
Split the string.
| |
142 } | 155 } |
143 } else if (target is ir.FunctionExpression) { | 156 assert(graph.isValid()); |
144 _targetFunction = (target as ir.FunctionExpression).function; | 157 return graph; |
145 buildFunctionNode(_targetFunction); | 158 }); |
146 } else if (target is ir.FunctionDeclaration) { | |
147 _targetFunction = (target as ir.FunctionDeclaration).function; | |
148 buildFunctionNode(_targetFunction); | |
149 } else { | |
150 throw 'No case implemented to handle target: $target for $targetElement'; | |
151 } | |
152 assert(graph.isValid()); | |
153 return graph; | |
154 } | 159 } |
155 | 160 |
156 void buildField(ir.Field field) { | 161 void buildField(ir.Field field) { |
157 openFunction(); | 162 openFunction(); |
158 if (field.initializer != null) { | 163 if (field.initializer != null) { |
159 field.initializer.accept(this); | 164 field.initializer.accept(this); |
160 HInstruction fieldValue = pop(); | 165 HInstruction fieldValue = pop(); |
161 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( | 166 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( |
162 fieldValue, _getDartTypeIfValid(field.type)); | 167 fieldValue, _getDartTypeIfValid(field.type)); |
163 stack.add(checkInstruction); | 168 stack.add(checkInstruction); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 | 263 |
259 // Collect field values for the current class. | 264 // Collect field values for the current class. |
260 Map<FieldEntity, HInstruction> fieldValues = | 265 Map<FieldEntity, HInstruction> fieldValues = |
261 _collectFieldValues(constructedClass); | 266 _collectFieldValues(constructedClass); |
262 List<ir.Constructor> constructorChain = <ir.Constructor>[]; | 267 List<ir.Constructor> constructorChain = <ir.Constructor>[]; |
263 _buildInitializers(constructor, constructorChain, fieldValues); | 268 _buildInitializers(constructor, constructorChain, fieldValues); |
264 | 269 |
265 final constructorArguments = <HInstruction>[]; | 270 final constructorArguments = <HInstruction>[]; |
266 // Doing this instead of fieldValues.forEach because we haven't defined the | 271 // Doing this instead of fieldValues.forEach because we haven't defined the |
267 // order of the arguments here. We can define that with JElements. | 272 // order of the arguments here. We can define that with JElements. |
268 ClassElement cls = _elementMap.getClass(constructedClass); | 273 ClassEntity cls = _elementMap.getClass(constructedClass); |
269 cls.forEachInstanceField( | 274 InterfaceType thisType = _elementMap.getThisType(cls); |
270 (ClassElement enclosingClass, FieldElement member) { | 275 _worldBuilder.forEachInstanceField(cls, |
276 (ClassEntity enclosingClass, FieldEntity member) { | |
271 var value = fieldValues[member]; | 277 var value = fieldValues[member]; |
272 assert(value != null, 'No value for field ${member}'); | 278 assert(value != null, 'No value for field ${member}'); |
273 constructorArguments.add(value); | 279 constructorArguments.add(value); |
274 }, includeSuperAndInjectedMembers: true); | 280 }); |
275 | 281 |
276 // Create the runtime type information, if needed. | 282 // Create the runtime type information, if needed. |
277 bool hasRtiInput = backend.rtiNeed | 283 bool hasRtiInput = backend.rtiNeed.classNeedsRtiField(cls); |
278 .classNeedsRtiField(_elementMap.getClass(constructedClass)); | |
279 if (hasRtiInput) { | 284 if (hasRtiInput) { |
280 // Read the values of the type arguments and create a HTypeInfoExpression | 285 // Read the values of the type arguments and create a HTypeInfoExpression |
281 // to set on the newly create object. | 286 // to set on the newly create object. |
282 List<HInstruction> typeArguments = <HInstruction>[]; | 287 List<HInstruction> typeArguments = <HInstruction>[]; |
283 for (ir.DartType typeParameter | 288 for (ir.DartType typeParameter |
284 in constructedClass.thisType.typeArguments) { | 289 in constructedClass.thisType.typeArguments) { |
285 HInstruction argument = localsHandler.readLocal(localsHandler | 290 HInstruction argument = localsHandler.readLocal(localsHandler |
286 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter) | 291 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter))); |
287 as ResolutionTypeVariableType)); | |
288 typeArguments.add(argument); | 292 typeArguments.add(argument); |
289 } | 293 } |
290 | 294 |
291 ClassElement cls = _elementMap.getClass(constructedClass); | |
292 HInstruction typeInfo = new HTypeInfoExpression( | 295 HInstruction typeInfo = new HTypeInfoExpression( |
293 TypeInfoExpressionKind.INSTANCE, | 296 TypeInfoExpressionKind.INSTANCE, |
294 cls.thisType, | 297 thisType, |
295 typeArguments, | 298 typeArguments, |
296 commonMasks.dynamicType); | 299 commonMasks.dynamicType); |
297 add(typeInfo); | 300 add(typeInfo); |
298 constructorArguments.add(typeInfo); | 301 constructorArguments.add(typeInfo); |
299 } | 302 } |
300 | 303 |
301 ClassElement constructedCls = _elementMap.getClass(constructedClass); | |
302 HInstruction newObject = new HCreate( | 304 HInstruction newObject = new HCreate( |
303 _elementMap.getClass(constructedClass), | 305 cls, constructorArguments, new TypeMask.nonNullExact(cls, closedWorld), |
304 constructorArguments, | 306 instantiatedTypes: <InterfaceType>[thisType], hasRtiInput: hasRtiInput); |
305 new TypeMask.nonNullExact( | |
306 _elementMap.getClass(constructedClass), closedWorld), | |
Siggi Cherem (dart-lang)
2017/06/08 18:01:46
wow... 6 times!
| |
307 instantiatedTypes: <ResolutionInterfaceType>[constructedCls.thisType], | |
308 hasRtiInput: hasRtiInput); | |
309 | 307 |
310 add(newObject); | 308 add(newObject); |
311 | 309 |
312 // Generate calls to the constructor bodies. | 310 // Generate calls to the constructor bodies. |
313 | 311 |
314 for (ir.Constructor body in constructorChain.reversed) { | 312 for (ir.Constructor body in constructorChain.reversed) { |
315 if (_isEmptyStatement(body.function.body)) continue; | 313 if (_isEmptyStatement(body.function.body)) continue; |
316 | 314 |
317 List<HInstruction> bodyCallInputs = <HInstruction>[]; | 315 List<HInstruction> bodyCallInputs = <HInstruction>[]; |
318 bodyCallInputs.add(newObject); | 316 bodyCallInputs.add(newObject); |
(...skipping 3123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3442 enterBlock.setBlockFlow( | 3440 enterBlock.setBlockFlow( |
3443 new HTryBlockInformation( | 3441 new HTryBlockInformation( |
3444 kernelBuilder.wrapStatementGraph(bodyGraph), | 3442 kernelBuilder.wrapStatementGraph(bodyGraph), |
3445 exception, | 3443 exception, |
3446 kernelBuilder.wrapStatementGraph(catchGraph), | 3444 kernelBuilder.wrapStatementGraph(catchGraph), |
3447 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3445 kernelBuilder.wrapStatementGraph(finallyGraph)), |
3448 exitBlock); | 3446 exitBlock); |
3449 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3447 kernelBuilder.inTryStatement = previouslyInTryStatement; |
3450 } | 3448 } |
3451 } | 3449 } |
OLD | NEW |