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

Side by Side Diff: dart/frog/leg/ssa/closure.dart

Issue 9567041: Implement prefixes in NewExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class ClosureFieldElement extends Element { 5 class ClosureFieldElement extends Element {
6 ClosureFieldElement(SourceString name, ClassElement enclosing) 6 ClosureFieldElement(SourceString name, ClassElement enclosing)
7 : super(name, ElementKind.FIELD, enclosing); 7 : super(name, ElementKind.FIELD, enclosing);
8 8
9 bool isInstanceMember() => true; 9 bool isInstanceMember() => true;
10 bool isAssignable() => false; 10 bool isAssignable() => false;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 this.callElement, 63 this.callElement,
64 this.thisElement) 64 this.thisElement)
65 : this.freeVariableMapping = new Map<Element, Element>(), 65 : this.freeVariableMapping = new Map<Element, Element>(),
66 this.capturedFieldMapping = new Map<Element, Element>(), 66 this.capturedFieldMapping = new Map<Element, Element>(),
67 this.capturingScopes = new Map<Node, ClosureScope>(), 67 this.capturingScopes = new Map<Node, ClosureScope>(),
68 this.usedVariablesInTry = new Set<Element>(); 68 this.usedVariablesInTry = new Set<Element>();
69 69
70 bool isClosure() => closureElement !== null; 70 bool isClosure() => closureElement !== null;
71 } 71 }
72 72
73 Map<Node, ClosureData> _closureDataCache;
74 Map<Node, ClosureData> get closureDataCache() {
75 if (_closureDataCache === null) {
76 _closureDataCache = new HashMap<Node, ClosureData>();
77 }
78 return _closureDataCache;
79 }
80
81 class ClosureTranslator extends AbstractVisitor { 73 class ClosureTranslator extends AbstractVisitor {
82 final Compiler compiler; 74 final Compiler compiler;
83 final TreeElements elements; 75 final TreeElements elements;
84 int boxCounter = 0; 76 int boxCounter = 0;
85 bool inTryCatchOrFinally = false; 77 bool inTryCatchOrFinally = false;
86 78
87 // Map of captured variables. Initially they will map to themselves. If 79 // Map of captured variables. Initially they will map to themselves. If
88 // a variable needs to be boxed then the scope declaring the variable 80 // a variable needs to be boxed then the scope declaring the variable
89 // will update this mapping. 81 // will update this mapping.
90 Map<Element, Element> capturedVariableMapping; 82 Map<Element, Element> capturedVariableMapping;
91 // List of encountered closures. 83 // List of encountered closures.
92 List<FunctionExpression> closures; 84 List<FunctionExpression> closures;
93 85
94 // The variables that have been declared in the current scope. 86 // The variables that have been declared in the current scope.
95 List<Element> scopeVariables; 87 List<Element> scopeVariables;
96 88
97 FunctionElement currentFunctionElement; 89 FunctionElement currentFunctionElement;
98 // The closureData of the currentFunctionElement. 90 // The closureData of the currentFunctionElement.
99 ClosureData closureData; 91 ClosureData closureData;
100 92
101 bool insideClosure = false; 93 bool insideClosure = false;
102 94
103 ClosureTranslator(this.compiler, this.elements) 95 ClosureTranslator(this.compiler, this.elements)
104 : capturedVariableMapping = new Map<Element, Element>(), 96 : capturedVariableMapping = new Map<Element, Element>(),
105 closures = <FunctionExpression>[]; 97 closures = <FunctionExpression>[];
106 98
107 ClosureData translate(Node node) { 99 ClosureData translate(Node node) {
108 // Closures have already been analyzed when visiting the surrounding 100 // Closures have already been analyzed when visiting the surrounding
109 // method/function. This also shortcuts for bailout functions. 101 // method/function. This also shortcuts for bailout functions.
110 ClosureData cached = closureDataCache[node]; 102 ClosureData cached = compiler.closureDataCache[node];
111 if (cached !== null) return cached; 103 if (cached !== null) return cached;
112 104
113 visit(node); 105 visit(node);
114 // When variables need to be boxed their [capturedVariableMapping] is 106 // When variables need to be boxed their [capturedVariableMapping] is
115 // updated, but we delay updating the similar freeVariableMapping in the 107 // updated, but we delay updating the similar freeVariableMapping in the
116 // closure datas that capture these variables. 108 // closure datas that capture these variables.
117 // The closures don't have their fields (in the closure class) set, either. 109 // The closures don't have their fields (in the closure class) set, either.
118 updateClosures(); 110 updateClosures();
119 111
120 return closureDataCache[node]; 112 return compiler.closureDataCache[node];
121 } 113 }
122 114
123 // This function runs through all of the existing closures and updates their 115 // This function runs through all of the existing closures and updates their
124 // free variables to the boxed value. It also adds the field-elements to the 116 // free variables to the boxed value. It also adds the field-elements to the
125 // class representing the closure. At the same time it fills the 117 // class representing the closure. At the same time it fills the
126 // [capturedFieldMapping]. 118 // [capturedFieldMapping].
127 void updateClosures() { 119 void updateClosures() {
128 for (FunctionExpression closure in closures) { 120 for (FunctionExpression closure in closures) {
129 // The captured variables that need to be stored in a field of the closure 121 // The captured variables that need to be stored in a field of the closure
130 // class. 122 // class.
131 Set<Element> fieldCaptures = new Set<Element>(); 123 Set<Element> fieldCaptures = new Set<Element>();
132 ClosureData data = closureDataCache[closure]; 124 ClosureData data = compiler.closureDataCache[closure];
133 Map<Element, Element> freeVariableMapping = data.freeVariableMapping; 125 Map<Element, Element> freeVariableMapping = data.freeVariableMapping;
134 // We get a copy of the keys and iterate over it, to avoid modifications 126 // We get a copy of the keys and iterate over it, to avoid modifications
135 // to the map while iterating over it. 127 // to the map while iterating over it.
136 freeVariableMapping.getKeys().forEach((Element fromElement) { 128 freeVariableMapping.getKeys().forEach((Element fromElement) {
137 assert(fromElement == freeVariableMapping[fromElement]); 129 assert(fromElement == freeVariableMapping[fromElement]);
138 Element updatedElement = capturedVariableMapping[fromElement]; 130 Element updatedElement = capturedVariableMapping[fromElement];
139 assert(updatedElement !== null); 131 assert(updatedElement !== null);
140 if (fromElement == updatedElement) { 132 if (fromElement == updatedElement) {
141 assert(freeVariableMapping[fromElement] == updatedElement); 133 assert(freeVariableMapping[fromElement] == updatedElement);
142 assert(Elements.isLocal(updatedElement)); 134 assert(Elements.isLocal(updatedElement));
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 declareLocal(element); 362 declareLocal(element);
371 } 363 }
372 364
373 // TODO(ahe): This is problematic. The backend should not repeat 365 // TODO(ahe): This is problematic. The backend should not repeat
374 // the work of the resolver. It is the resolver's job to create 366 // the work of the resolver. It is the resolver's job to create
375 // parameters, etc. Other phases should only visit statements. 367 // parameters, etc. Other phases should only visit statements.
376 node.visitChildren(this); 368 node.visitChildren(this);
377 369
378 attachCapturedScopeVariables(node); 370 attachCapturedScopeVariables(node);
379 371
380 closureDataCache[node] = closureData; 372 compiler.closureDataCache[node] = closureData;
381 373
382 ClosureData savedClosureData = closureData; 374 ClosureData savedClosureData = closureData;
383 bool savedInsideClosure = insideClosure; 375 bool savedInsideClosure = insideClosure;
384 376
385 // Restore old values. 377 // Restore old values.
386 scopeVariables = oldScopeVariables; 378 scopeVariables = oldScopeVariables;
387 insideClosure = oldInsideClosure; 379 insideClosure = oldInsideClosure;
388 closureData = oldClosureData; 380 closureData = oldClosureData;
389 currentFunctionElement = oldFunctionElement; 381 currentFunctionElement = oldFunctionElement;
390 382
(...skipping 18 matching lines...) Expand all
409 // TODO(ngeoffray): implement finer grain state. 401 // TODO(ngeoffray): implement finer grain state.
410 inTryCatchOrFinally = true; 402 inTryCatchOrFinally = true;
411 node.visitChildren(this); 403 node.visitChildren(this);
412 inTryCatchOrFinally = false; 404 inTryCatchOrFinally = false;
413 } 405 }
414 406
415 visitLiteralMap(LiteralMap node) { 407 visitLiteralMap(LiteralMap node) {
416 // TODO(ahe): Remove this method. 408 // TODO(ahe): Remove this method.
417 } 409 }
418 } 410 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698