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

Side by Side Diff: lib/compiler/implementation/closure.dart

Issue 10911062: Codegen support for the argument definition test. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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
« no previous file with comments | « no previous file | lib/compiler/implementation/compile_time_constants.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #library("closureToClassMapper"); 5 #library("closureToClassMapper");
6 6
7 #import("elements/elements.dart"); 7 #import("elements/elements.dart");
8 #import("leg.dart"); 8 #import("leg.dart");
9 #import("scanner/scannerlib.dart"); 9 #import("scanner/scannerlib.dart");
10 #import("tree/tree.dart"); 10 #import("tree/tree.dart");
11 #import("util/util.dart"); 11 #import("util/util.dart");
12 12
13 class ClosureTask extends CompilerTask { 13 class ClosureTask extends CompilerTask {
14 Map<Node, ClosureClassMap> closureMappingCache; 14 Map<Node, ClosureClassMap> closureMappingCache;
15 ClosureTask(Compiler compiler) 15 ClosureTask(Compiler compiler)
16 : closureMappingCache = new Map<Node, ClosureClassMap>(), 16 : closureMappingCache = new Map<Node, ClosureClassMap>(),
17 super(compiler); 17 super(compiler);
18 18
19 String get name => "Closure Simplifier"; 19 String get name => "Closure Simplifier";
20 20
21 ClosureClassMap computeClosureToClassMapping(FunctionExpression node, 21 ClosureClassMap computeClosureToClassMapping(FunctionExpression node,
22 TreeElements elements) { 22 TreeElements elements) {
23 return measure(() { 23 return measure(() {
24 ClosureClassMap cached = closureMappingCache[node]; 24 ClosureClassMap cached = closureMappingCache[node];
25 if (cached !== null) return cached; 25 if (cached !== null) return cached;
26 26
27 ClosureTranslator translator = 27 ClosureTranslator translator =
28 new ClosureTranslator(compiler, elements, closureMappingCache); 28 new ClosureTranslator(compiler, elements, closureMappingCache);
29 // The translator will store the computed closure-mappings inside the 29 // The translator will store the computed closure-mappings inside the
30 // cache. One for given method and one for each nested closure. 30 // cache. One for given method and one for each nested closure.
31 translator.translate(node); 31 translator.translate(node);
32 assert(closureMappingCache[node] != null); 32 assert(closureMappingCache[node] != null);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 134
135 // Maps scopes ([Loop] and [FunctionExpression] nodes) to their 135 // Maps scopes ([Loop] and [FunctionExpression] nodes) to their
136 // [ClosureScope] which contains their box and the 136 // [ClosureScope] which contains their box and the
137 // captured variables that are stored in the box. 137 // captured variables that are stored in the box.
138 // This map will be empty if the method/closure of this [ClosureData] does not 138 // This map will be empty if the method/closure of this [ClosureData] does not
139 // contain any nested closure. 139 // contain any nested closure.
140 final Map<Node, ClosureScope> capturingScopes; 140 final Map<Node, ClosureScope> capturingScopes;
141 141
142 final Set<Element> usedVariablesInTry; 142 final Set<Element> usedVariablesInTry;
143 143
144 // A map from the parameter element to the variable element that
145 // holds the sentinel check.
146 final Map<Element, Element> parametersWithSentinel;
147
144 ClosureClassMap(this.closureElement, 148 ClosureClassMap(this.closureElement,
145 this.closureClassElement, 149 this.closureClassElement,
146 this.callElement, 150 this.callElement,
147 this.thisElement) 151 this.thisElement)
148 : this.freeVariableMapping = new Map<Element, Element>(), 152 : this.freeVariableMapping = new Map<Element, Element>(),
149 this.capturedFieldMapping = new Map<Element, Element>(), 153 this.capturedFieldMapping = new Map<Element, Element>(),
150 this.capturingScopes = new Map<Node, ClosureScope>(), 154 this.capturingScopes = new Map<Node, ClosureScope>(),
151 this.usedVariablesInTry = new Set<Element>(); 155 this.usedVariablesInTry = new Set<Element>(),
156 this.parametersWithSentinel = new Map<Element, Element>();
152 157
153 bool isClosure() => closureElement !== null; 158 bool isClosure() => closureElement !== null;
154 } 159 }
155 160
156 class ClosureTranslator extends AbstractVisitor { 161 class ClosureTranslator extends AbstractVisitor {
157 final Compiler compiler; 162 final Compiler compiler;
158 final TreeElements elements; 163 final TreeElements elements;
159 int closureFieldCounter = 0; 164 int closureFieldCounter = 0;
160 bool inTryStatement = false; 165 bool inTryStatement = false;
161 final Map<Node, ClosureClassMap> closureMappingCache; 166 final Map<Node, ClosureClassMap> closureMappingCache;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 310
306 visitSend(Send node) { 311 visitSend(Send node) {
307 Element element = elements[node]; 312 Element element = elements[node];
308 if (Elements.isLocal(element)) { 313 if (Elements.isLocal(element)) {
309 useLocal(element); 314 useLocal(element);
310 } else if (node.receiver === null && 315 } else if (node.receiver === null &&
311 Elements.isInstanceSend(node, elements)) { 316 Elements.isInstanceSend(node, elements)) {
312 useLocal(closureData.thisElement); 317 useLocal(closureData.thisElement);
313 } else if (node.isSuperCall) { 318 } else if (node.isSuperCall) {
314 useLocal(closureData.thisElement); 319 useLocal(closureData.thisElement);
320 } else if (node.isOperator
321 && node.argumentsNode is Prefix
322 && node.selector.source.stringValue == '?') {
323 Element parameter = elements[node.receiver];
324 FunctionElement enclosing = parameter.enclosingElement;
325 FunctionExpression function = enclosing.parseNode(compiler);
326 ClosureClassMap cached = closureMappingCache[function];
327 if (!cached.parametersWithSentinel.containsKey(parameter)) {
328 SourceString parameterName = parameter.name;
329 String name = '${parameterName.slowToString()}_check';
330 Element newElement = new Element(new SourceString(name),
331 ElementKind.VARIABLE,
332 enclosing);
333 useLocal(newElement);
334 cached.parametersWithSentinel[parameter] = newElement;
335 }
315 } 336 }
316 node.visitChildren(this); 337 node.visitChildren(this);
317 } 338 }
318 339
319 visitSendSet(SendSet node) { 340 visitSendSet(SendSet node) {
320 Element element = elements[node]; 341 Element element = elements[node];
321 if (Elements.isLocal(element)) { 342 if (Elements.isLocal(element)) {
322 mutatedVariables.add(element); 343 mutatedVariables.add(element);
323 } 344 }
324 super.visitSendSet(node); 345 super.visitSendSet(node);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // declared in the GENERATIVE_CONSTRUCTOR. Including the 'this'. 492 // declared in the GENERATIVE_CONSTRUCTOR. Including the 'this'.
472 Element thisEnclosingElement = element; 493 Element thisEnclosingElement = element;
473 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 494 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
474 ConstructorBodyElement body = element; 495 ConstructorBodyElement body = element;
475 thisEnclosingElement = body.constructor; 496 thisEnclosingElement = body.constructor;
476 } 497 }
477 thisElement = new ThisElement(thisEnclosingElement); 498 thisElement = new ThisElement(thisEnclosingElement);
478 } 499 }
479 closureData = new ClosureClassMap(null, null, null, thisElement); 500 closureData = new ClosureClassMap(null, null, null, thisElement);
480 } 501 }
502 closureMappingCache[node] = closureData;
481 503
482 inNewScope(node, () { 504 inNewScope(node, () {
483 // We have to declare the implicit 'this' parameter. 505 // We have to declare the implicit 'this' parameter.
484 if (!insideClosure && closureData.thisElement !== null) { 506 if (!insideClosure && closureData.thisElement !== null) {
485 declareLocal(closureData.thisElement); 507 declareLocal(closureData.thisElement);
486 } 508 }
487 // If we are inside a named closure we have to declare ourselve. For 509 // If we are inside a named closure we have to declare ourselve. For
488 // simplicity we declare the local even if the closure does not have a 510 // simplicity we declare the local even if the closure does not have a
489 // name. 511 // name.
490 // It will simply not be used. 512 // It will simply not be used.
491 if (insideClosure) { 513 if (insideClosure) {
492 declareLocal(element); 514 declareLocal(element);
493 } 515 }
494 516
495 // TODO(ahe): This is problematic. The backend should not repeat 517 // TODO(ahe): This is problematic. The backend should not repeat
496 // the work of the resolver. It is the resolver's job to create 518 // the work of the resolver. It is the resolver's job to create
497 // parameters, etc. Other phases should only visit statements. 519 // parameters, etc. Other phases should only visit statements.
498 // TODO(floitsch): we avoid visiting the initializers on purpose so that 520 // TODO(floitsch): we avoid visiting the initializers on purpose so that
499 // we get an error-message later in the builder. 521 // we get an error-message later in the builder.
500 if (node.parameters !== null) node.parameters.accept(this); 522 if (node.parameters !== null) node.parameters.accept(this);
501 if (node.body !== null) node.body.accept(this); 523 if (node.body !== null) node.body.accept(this);
502 }); 524 });
503 525
504 closureMappingCache[node] = closureData;
505 526
506 ClosureClassMap savedClosureData = closureData; 527 ClosureClassMap savedClosureData = closureData;
507 bool savedInsideClosure = insideClosure; 528 bool savedInsideClosure = insideClosure;
508 529
509 // Restore old values. 530 // Restore old values.
510 insideClosure = oldInsideClosure; 531 insideClosure = oldInsideClosure;
511 closureData = oldClosureData; 532 closureData = oldClosureData;
512 currentFunctionElement = oldFunctionElement; 533 currentFunctionElement = oldFunctionElement;
513 534
514 // Mark all free variables as captured and use them in the outer function. 535 // Mark all free variables as captured and use them in the outer function.
(...skipping 16 matching lines...) Expand all
531 } 552 }
532 553
533 visitTryStatement(TryStatement node) { 554 visitTryStatement(TryStatement node) {
534 // TODO(ngeoffray): implement finer grain state. 555 // TODO(ngeoffray): implement finer grain state.
535 bool oldInTryStatement = inTryStatement; 556 bool oldInTryStatement = inTryStatement;
536 inTryStatement = true; 557 inTryStatement = true;
537 node.visitChildren(this); 558 node.visitChildren(this);
538 inTryStatement = oldInTryStatement; 559 inTryStatement = oldInTryStatement;
539 } 560 }
540 } 561 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/compile_time_constants.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698