| Index: lib/compiler/implementation/ssa/builder.dart
 | 
| ===================================================================
 | 
| --- lib/compiler/implementation/ssa/builder.dart	(revision 14321)
 | 
| +++ lib/compiler/implementation/ssa/builder.dart	(working copy)
 | 
| @@ -322,15 +322,21 @@
 | 
|     * If the scope (function or loop) [node] has captured variables then this
 | 
|     * method creates a box and sets up the redirections.
 | 
|     */
 | 
| -  void enterScope(Node node) {
 | 
| +  void enterScope(Node node, Element element) {
 | 
|      // See if any variable in the top-scope of the function is captured. If yes
 | 
|      // we need to create a box-object.
 | 
|      ClosureScope scopeData = closureData.capturingScopes[node];
 | 
|      if (scopeData != null) {
 | 
| -      // The scope has captured variables. Create a box.
 | 
| -      // TODO(floitsch): Clean up this hack. Should we create a box-object by
 | 
| -      // just creating an empty object literal?
 | 
| -      HInstruction box = createBox();
 | 
| +      HInstruction box;
 | 
| +      // The scope has captured variables.
 | 
| +      if (element != null && element.isGenerativeConstructorBody()) {
 | 
| +        // The box is passed as a parameter to a generative
 | 
| +        // constructor body.
 | 
| +        box = new HParameterValue(scopeData.boxElement);
 | 
| +        builder.add(box);
 | 
| +      } else {
 | 
| +        box = createBox();
 | 
| +      }
 | 
|        // Add the box to the known locals.
 | 
|        directLocals[scopeData.boxElement] = box;
 | 
|        // Make sure that accesses to the boxed locals go into the box. We also
 | 
| @@ -398,7 +404,7 @@
 | 
|        });
 | 
|      }
 | 
|  
 | 
| -    enterScope(node);
 | 
| +    enterScope(node, element);
 | 
|  
 | 
|      // If the freeVariableMapping is not empty, then this function was a
 | 
|      // nested closure that captures variables. Redirect the captured
 | 
| @@ -610,7 +616,7 @@
 | 
|        // 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(node);
 | 
| +      enterScope(node, null);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -641,7 +647,7 @@
 | 
|      // 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(node);
 | 
| +      enterScope(node, null);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -1170,16 +1176,17 @@
 | 
|            compiler.enqueuer.resolution.getCachedElements(constructor);
 | 
|  
 | 
|        ClosureClassMap oldClosureData = localsHandler.closureData;
 | 
| +      Node node = constructor.parseNode(compiler);
 | 
|        localsHandler.closureData =
 | 
|            compiler.closureToClassMapper.computeClosureToClassMapping(
 | 
| -              constructor, constructor.parseNode(compiler), elements);
 | 
| +              constructor, node, elements);
 | 
|  
 | 
|        params.orderedForEachParameter((Element parameterElement) {
 | 
|          if (elements.isParameterChecked(parameterElement)) {
 | 
|            addParameterCheckInstruction(parameterElement);
 | 
|          }
 | 
|        });
 | 
| -
 | 
| +      localsHandler.enterScope(node, constructor);
 | 
|        buildInitializers(constructor, constructors, fieldValues);
 | 
|        localsHandler.closureData = oldClosureData;
 | 
|        elements = oldElements;
 | 
| @@ -1369,6 +1376,11 @@
 | 
|        FunctionSignature functionSignature = body.computeSignature(compiler);
 | 
|        int arity = functionSignature.parameterCount;
 | 
|        functionSignature.orderedForEachParameter((parameter) {
 | 
| +        // TODO(ngeoffray): No need to pass the parameters that are
 | 
| +        // captured and stored in a box. Because this information is
 | 
| +        // not trivial to get in codegen.dart, we just pass the
 | 
| +        // parameters anyway. We need to update both codegen.dart and
 | 
| +        // builder.dart on how parameters are being passed.
 | 
|          bodyCallInputs.add(localsHandler.readLocal(parameter));
 | 
|        });
 | 
|  
 | 
| @@ -1387,6 +1399,13 @@
 | 
|          }
 | 
|        });
 | 
|  
 | 
| +      // If there are locals that escape (ie used in closures), we
 | 
| +      // pass the box to the constructor.
 | 
| +      ClosureScope scopeData = parameterClosureData.capturingScopes[node];
 | 
| +      if (scopeData != null) {
 | 
| +        bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
 | 
| +      }
 | 
| +
 | 
|        // TODO(ahe): The constructor name is statically resolved. See
 | 
|        // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
 | 
|        // way to do this?
 | 
| 
 |