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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 import 'locals_handler.dart'; | 42 import 'locals_handler.dart'; |
43 import 'loop_handler.dart'; | 43 import 'loop_handler.dart'; |
44 import 'nodes.dart'; | 44 import 'nodes.dart'; |
45 import 'ssa.dart'; | 45 import 'ssa.dart'; |
46 import 'ssa_branch_builder.dart'; | 46 import 'ssa_branch_builder.dart'; |
47 import 'switch_continue_analysis.dart'; | 47 import 'switch_continue_analysis.dart'; |
48 import 'type_builder.dart'; | 48 import 'type_builder.dart'; |
49 | 49 |
50 class KernelSsaGraphBuilder extends ir.Visitor | 50 class KernelSsaGraphBuilder extends ir.Visitor |
51 with GraphBuilder, SsaBuilderFieldMixin { | 51 with GraphBuilder, SsaBuilderFieldMixin { |
52 final ir.Node target; | |
53 final MemberEntity targetElement; | 52 final MemberEntity targetElement; |
54 | 53 |
55 /// The root node of [targetElement]. This is used as the key into the | 54 /// The root node of [targetElement]. This is used as the key into the |
56 /// [startFunction] of the locals handler. | 55 /// [startFunction] of the locals handler. |
57 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals | 56 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals |
58 // handler. | 57 // handler. |
59 final Node functionNode; | 58 final Node functionNode; |
60 final ClosedWorld closedWorld; | 59 final ClosedWorld closedWorld; |
61 final CodegenWorldBuilder _worldBuilder; | 60 final CodegenWorldBuilder _worldBuilder; |
62 final CodegenRegistry registry; | 61 final CodegenRegistry registry; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 final Map<ir.VariableDeclaration, HInstruction> letBindings = | 96 final Map<ir.VariableDeclaration, HInstruction> letBindings = |
98 <ir.VariableDeclaration, HInstruction>{}; | 97 <ir.VariableDeclaration, HInstruction>{}; |
99 | 98 |
100 /// True if we are visiting the expression of a throw statement; we assume | 99 /// True if we are visiting the expression of a throw statement; we assume |
101 /// this is a slow path. | 100 /// this is a slow path. |
102 bool _inExpressionOfThrow = false; | 101 bool _inExpressionOfThrow = false; |
103 | 102 |
104 KernelSsaGraphBuilder( | 103 KernelSsaGraphBuilder( |
105 this.targetElement, | 104 this.targetElement, |
106 ClassEntity contextClass, | 105 ClassEntity contextClass, |
107 this.target, | |
108 this.compiler, | 106 this.compiler, |
109 this._elementMap, | 107 this._elementMap, |
110 this._typeInferenceMap, | 108 this._typeInferenceMap, |
111 this.localsMap, | 109 this.localsMap, |
112 this.closedWorld, | 110 this.closedWorld, |
113 this._worldBuilder, | 111 this._worldBuilder, |
114 this.registry, | 112 this.registry, |
115 this.closureDataLookup, | 113 this.closureDataLookup, |
116 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? | 114 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? |
117 this.sourceInformationBuilder, | 115 this.sourceInformationBuilder, |
118 this.functionNode) { | 116 this.functionNode) { |
119 this.loopHandler = new KernelLoopHandler(this); | 117 this.loopHandler = new KernelLoopHandler(this); |
120 typeBuilder = new TypeBuilder(this); | 118 typeBuilder = new TypeBuilder(this); |
121 graph.element = targetElement; | 119 graph.element = targetElement; |
122 graph.sourceInformation = | 120 graph.sourceInformation = |
123 sourceInformationBuilder.buildVariableDeclaration(); | 121 sourceInformationBuilder.buildVariableDeclaration(); |
124 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, | 122 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, |
125 contextClass, null, nativeData, interceptorData); | 123 contextClass, null, nativeData, interceptorData); |
126 _targetStack.add(targetElement); | 124 _targetStack.add(targetElement); |
127 } | 125 } |
128 | 126 |
129 CommonElements get _commonElements => _elementMap.commonElements; | 127 CommonElements get _commonElements => _elementMap.commonElements; |
130 | 128 |
131 HGraph build() { | 129 HGraph build() { |
132 return reporter.withCurrentElement(localsMap.currentMember, () { | 130 return reporter.withCurrentElement(localsMap.currentMember, () { |
133 // TODO(het): no reason to do this here... | 131 // TODO(het): no reason to do this here... |
134 HInstruction.idCounter = 0; | 132 HInstruction.idCounter = 0; |
135 if (target is ir.Procedure) { | 133 MemberDefinition definition = |
136 _targetFunction = (target as ir.Procedure).function; | 134 _elementMap.getMemberDefinition(targetElement); |
137 buildFunctionNode(_targetFunction); | 135 |
138 } else if (target is ir.Field) { | 136 switch (definition.kind) { |
139 if (handleConstantField(targetElement, registry, closedWorld)) { | 137 case MemberKind.regular: |
140 // No code is generated for `targetElement`: All references inline the | 138 case MemberKind.closureCall: |
141 // constant value. | 139 ir.Node target = definition.node; |
142 return null; | 140 if (target is ir.Procedure) { |
143 } else if (targetElement.isStatic || targetElement.isTopLevel) { | 141 _targetFunction = target.function; |
144 backend.constants.registerLazyStatic(targetElement); | 142 buildFunctionNode(_targetFunction); |
145 } | 143 } else if (target is ir.Field) { |
146 buildField(target); | 144 if (handleConstantField(targetElement, registry, closedWorld)) { |
147 } else if (target is ir.Constructor) { | 145 // No code is generated for `targetElement`: All references inline
the |
148 if (targetElement is ConstructorBodyEntity) { | 146 // constant value. |
149 buildConstructorBody(target); | 147 return null; |
150 } else { | 148 } else if (targetElement.isStatic || targetElement.isTopLevel) { |
151 buildConstructor(target); | 149 backend.constants.registerLazyStatic(targetElement); |
152 } | 150 } |
153 } else if (target is ir.FunctionExpression) { | 151 buildField(target); |
154 _targetFunction = (target as ir.FunctionExpression).function; | 152 } else if (target is ir.FunctionExpression) { |
155 buildFunctionNode(_targetFunction); | 153 _targetFunction = target.function; |
156 } else if (target is ir.FunctionDeclaration) { | 154 buildFunctionNode(_targetFunction); |
157 _targetFunction = (target as ir.FunctionDeclaration).function; | 155 } else if (target is ir.FunctionDeclaration) { |
158 buildFunctionNode(_targetFunction); | 156 _targetFunction = target.function; |
159 } else { | 157 buildFunctionNode(_targetFunction); |
160 throw 'No case implemented to handle target: ' | 158 } else { |
161 '$target for $targetElement'; | 159 throw 'No case implemented to handle target: ' |
| 160 '$target for $targetElement'; |
| 161 } |
| 162 break; |
| 163 case MemberKind.constructor: |
| 164 buildConstructor(definition.node); |
| 165 break; |
| 166 case MemberKind.constructorBody: |
| 167 buildConstructorBody(definition.node); |
| 168 break; |
162 } | 169 } |
163 assert(graph.isValid()); | 170 assert(graph.isValid()); |
164 return graph; | 171 return graph; |
165 }); | 172 }); |
166 } | 173 } |
167 | 174 |
168 @override | 175 @override |
169 ConstantValue getFieldInitialConstantValue(FieldEntity field) { | 176 ConstantValue getFieldInitialConstantValue(FieldEntity field) { |
170 assert(field == targetElement); | 177 assert(field == targetElement); |
171 return _elementMap.getFieldConstantValue(target); | 178 MemberDefinition definition = _elementMap.getMemberDefinition(field); |
| 179 assert(definition.kind == MemberKind.regular, |
| 180 failedAt(field, "Unexpected member definition: $definition")); |
| 181 return _elementMap.getFieldConstantValue(definition.node); |
172 } | 182 } |
173 | 183 |
174 void buildField(ir.Field field) { | 184 void buildField(ir.Field field) { |
175 openFunction(); | 185 openFunction(); |
176 if (field.initializer != null) { | 186 if (field.initializer != null) { |
177 field.initializer.accept(this); | 187 field.initializer.accept(this); |
178 HInstruction fieldValue = pop(); | 188 HInstruction fieldValue = pop(); |
179 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( | 189 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( |
180 fieldValue, _getDartTypeIfValid(field.type)); | 190 fieldValue, _getDartTypeIfValid(field.type)); |
181 stack.add(checkInstruction); | 191 stack.add(checkInstruction); |
(...skipping 3334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3516 enterBlock.setBlockFlow( | 3526 enterBlock.setBlockFlow( |
3517 new HTryBlockInformation( | 3527 new HTryBlockInformation( |
3518 kernelBuilder.wrapStatementGraph(bodyGraph), | 3528 kernelBuilder.wrapStatementGraph(bodyGraph), |
3519 exception, | 3529 exception, |
3520 kernelBuilder.wrapStatementGraph(catchGraph), | 3530 kernelBuilder.wrapStatementGraph(catchGraph), |
3521 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3531 kernelBuilder.wrapStatementGraph(finallyGraph)), |
3522 exitBlock); | 3532 exitBlock); |
3523 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3533 kernelBuilder.inTryStatement = previouslyInTryStatement; |
3524 } | 3534 } |
3525 } | 3535 } |
OLD | NEW |