Chromium Code Reviews| 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 |