Index: pkg/compiler/lib/src/ssa/locals_handler.dart |
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart |
index 889270f448362c5fa1e6f3eedab002916240d0d1..c9ece7cba30a9a0a188adb88bfa86e01a58c1701 100644 |
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart |
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart |
@@ -32,7 +32,7 @@ class LocalsHandler { |
Map<Local, HInstruction> directLocals = new Map<Local, HInstruction>(); |
Map<Local, FieldEntity> redirectionMapping = new Map<Local, FieldEntity>(); |
final GraphBuilder builder; |
- ClosureRepresentationInfo closureData; |
+ ScopeInfo scopeInfo; |
Map<TypeVariableType, TypeVariableLocal> typeVariableLocals = |
new Map<TypeVariableType, TypeVariableLocal>(); |
final Entity executableContext; |
@@ -113,7 +113,7 @@ class LocalsHandler { |
contextClass = other.contextClass, |
instanceType = other.instanceType, |
builder = other.builder, |
- closureData = other.closureData, |
+ scopeInfo = other.scopeInfo, |
_nativeData = other._nativeData, |
_interceptorData = other._interceptorData, |
activationVariables = other.activationVariables, |
@@ -197,15 +197,12 @@ class LocalsHandler { |
/// Documentation wanted -- johnniwinther |
/// |
/// Invariant: [function] must be an implementation element. |
- void startFunction( |
- MemberEntity element, |
- ClosureRepresentationInfo closureData, |
- ClosureAnalysisInfo scopeData, |
- Map<Local, TypeMask> parameters, |
+ void startFunction(MemberEntity element, ScopeInfo scopeInfo, |
+ ClosureAnalysisInfo scopeData, Map<Local, TypeMask> parameters, |
{bool isGenerativeConstructorBody}) { |
assert(!(element is MemberElement && !element.isImplementation), |
failedAt(element)); |
- this.closureData = closureData; |
+ this.scopeInfo = scopeInfo; |
parameters.forEach((Local local, TypeMask typeMask) { |
if (isGenerativeConstructorBody) { |
@@ -223,7 +220,11 @@ class LocalsHandler { |
enterScope(scopeData, |
forGenerativeConstructorBody: isGenerativeConstructorBody); |
- if (closureData.isClosure) { |
+ // When we remove the element model, we can just use the first check |
+ // (because the underlying elements won't all be *both* ScopeInfos and |
+ // ClosureRepresentationInfos). |
+ if (scopeInfo is ClosureRepresentationInfo && scopeInfo.isClosure) { |
+ ClosureRepresentationInfo closureData = scopeInfo; |
// If the freeVariableMapping is not empty, then this function was a |
// nested closure that captures variables. Redirect the captured |
// variables to fields in the closure. |
@@ -240,10 +241,10 @@ class LocalsHandler { |
// Once closures have been mapped to classes their instance members might |
// not have any thisElement if the closure was created inside a static |
// context. |
- HThis thisInstruction = new HThis(closureData.thisLocal, getTypeOfThis()); |
+ HThis thisInstruction = new HThis(scopeInfo.thisLocal, getTypeOfThis()); |
builder.graph.thisInstruction = thisInstruction; |
builder.graph.entry.addAtEntry(thisInstruction); |
- directLocals[closureData.thisLocal] = thisInstruction; |
+ directLocals[scopeInfo.thisLocal] = thisInstruction; |
} |
// If this method is an intercepted method, add the extra |
@@ -264,14 +265,14 @@ class LocalsHandler { |
SyntheticLocal parameter = createLocal(name); |
HParameterValue value = new HParameterValue(parameter, getTypeOfThis()); |
builder.graph.explicitReceiverParameter = value; |
- builder.graph.entry.addAfter(directLocals[closureData.thisLocal], value); |
+ builder.graph.entry.addAfter(directLocals[scopeInfo.thisLocal], value); |
if (builder.lastAddedParameter == null) { |
// If this is the first parameter inserted, make sure it stays first. |
builder.lastAddedParameter = value; |
} |
if (isInterceptedClass) { |
// Only use the extra parameter in intercepted classes. |
- directLocals[closureData.thisLocal] = value; |
+ directLocals[scopeInfo.thisLocal] = value; |
} |
} else if (isNativeUpgradeFactory) { |
SyntheticLocal parameter = createLocal('receiver'); |
@@ -293,12 +294,13 @@ class LocalsHandler { |
bool isAccessedDirectly(Local local) { |
assert(local != null); |
return !redirectionMapping.containsKey(local) && |
- !closureData.variableIsUsedInTryOrSync(local); |
+ !scopeInfo.variableIsUsedInTryOrSync(local); |
} |
bool isStoredInClosureField(Local local) { |
assert(local != null); |
if (isAccessedDirectly(local)) return false; |
+ if (scopeInfo is! ClosureRepresentationInfo) return false; |
FieldEntity redirectTarget = redirectionMapping[local]; |
if (redirectTarget == null) return false; |
return redirectTarget is ClosureFieldElement; |
@@ -311,7 +313,7 @@ class LocalsHandler { |
} |
bool _isUsedInTryOrGenerator(Local local) { |
- return closureData.variableIsUsedInTryOrSync(local); |
+ return scopeInfo.variableIsUsedInTryOrSync(local); |
} |
/// Returns an [HInstruction] for the given element. If the element is |
@@ -339,6 +341,7 @@ class LocalsHandler { |
} |
return value; |
} else if (isStoredInClosureField(local)) { |
+ ClosureRepresentationInfo closureData = scopeInfo; |
ClosureFieldElement redirect = redirectionMapping[local]; |
HInstruction receiver = readLocal(closureData.closureEntity); |
TypeMask type = local is BoxLocal |
@@ -370,7 +373,7 @@ class LocalsHandler { |
} |
HInstruction readThis() { |
- HInstruction res = readLocal(closureData.thisLocal); |
+ HInstruction res = readLocal(scopeInfo.thisLocal); |
if (res.instructionType == null) { |
res.instructionType = getTypeOfThis(); |
} |
@@ -494,7 +497,7 @@ class LocalsHandler { |
savedDirectLocals.forEach((Local local, HInstruction instruction) { |
if (isAccessedDirectly(local)) { |
// We know 'this' cannot be modified. |
- if (local != closureData.thisLocal) { |
+ if (local != scopeInfo.thisLocal) { |
HPhi phi = |
new HPhi.singleInput(local, instruction, commonMasks.dynamicType); |
loopEntry.addPhi(phi); |
@@ -551,7 +554,7 @@ class LocalsHandler { |
Map<Local, HInstruction> joinedLocals = new Map<Local, HInstruction>(); |
otherLocals.directLocals.forEach((Local local, HInstruction instruction) { |
// We know 'this' cannot be modified. |
- if (local == closureData.thisLocal) { |
+ if (local == scopeInfo.thisLocal) { |
assert(directLocals[local] == instruction); |
joinedLocals[local] = instruction; |
} else { |
@@ -582,7 +585,7 @@ class LocalsHandler { |
Map<Local, HInstruction> joinedLocals = new Map<Local, HInstruction>(); |
HInstruction thisValue = null; |
directLocals.forEach((Local local, HInstruction instruction) { |
- if (local != closureData.thisLocal) { |
+ if (local != scopeInfo.thisLocal) { |
HPhi phi = new HPhi.noInputs(local, commonMasks.dynamicType); |
joinedLocals[local] = phi; |
joinBlock.addPhi(phi); |
@@ -603,13 +606,13 @@ class LocalsHandler { |
} |
if (thisValue != null) { |
// If there was a "this" for the scope, add it to the new locals. |
- joinedLocals[closureData.thisLocal] = thisValue; |
+ joinedLocals[scopeInfo.thisLocal] = thisValue; |
} |
// Remove locals that are not in all handlers. |
directLocals = new Map<Local, HInstruction>(); |
joinedLocals.forEach((Local local, HInstruction instruction) { |
- if (local != closureData.thisLocal && |
+ if (local != scopeInfo.thisLocal && |
instruction.inputs.length != localsHandlers.length) { |
joinBlock.removePhi(instruction); |
} else { |
@@ -624,7 +627,7 @@ class LocalsHandler { |
TypeMask getTypeOfThis() { |
TypeMask result = cachedTypeOfThis; |
if (result == null) { |
- ThisLocal local = closureData.thisLocal; |
+ ThisLocal local = scopeInfo.thisLocal; |
ClassEntity cls = local.enclosingClass; |
if (closedWorld.isUsedAsMixin(cls)) { |
// If the enclosing class is used as a mixin, [:this:] can be |