| 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 7bef58cc7b22c160aea0954e72942797ba181f74..b55cdedfcb6464a7d73354dee58b91d715f1e5f9 100644
|
| --- a/pkg/compiler/lib/src/ssa/locals_handler.dart
|
| +++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
|
| @@ -136,25 +136,25 @@ class LocalsHandler {
|
|
|
| /// If the scope (function or loop) [node] has captured variables then this
|
| /// method creates a box and sets up the redirections.
|
| - void enterScope(ClosureScope scopeData,
|
| + void enterScope(ClosureAnalysisInfo closureInfo,
|
| {bool forGenerativeConstructorBody: false}) {
|
| // See if any variable in the top-scope of the function is captured. If yes
|
| // we need to create a box-object.
|
| - if (scopeData == null) return;
|
| + if (!closureInfo.requiresContextBox()) return;
|
| HInstruction box;
|
| // The scope has captured variables.
|
| if (forGenerativeConstructorBody) {
|
| // The box is passed as a parameter to a generative
|
| // constructor body.
|
| - box = builder.addParameter(scopeData.boxElement, commonMasks.nonNullType);
|
| + box = builder.addParameter(closureInfo.context, commonMasks.nonNullType);
|
| } else {
|
| box = createBox();
|
| }
|
| // Add the box to the known locals.
|
| - directLocals[scopeData.boxElement] = box;
|
| + directLocals[closureInfo.context] = box;
|
| // Make sure that accesses to the boxed locals go into the box. We also
|
| // need to make sure that parameters are copied into the box if necessary.
|
| - scopeData.forEachCapturedVariable(
|
| + closureInfo.forEachCapturedVariable(
|
| (LocalVariableElement from, BoxFieldElement to) {
|
| // The [from] can only be a parameter for function-scopes and not
|
| // loop scopes.
|
| @@ -216,8 +216,14 @@ class LocalsHandler {
|
| directLocals[local] = parameter;
|
| });
|
|
|
| - enterScope(scopeData,
|
| - forGenerativeConstructorBody: isGenerativeConstructorBody);
|
| + if (scopeData != null) {
|
| + // TODO(efortuna): Remove the above if wrapper (always execute this step)
|
| + // when the switch away from ClosureClassMap is complete (prior behavior
|
| + // in enterScope it was acceptable to pass in a null scopeData, but no
|
| + // longer).
|
| + enterScope(scopeData,
|
| + forGenerativeConstructorBody: isGenerativeConstructorBody);
|
| + }
|
|
|
| // If the freeVariableMapping is not empty, then this function was a
|
| // nested closure that captures variables. Redirect the captured
|
| @@ -473,15 +479,13 @@ class LocalsHandler {
|
| /// <updates>
|
| /// goto loop-entry;
|
| /// loop-exit:
|
| - void startLoop(ast.Node node) {
|
| - ClosureScope scopeData = closureData.capturingScopes[node];
|
| - if (scopeData == null) return;
|
| - if (scopeData.hasBoxedLoopVariables()) {
|
| + void startLoop(LoopClosureRepresentationInfo loopInfo) {
|
| + if (loopInfo.hasBoxedVariables) {
|
| // If there are boxed loop variables then we set up the box and
|
| // redirections already now. This way the initializer can write its
|
| // values into the box.
|
| // For other loops the box will be created when entering the body.
|
| - enterScope(scopeData);
|
| + enterScope(loopInfo);
|
| }
|
| }
|
|
|
| @@ -508,26 +512,22 @@ class LocalsHandler {
|
| });
|
| }
|
|
|
| - void enterLoopBody(ast.Node node) {
|
| - ClosureScope scopeData = closureData.capturingScopes[node];
|
| - if (scopeData == null) return;
|
| + void enterLoopBody(LoopClosureRepresentationInfo loopInfo) {
|
| // If there are no declared boxed loop variables then we did not create the
|
| // box before the initializer and we have to create the box now.
|
| - if (!scopeData.hasBoxedLoopVariables()) {
|
| - enterScope(scopeData);
|
| + if (!loopInfo.hasBoxedVariables) {
|
| + enterScope(loopInfo);
|
| }
|
| }
|
|
|
| - void enterLoopUpdates(ast.Node node) {
|
| + void enterLoopUpdates(LoopClosureRepresentationInfo loopInfo) {
|
| // If there are declared boxed loop variables then the updates might have
|
| // access to the box and we must switch to a new box before executing the
|
| // updates.
|
| // In all other cases a new box will be created when entering the body of
|
| // the next iteration.
|
| - ClosureScope scopeData = closureData.capturingScopes[node];
|
| - if (scopeData == null) return;
|
| - if (scopeData.hasBoxedLoopVariables()) {
|
| - updateCaptureBox(scopeData.boxElement, scopeData.boxedLoopVariables);
|
| + if (loopInfo.hasBoxedVariables) {
|
| + updateCaptureBox(loopInfo.context, loopInfo.boxedVariables);
|
| }
|
| }
|
|
|
|
|