Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- lib/compiler/implementation/ssa/builder.dart (revision 14294) |
| +++ lib/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -322,15 +322,24 @@ |
| * 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 { |
| + // Create a box. |
|
kasperl
2012/10/31 08:25:46
Remove this comment. It's obvious from the code.
ngeoffray
2012/10/31 09:04:28
Done.
|
| + // TODO(floitsch): Clean up this hack. Should we create a box-object by |
|
floitsch
2012/10/31 10:14:50
please remove this comment.
ngeoffray
2012/10/31 11:28:39
Done.
|
| + // just creating an empty object literal? |
| + 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 +407,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 +619,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 +650,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); |
| } |
| } |
| @@ -1172,16 +1181,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; |
| @@ -1371,6 +1381,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)); |
| }); |
| @@ -1389,6 +1404,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? |