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

Side by Side Diff: pkg/compiler/lib/src/closure.dart

Issue 1009053005: Do not use the namer for naming closure elements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Better naming for closure/box fields. Created 5 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.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 "dart2jslib.dart"; 8 import "dart2jslib.dart";
9 import "dart_types.dart"; 9 import "dart_types.dart";
10 import "js_backend/js_backend.dart" show JavaScriptBackend; 10 import "js_backend/js_backend.dart" show JavaScriptBackend;
11 import "scanner/scannerlib.dart" show Token; 11 import "scanner/scannerlib.dart" show Token;
12 import "tree/tree.dart"; 12 import "tree/tree.dart";
13 import "util/util.dart"; 13 import "util/util.dart";
14 import "elements/modelx.dart" 14 import "elements/modelx.dart"
15 show BaseFunctionElementX, 15 show BaseFunctionElementX,
16 ClassElementX, 16 ClassElementX,
17 ElementX, 17 ElementX,
18 LocalFunctionElementX; 18 LocalFunctionElementX;
19 import "elements/visitor.dart" show ElementVisitor; 19 import "elements/visitor.dart" show ElementVisitor;
20 20
21 import 'universe/universe.dart' show 21 import 'universe/universe.dart' show
22 Universe; 22 Universe;
23 23
24 class ClosureNamer {
25 String getClosureVariableName(String name, int id) {
26 return "${name}_$id";
27 }
28
29 void forgetElement(Element element) {}
30 }
31
32 class ClosureTask extends CompilerTask { 24 class ClosureTask extends CompilerTask {
33 Map<Node, ClosureClassMap> closureMappingCache; 25 Map<Node, ClosureClassMap> closureMappingCache;
34 ClosureNamer namer; 26 ClosureTask(Compiler compiler)
35 ClosureTask(Compiler compiler, this.namer)
36 : closureMappingCache = new Map<Node, ClosureClassMap>(), 27 : closureMappingCache = new Map<Node, ClosureClassMap>(),
37 super(compiler); 28 super(compiler);
38 29
39 String get name => "Closure Simplifier"; 30 String get name => "Closure Simplifier";
40 31
41 ClosureClassMap computeClosureToClassMapping(Element element, 32 ClosureClassMap computeClosureToClassMapping(Element element,
42 Node node, 33 Node node,
43 TreeElements elements) { 34 TreeElements elements) {
44 return measure(() { 35 return measure(() {
45 ClosureClassMap cached = closureMappingCache[node]; 36 ClosureClassMap cached = closureMappingCache[node];
46 if (cached != null) return cached; 37 if (cached != null) return cached;
47 38
48 ClosureTranslator translator = 39 ClosureTranslator translator =
49 new ClosureTranslator(compiler, elements, closureMappingCache, namer); 40 new ClosureTranslator(compiler, elements, closureMappingCache);
50 41
51 // The translator will store the computed closure-mappings inside the 42 // The translator will store the computed closure-mappings inside the
52 // cache. One for given node and one for each nested closure. 43 // cache. One for given node and one for each nested closure.
53 if (node is FunctionExpression) { 44 if (node is FunctionExpression) {
54 translator.translateFunction(element, node); 45 translator.translateFunction(element, node);
55 } else if (element.isSynthesized) { 46 } else if (element.isSynthesized) {
56 return new ClosureClassMap(null, null, null, new ThisLocal(element)); 47 return new ClosureClassMap(null, null, null, new ThisLocal(element));
57 } else { 48 } else {
58 assert(element.isField); 49 assert(element.isField);
59 VariableElement field = element; 50 VariableElement field = element;
(...skipping 24 matching lines...) Expand all
84 void forgetElement(var closure) { 75 void forgetElement(var closure) {
85 ClosureClassElement cls; 76 ClosureClassElement cls;
86 if (closure is ClosureFieldElement) { 77 if (closure is ClosureFieldElement) {
87 cls = closure.closureClass; 78 cls = closure.closureClass;
88 } else if (closure is SynthesizedCallMethodElementX) { 79 } else if (closure is SynthesizedCallMethodElementX) {
89 cls = closure.closureClass; 80 cls = closure.closureClass;
90 } else { 81 } else {
91 throw new SpannableAssertionFailure( 82 throw new SpannableAssertionFailure(
92 closure, 'Not a closure: $closure (${closure.runtimeType}).'); 83 closure, 'Not a closure: $closure (${closure.runtimeType}).');
93 } 84 }
94 namer.forgetElement(cls);
95 compiler.enqueuer.codegen.forgetElement(cls); 85 compiler.enqueuer.codegen.forgetElement(cls);
96 } 86 }
97 } 87 }
98 88
99 /// Common interface for [BoxFieldElement] and [ClosureFieldElement] as 89 /// Common interface for [BoxFieldElement] and [ClosureFieldElement] as
100 /// non-elements. 90 /// non-elements.
101 abstract class CapturedVariable {} 91 abstract class CapturedVariable {}
102 92
103 // TODO(ahe): These classes continuously cause problems. We need to 93 // TODO(ahe): These classes continuously cause problems. We need to
104 // find a more general solution. 94 // find a more general solution.
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 // Keep track of the mutated local variables so that we don't need to box 442 // Keep track of the mutated local variables so that we don't need to box
453 // non-mutated variables. 443 // non-mutated variables.
454 Set<LocalVariableElement> mutatedVariables = new Set<LocalVariableElement>(); 444 Set<LocalVariableElement> mutatedVariables = new Set<LocalVariableElement>();
455 445
456 MemberElement outermostElement; 446 MemberElement outermostElement;
457 ExecutableElement executableContext; 447 ExecutableElement executableContext;
458 448
459 // The closureData of the currentFunctionElement. 449 // The closureData of the currentFunctionElement.
460 ClosureClassMap closureData; 450 ClosureClassMap closureData;
461 451
462 ClosureNamer namer;
463
464 bool insideClosure = false; 452 bool insideClosure = false;
465 453
466 ClosureTranslator(this.compiler, 454 ClosureTranslator(this.compiler,
467 this.elements, 455 this.elements,
468 this.closureMappingCache, 456 this.closureMappingCache);
469 this.namer); 457
458 /// Generate a unique name for the [id]th closure field, with proposed name
459 /// [name].
460 ///
461 /// The result is used as the name of [ClosureFieldElement]s, and must
462 /// therefore be unique to avoid breaking an invariant in the element model
463 /// (classes cannot declare multiple fields with the same name).
464 ///
465 /// Also, the names should be distinct from real field names to prevent
466 /// clashes with selectors for those fields.
467 String getClosureVariableName(String name, int id) {
468 return "_captured_${name}_$id";
469 }
470
471 /// Generate a unique name for the [id]th box field, with proposed name
472 /// [name].
473 ///
474 /// The result is used as the name of [BoxFieldElement]s, and must
475 /// therefore be unique to avoid breaking an invariant in the element model
476 /// (classes cannot declare multiple fields with the same name).
477 ///
478 /// Also, the names should be distinct from real field names to prevent
479 /// clashes with selectors for those fields.
480 String getBoxFieldName(int id) {
481 return "_box_$id";
482 }
470 483
471 bool isCapturedVariable(Local element) { 484 bool isCapturedVariable(Local element) {
472 return _capturedVariableMapping.containsKey(element); 485 return _capturedVariableMapping.containsKey(element);
473 } 486 }
474 487
475 void addCapturedVariable(Node node, Local variable) { 488 void addCapturedVariable(Node node, Local variable) {
476 if (_capturedVariableMapping[variable] != null) { 489 if (_capturedVariableMapping[variable] != null) {
477 compiler.internalError(node, 'In closure analyzer.'); 490 compiler.internalError(node, 'In closure analyzer.');
478 } 491 }
479 _capturedVariableMapping[variable] = null; 492 _capturedVariableMapping[variable] = null;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 return 1; 575 return 1;
563 } else if (b is Element) { 576 } else if (b is Element) {
564 return -1; 577 return -1;
565 } else { 578 } else {
566 return a.name.compareTo(b.name); 579 return a.name.compareTo(b.name);
567 } 580 }
568 } 581 }
569 582
570 for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) { 583 for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) {
571 int id = closureFieldCounter++; 584 int id = closureFieldCounter++;
572 String name = namer.getClosureVariableName(capturedLocal.name, id); 585 String name = getClosureVariableName(capturedLocal.name, id);
573 addClosureField(capturedLocal, name); 586 addClosureField(capturedLocal, name);
574 } 587 }
575 closureClass.reverseBackendMembers(); 588 closureClass.reverseBackendMembers();
576 } 589 }
577 } 590 }
578 591
579 void useLocal(Local variable) { 592 void useLocal(Local variable) {
580 // If the element is not declared in the current function and the element 593 // If the element is not declared in the current function and the element
581 // is not the closure itself we need to mark the element as free variable. 594 // is not the closure itself we need to mark the element as free variable.
582 // Note that the check on [insideClosure] is not just an 595 // Note that the check on [insideClosure] is not just an
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 // The boxed variables are updated in the [capturedVariableMapping]. 803 // The boxed variables are updated in the [capturedVariableMapping].
791 void attachCapturedScopeVariables(Node node) { 804 void attachCapturedScopeVariables(Node node) {
792 BoxLocal box = null; 805 BoxLocal box = null;
793 Map<LocalVariableElement, BoxFieldElement> scopeMapping = 806 Map<LocalVariableElement, BoxFieldElement> scopeMapping =
794 new Map<LocalVariableElement, BoxFieldElement>(); 807 new Map<LocalVariableElement, BoxFieldElement>();
795 808
796 void boxCapturedVariable(LocalVariableElement variable) { 809 void boxCapturedVariable(LocalVariableElement variable) {
797 if (isCapturedVariable(variable)) { 810 if (isCapturedVariable(variable)) {
798 if (box == null) { 811 if (box == null) {
799 // TODO(floitsch): construct better box names. 812 // TODO(floitsch): construct better box names.
800 String boxName = 813 String boxName = getBoxFieldName(closureFieldCounter++);
801 namer.getClosureVariableName('box', closureFieldCounter++);
802 box = new BoxLocal(boxName, executableContext); 814 box = new BoxLocal(boxName, executableContext);
803 } 815 }
804 String elementName = variable.name; 816 String elementName = variable.name;
805 String boxedName = 817 String boxedName =
806 namer.getClosureVariableName(elementName, boxedFieldCounter++); 818 getClosureVariableName(elementName, boxedFieldCounter++);
807 // TODO(kasperl): Should this be a FieldElement instead? 819 // TODO(kasperl): Should this be a FieldElement instead?
808 BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box); 820 BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box);
809 // No need to rename the fields of a box, so we give them a native name
810 // right now.
811 boxed.setFixedBackendName(boxedName);
812 scopeMapping[variable] = boxed; 821 scopeMapping[variable] = boxed;
813 setCapturedVariableBoxField(variable, boxed); 822 setCapturedVariableBoxField(variable, boxed);
814 } 823 }
815 } 824 }
816 825
817 for (LocalVariableElement variable in scopeVariables) { 826 for (LocalVariableElement variable in scopeVariables) {
818 // No need to box non-assignable elements. 827 // No need to box non-assignable elements.
819 if (!variable.isAssignable) continue; 828 if (!variable.isAssignable) continue;
820 if (!mutatedVariables.contains(variable)) continue; 829 if (!mutatedVariables.contains(variable)) continue;
821 boxCapturedVariable(variable); 830 boxCapturedVariable(variable);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1060
1052 String get name => typeVariable.name; 1061 String get name => typeVariable.name;
1053 1062
1054 int get hashCode => typeVariable.hashCode; 1063 int get hashCode => typeVariable.hashCode;
1055 1064
1056 bool operator ==(other) { 1065 bool operator ==(other) {
1057 if (other is! TypeVariableLocal) return false; 1066 if (other is! TypeVariableLocal) return false;
1058 return typeVariable == other.typeVariable; 1067 return typeVariable == other.typeVariable;
1059 } 1068 }
1060 } 1069 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698