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 '../closure.dart'; | 5 import '../closure.dart'; |
6 import '../common.dart'; | 6 import '../common.dart'; |
7 import '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
9 import '../elements/types.dart'; | 9 import '../elements/types.dart'; |
10 import '../io/source_information.dart'; | 10 import '../io/source_information.dart'; |
(...skipping 14 matching lines...) Expand all Loading... |
25 /// The values of locals that can be directly accessed (without redirections | 25 /// The values of locals that can be directly accessed (without redirections |
26 /// to boxes or closure-fields). | 26 /// to boxes or closure-fields). |
27 /// | 27 /// |
28 /// [directLocals] is iterated, so it is "insertion ordered" to make the | 28 /// [directLocals] is iterated, so it is "insertion ordered" to make the |
29 /// iteration order a function only of insertions and not a function of | 29 /// iteration order a function only of insertions and not a function of |
30 /// e.g. Element hash codes. I'd prefer to use a SortedMap but some elements | 30 /// e.g. Element hash codes. I'd prefer to use a SortedMap but some elements |
31 /// don't have source locations for [Elements.compareByPosition]. | 31 /// don't have source locations for [Elements.compareByPosition]. |
32 Map<Local, HInstruction> directLocals = new Map<Local, HInstruction>(); | 32 Map<Local, HInstruction> directLocals = new Map<Local, HInstruction>(); |
33 Map<Local, FieldEntity> redirectionMapping = new Map<Local, FieldEntity>(); | 33 Map<Local, FieldEntity> redirectionMapping = new Map<Local, FieldEntity>(); |
34 final GraphBuilder builder; | 34 final GraphBuilder builder; |
35 ClosureClassMap closureData; | 35 ClosureRepresentationInfo closureData; |
36 Map<TypeVariableType, TypeVariableLocal> typeVariableLocals = | 36 Map<TypeVariableType, TypeVariableLocal> typeVariableLocals = |
37 new Map<TypeVariableType, TypeVariableLocal>(); | 37 new Map<TypeVariableType, TypeVariableLocal>(); |
38 final Entity executableContext; | 38 final Entity executableContext; |
39 final MemberEntity memberContext; | 39 final MemberEntity memberContext; |
40 | 40 |
41 /// The class that defines the current type environment or null if no type | 41 /// The class that defines the current type environment or null if no type |
42 /// variables are in scope. | 42 /// variables are in scope. |
43 final ClassEntity contextClass; | 43 final ClassEntity contextClass; |
44 | 44 |
45 /// The type of the current instance, if concrete. | 45 /// The type of the current instance, if concrete. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 HInstruction oldValue = readLocal(boxedVariable); | 189 HInstruction oldValue = readLocal(boxedVariable); |
190 updateLocal(boxElement, newBox); | 190 updateLocal(boxElement, newBox); |
191 updateLocal(boxedVariable, oldValue); | 191 updateLocal(boxedVariable, oldValue); |
192 } | 192 } |
193 updateLocal(boxElement, newBox); | 193 updateLocal(boxElement, newBox); |
194 } | 194 } |
195 | 195 |
196 /// Documentation wanted -- johnniwinther | 196 /// Documentation wanted -- johnniwinther |
197 /// | 197 /// |
198 /// Invariant: [function] must be an implementation element. | 198 /// Invariant: [function] must be an implementation element. |
199 void startFunction(MemberEntity element, ClosureClassMap closureData, | 199 void startFunction( |
200 ClosureScope scopeData, Map<Local, TypeMask> parameters, | 200 MemberEntity element, |
| 201 ClosureRepresentationInfo closureData, |
| 202 ClosureAnalysisInfo scopeData, |
| 203 Map<Local, TypeMask> parameters, |
201 {bool isGenerativeConstructorBody}) { | 204 {bool isGenerativeConstructorBody}) { |
202 assert(!(element is MemberElement && !element.isImplementation), | 205 assert(!(element is MemberElement && !element.isImplementation), |
203 failedAt(element)); | 206 failedAt(element)); |
| 207 |
204 this.closureData = closureData; | 208 this.closureData = closureData; |
205 | 209 |
206 parameters.forEach((Local local, TypeMask typeMask) { | 210 parameters.forEach((Local local, TypeMask typeMask) { |
207 if (isGenerativeConstructorBody) { | 211 if (isGenerativeConstructorBody) { |
208 if (scopeData != null && scopeData.isCaptured(local)) { | 212 if (scopeData != null && scopeData.isCaptured(local)) { |
209 // The parameter will be a field in the box passed as the | 213 // The parameter will be a field in the box passed as the |
210 // last parameter. So no need to have it. | 214 // last parameter. So no need to have it. |
211 return; | 215 return; |
212 } | 216 } |
213 } | 217 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 builder.lastAddedParameter = value; | 292 builder.lastAddedParameter = value; |
289 } | 293 } |
290 } | 294 } |
291 } | 295 } |
292 | 296 |
293 /// Returns true if the local can be accessed directly. Boxed variables or | 297 /// Returns true if the local can be accessed directly. Boxed variables or |
294 /// captured variables that are stored in the closure-field return [:false:]. | 298 /// captured variables that are stored in the closure-field return [:false:]. |
295 bool isAccessedDirectly(Local local) { | 299 bool isAccessedDirectly(Local local) { |
296 assert(local != null); | 300 assert(local != null); |
297 return !redirectionMapping.containsKey(local) && | 301 return !redirectionMapping.containsKey(local) && |
298 !closureData.variablesUsedInTryOrGenerator.contains(local); | 302 !closureData.isVariableUsedInTryOrSync(local); |
299 } | 303 } |
300 | 304 |
301 bool isStoredInClosureField(Local local) { | 305 bool isStoredInClosureField(Local local) { |
302 assert(local != null); | 306 assert(local != null); |
303 if (isAccessedDirectly(local)) return false; | 307 if (isAccessedDirectly(local)) return false; |
304 FieldEntity redirectTarget = redirectionMapping[local]; | 308 FieldEntity redirectTarget = redirectionMapping[local]; |
305 if (redirectTarget == null) return false; | 309 if (redirectTarget == null) return false; |
306 return redirectTarget is ClosureFieldElement; | 310 return redirectTarget is ClosureFieldElement; |
307 } | 311 } |
308 | 312 |
309 bool isBoxed(Local local) { | 313 bool isBoxed(Local local) { |
310 if (isAccessedDirectly(local)) return false; | 314 if (isAccessedDirectly(local)) return false; |
311 if (isStoredInClosureField(local)) return false; | 315 if (isStoredInClosureField(local)) return false; |
312 return redirectionMapping.containsKey(local); | 316 return redirectionMapping.containsKey(local); |
313 } | 317 } |
314 | 318 |
315 bool isUsedInTryOrGenerator(Local local) { | 319 bool isUsedInTryOrGenerator(Local local) { |
316 return closureData.variablesUsedInTryOrGenerator.contains(local); | 320 return closureData.isVariableUsedInTryOrSync(local); |
317 } | 321 } |
318 | 322 |
319 /// Returns an [HInstruction] for the given element. If the element is | 323 /// Returns an [HInstruction] for the given element. If the element is |
320 /// boxed or stored in a closure then the method generates code to retrieve | 324 /// boxed or stored in a closure then the method generates code to retrieve |
321 /// the value. | 325 /// the value. |
322 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) { | 326 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) { |
323 if (isAccessedDirectly(local)) { | 327 if (isAccessedDirectly(local)) { |
324 if (directLocals[local] == null) { | 328 if (directLocals[local] == null) { |
325 if (local is TypeVariableLocal) { | 329 if (local is TypeVariableLocal) { |
326 throw new SpannableAssertionFailure( | 330 throw new SpannableAssertionFailure( |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 final MemberEntity memberContext; | 680 final MemberEntity memberContext; |
677 | 681 |
678 // Avoid slow Object.hashCode. | 682 // Avoid slow Object.hashCode. |
679 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); | 683 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); |
680 static int _nextHashCode = 0; | 684 static int _nextHashCode = 0; |
681 | 685 |
682 SyntheticLocal(this.name, this.executableContext, this.memberContext); | 686 SyntheticLocal(this.name, this.executableContext, this.memberContext); |
683 | 687 |
684 toString() => 'SyntheticLocal($name)'; | 688 toString() => 'SyntheticLocal($name)'; |
685 } | 689 } |
OLD | NEW |