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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart

Issue 1068243002: Overhaul tree IR visitor and rename IR classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add dummy use for RootVisitor and InitializerVisitor without arguments Created 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 library tree_ir.integrity; 1 library tree_ir.integrity;
2 2
3 import 'tree_ir_nodes.dart'; 3 import 'tree_ir_nodes.dart';
4 4
5 /// Performs integrity checks on the tree_ir. 5 /// Performs integrity checks on the tree_ir.
6 /// 6 ///
7 /// Should only be run for debugging purposes, not in production. 7 /// Should only be run for debugging purposes, not in production.
8 /// 8 ///
9 /// - Reference counts on must match the actual number of references. 9 /// - Reference counts on must match the actual number of references.
10 /// - Labels must be in scope when referenced. 10 /// - Labels must be in scope when referenced.
11 /// - Breaks must target a [LabeledStatement]. 11 /// - Breaks must target a [LabeledStatement].
12 /// - Continues must target a [Loop]. 12 /// - Continues must target a [Loop].
13 /// - Variables must only be used after their first assignment 13 /// - Variables must only be used after their first assignment
14 /// (checked on a best-effort basis). 14 /// (checked on a best-effort basis).
15 /// - Variables with a declaration must only be referenced in scope. 15 /// - Variables with a declaration must only be referenced in scope.
16 /// - Variables must not have more than one declaration. 16 /// - Variables must not have more than one declaration.
17 /// 17 ///
18 class CheckTreeIntegrity extends RecursiveVisitor { 18 class CheckTreeIntegrity extends RecursiveVisitor {
19 ExecutableDefinition topLevelNode; 19 RootNode topLevelNode;
20 20
21 Map<Variable, int> varReads = <Variable, int>{}; 21 Map<Variable, int> varReads = <Variable, int>{};
22 Map<Variable, int> varWrites = <Variable, int>{}; 22 Map<Variable, int> varWrites = <Variable, int>{};
23 Map<Label, int> labelUses = <Label, int>{}; 23 Map<Label, int> labelUses = <Label, int>{};
24 Map<Label, JumpTarget> label2declaration = <Label, JumpTarget>{}; 24 Map<Label, JumpTarget> label2declaration = <Label, JumpTarget>{};
25 25
26 /// Variables that are currently in scope. 26 /// Variables that are currently in scope.
27 Set<Variable> scope = new Set<Variable>(); 27 Set<Variable> scope = new Set<Variable>();
28 28
29 /// Variables for which we have seen a declaration. 29 /// Variables for which we have seen a declaration.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 } 79 }
80 80
81 visitTry(Try node) { 81 visitTry(Try node) {
82 visitStatement(node.tryBody); 82 visitStatement(node.tryBody);
83 node.catchParameters.forEach(declare); 83 node.catchParameters.forEach(declare);
84 visitStatement(node.catchBody); 84 visitStatement(node.catchBody);
85 node.catchParameters.forEach(undeclare); 85 node.catchParameters.forEach(undeclare);
86 } 86 }
87 87
88 visitFunctionDefinition(FunctionDefinition node) {
89 node.parameters.forEach(declare);
90 if (node.body != null) visitStatement(node.body);
91 node.parameters.forEach(undeclare);
92 }
93
94 visitConstructorDefinition(ConstructorDefinition node) {
95 node.parameters.forEach(declare);
96 if (node.initializers != null) node.initializers.forEach(visitInitializer);
97 if (node.body != null) visitStatement(node.body);
98 node.parameters.forEach(undeclare);
99 }
100
101 visitFunctionDeclaration(FunctionDeclaration node) { 88 visitFunctionDeclaration(FunctionDeclaration node) {
102 declare(node.variable); 89 declare(node.variable);
103 visitFunctionDefinition(node.definition); 90 checkBody(node.definition);
104 visitStatement(node.next); 91 visitStatement(node.next);
105 undeclare(node.variable); 92 undeclare(node.variable);
106 if (varWrites[node.variable] > 1) { 93 if (varWrites[node.variable] > 1) {
107 error('Assignment to function declaration ${node.variable}'); 94 error('Assignment to function declaration ${node.variable}');
108 } 95 }
109 } 96 }
110 97
111 visitJumpTargetBody(JumpTarget target) { 98 visitJumpTargetBody(JumpTarget target) {
112 Label label = target.label; 99 Label label = target.label;
113 if (label2declaration.containsKey(label)) { 100 if (label2declaration.containsKey(label)) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 visitContinue(Continue node) { 139 visitContinue(Continue node) {
153 if (!label2declaration.containsKey(node.target)) { 140 if (!label2declaration.containsKey(node.target)) {
154 error('Continue to label that is not in scope'); 141 error('Continue to label that is not in scope');
155 } 142 }
156 if (label2declaration[node.target] is! Loop) { 143 if (label2declaration[node.target] is! Loop) {
157 error('Continue to non-loop statement ${label2declaration[node.target]}'); 144 error('Continue to non-loop statement ${label2declaration[node.target]}');
158 } 145 }
159 labelUses[node.target]++; 146 labelUses[node.target]++;
160 } 147 }
161 148
149 visitInnerFunction(FunctionDefinition node) {
150 checkBody(node);
151 }
152
153 void checkBody(RootNode node) {
154 node.parameters.forEach(declare);
155 node.forEachBody(visitStatement);
156 node.parameters.forEach(undeclare);
157 }
158
162 dynamic error(String message) { 159 dynamic error(String message) {
163 throw 'Tree IR integrity violation in ${topLevelNode.element}:\n$message'; 160 throw 'Tree IR integrity violation in ${topLevelNode.element}:\n$message';
164 } 161 }
165 162
166 void check(ExecutableDefinition node) { 163 void check(RootNode node) {
167 topLevelNode = node; 164 topLevelNode = node;
168 visitExecutableDefinition(node); 165 checkBody(node);
169 166
170 // Verify reference counters for all variables. 167 // Verify reference counters for all variables.
171 List<Variable> seenVariables = new List<Variable>(); 168 List<Variable> seenVariables = new List<Variable>();
172 seenVariables.addAll(varReads.keys); 169 seenVariables.addAll(varReads.keys);
173 seenVariables.addAll(varWrites.keys); 170 seenVariables.addAll(varWrites.keys);
174 for (Variable variable in seenVariables) { 171 for (Variable variable in seenVariables) {
175 int reads = varReads.putIfAbsent(variable, () => 0); 172 int reads = varReads.putIfAbsent(variable, () => 0);
176 int writes = varWrites.putIfAbsent(variable, () => 0); 173 int writes = varWrites.putIfAbsent(variable, () => 0);
177 if (reads != variable.readCount || writes != variable.writeCount) { 174 if (reads != variable.readCount || writes != variable.writeCount) {
178 error('Invalid reference count for $variable:\n' 175 error('Invalid reference count for $variable:\n'
179 '- Variable has $reads reads and $writes writes\n' 176 '- Variable has $reads reads and $writes writes\n'
180 '- Reference count is ${variable.readCount} reads and ' 177 '- Reference count is ${variable.readCount} reads and '
181 '${variable.writeCount} writes'); 178 '${variable.writeCount} writes');
182 } 179 }
183 } 180 }
184 } 181 }
185 182
186 } 183 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698