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

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

Issue 9969212: Reapplies (again) "Don't try to box immutable objects." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Apply fix. Created 8 years, 8 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
« no previous file with comments | « no previous file | samples/tests/samples/samples-leg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/ssa/closure.dart
diff --git a/lib/compiler/implementation/ssa/closure.dart b/lib/compiler/implementation/ssa/closure.dart
index ab2d6a48c541bdbf94572232acce6b9d99a23635..947f865d4ee905206be414a91a2a4918ad7a7f6c 100644
--- a/lib/compiler/implementation/ssa/closure.dart
+++ b/lib/compiler/implementation/ssa/closure.dart
@@ -21,6 +21,19 @@ class ClosureClassElement extends ClassElement {
}
}
+class BoxElement extends Element {
+ BoxElement(SourceString name, Element enclosingElement)
+ : super(name, ElementKind.VARIABLE, enclosingElement);
+}
+
+class ThisElement extends Element {
+ ThisElement(Element enclosing)
+ : super(const SourceString('this'), ElementKind.PARAMETER, enclosing);
+
+ bool isAssignable() => false;
+ bool isInstanceMember() => false;
ngeoffray 2012/04/18 08:12:54 I don't think you need this last method here, it's
floitsch 2012/04/18 10:57:39 Done.
+}
+
// The box-element for a scope, and the captured variables that need to be
// stored in the box.
class ClosureScope {
@@ -47,7 +60,7 @@ class ClosureData {
final FunctionElement callElement;
// The [thisElement] makes handling 'this' easier by treating it like any
// other argument. It is only set for instance-members.
- final Element thisElement;
+ final ThisElement thisElement;
// Maps free locals, arguments and function elements to their captured
// copies.
@@ -82,7 +95,7 @@ class ClosureData {
class ClosureTranslator extends AbstractVisitor {
final Compiler compiler;
final TreeElements elements;
- int boxCounter = 0;
+ int closureFieldCounter = 0;
bool inTryCatchOrFinally = false;
final Map<Node, ClosureData> closureDataCache;
@@ -156,13 +169,20 @@ class ClosureTranslator extends AbstractVisitor {
});
ClassElement closureElement = data.closureClassElement;
assert(closureElement != null || fieldCaptures.isEmpty());
- for (Element boxElement in fieldCaptures) {
- Element fieldElement =
- new ClosureFieldElement(boxElement.name, closureElement);
+ for (Element capturedElement in fieldCaptures) {
+ SourceString name;
+ if (capturedElement is BoxElement) {
+ // The name is already mangled.
+ name = capturedElement.name;
+ } else {
+ int id = closureFieldCounter++;
+ name = new SourceString("${capturedElement.name.slowToString()}_$id");
+ }
+ Element fieldElement = new ClosureFieldElement(name, closureElement);
closureElement.backendMembers =
closureElement.backendMembers.prepend(fieldElement);
- data.capturedFieldMapping[fieldElement] = boxElement;
- freeVariableMapping[boxElement] = fieldElement;
+ data.capturedFieldMapping[fieldElement] = capturedElement;
+ freeVariableMapping[capturedElement] = fieldElement;
}
}
}
@@ -240,20 +260,22 @@ class ClosureTranslator extends AbstractVisitor {
Element box = null;
Map<Element, Element> scopeMapping = new Map<Element, Element>();
for (Element element in scopeVariables) {
+ // No need to box non-assignable elements.
+ if (!element.isAssignable()) continue;
if (capturedVariableMapping.containsKey(element)) {
if (box == null) {
// TODO(floitsch): construct better box names.
- SourceString boxName = new SourceString("box${boxCounter++}");
- box = new Element(boxName,
- ElementKind.VARIABLE,
- currentFunctionElement);
+ SourceString boxName =
+ new SourceString("box_${closureFieldCounter++}");
+ box = new BoxElement(boxName, currentFunctionElement);
}
// TODO(floitsch): construct better boxed names.
String elementName = element.name.slowToString();
// We are currently using the name in an HForeign which could replace
// "$X" with something else.
String escaped = elementName.replaceAll("\$", "_");
- SourceString boxedName = new SourceString("${escaped}_${boxCounter++}");
+ SourceString boxedName =
+ new SourceString("${escaped}_${closureFieldCounter++}");
Element boxed = new Element(boxedName, ElementKind.FIELD, box);
scopeMapping[element] = boxed;
capturedVariableMapping[element] = boxed;
@@ -346,17 +368,12 @@ class ClosureTranslator extends AbstractVisitor {
ConstructorBodyElement body = element;
thisEnclosingElement = body.constructor;
}
- thisElement = new Element(const SourceString("this"),
- ElementKind.PARAMETER,
- thisEnclosingElement);
+ thisElement = new ThisElement(thisEnclosingElement);
}
closureData = new ClosureData(null, null, null, thisElement);
}
scopeVariables = new List<Element>();
- // TODO(floitsch): a named function is visible from inside itself. Add
- // the element to the block.
-
// We have to declare the implicit 'this' parameter.
if (!insideClosure && closureData.thisElement !== null) {
declareLocal(closureData.thisElement);
« no previous file with comments | « no previous file | samples/tests/samples/samples-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698