Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 11273121: Support closures inside initializers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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?

Powered by Google App Engine
This is Rietveld 408576698