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

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

Issue 923013002: dart2dart: Implementation of simple try/catch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 part of tree_ir.optimization; 5 part of tree_ir.optimization;
6 6
7 /** 7 /**
8 * Performs the following transformations on the tree: 8 * Performs the following transformations on the tree:
9 * - Assignment propagation 9 * - Assignment propagation
10 * - If-to-conditional conversion 10 * - If-to-conditional conversion
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 */ 93 */
94 class StatementRewriter extends Visitor<Statement, Expression> with PassMixin { 94 class StatementRewriter extends Visitor<Statement, Expression> with PassMixin {
95 // The binding environment. The rightmost element of the list is the nearest 95 // The binding environment. The rightmost element of the list is the nearest
96 // available enclosing binding. 96 // available enclosing binding.
97 List<Assign> environment; 97 List<Assign> environment;
98 98
99 /// Substitution map for labels. Any break to a label L should be substituted 99 /// Substitution map for labels. Any break to a label L should be substituted
100 /// for a break to L' if L maps to L'. 100 /// for a break to L' if L maps to L'.
101 Map<Label, Jump> labelRedirects = <Label, Jump>{}; 101 Map<Label, Jump> labelRedirects = <Label, Jump>{};
102 102
103 /// Returns the redirect target of [label] or [label] itself if it should not 103 // The successor statements for labeled statements that have only one break
karlklose 2015/02/16 10:15:48 Use '///'.
104 // from them are normally rewritten inline at the site of the break. This is
105 // not safe if the code would be move inside the scope of an exception
karlklose 2015/02/16 10:15:48 'move' -> 'moved'.
106 // handler (i.e., if the code would be moved into a try from outside it.
karlklose 2015/02/16 10:15:48 Missing ')'.
Kevin Millikin (Google) 2015/02/25 11:06:36 That's embarassing for a Lisper.
107 List<Label> safeForHandlers = <Label>[];
108
109 /// Returns the redirect target of [jump] or [jump] itself if it should not
104 /// be redirected. 110 /// be redirected.
105 Jump redirect(Jump jump) { 111 Jump redirect(Jump jump) {
106 Jump newJump = labelRedirects[jump.target]; 112 Jump newJump = labelRedirects[jump.target];
107 return newJump != null ? newJump : jump; 113 return newJump != null ? newJump : jump;
108 } 114 }
109 115
110 116
111 rewriteExecutableDefinition(ExecutableDefinition definition) { 117 rewriteExecutableDefinition(ExecutableDefinition definition) {
112 definition.body = rewriteInEmptyEnvironment(definition.body); 118 definition.body = rewriteInEmptyEnvironment(definition.body);
113 } 119 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 node.value = visitExpression(node.value); 264 node.value = visitExpression(node.value);
259 return node; 265 return node;
260 } 266 }
261 267
262 268
263 Statement visitBreak(Break node) { 269 Statement visitBreak(Break node) {
264 // Redirect through chain of breaks. 270 // Redirect through chain of breaks.
265 // Note that useCount was accounted for at visitLabeledStatement. 271 // Note that useCount was accounted for at visitLabeledStatement.
266 // Note redirect may return either a Break or Continue statement. 272 // Note redirect may return either a Break or Continue statement.
267 Jump jump = redirect(node); 273 Jump jump = redirect(node);
268 if (jump is Break && jump.target.useCount == 1) { 274 if (jump is Break &&
275 jump.target.useCount == 1 &&
276 safeForHandlers.contains(jump.target)) {
asgerf 2015/02/20 10:10:07 Isn't this a bit expensive? It looks like a quadra
Kevin Millikin (Google) 2015/02/25 11:06:36 I don't think it's best to add only singly-used la
asgerf 2015/02/25 11:55:11 Ah, I forgot the use-counts on labels change durin
269 --jump.target.useCount; 277 --jump.target.useCount;
270 return visitStatement(jump.target.binding.next); 278 return visitStatement(jump.target.binding.next);
271 } 279 }
272 return jump; 280 return jump;
273 } 281 }
274 282
275 Statement visitContinue(Continue node) { 283 Statement visitContinue(Continue node) {
276 return node; 284 return node;
277 } 285 }
278 286
279 Statement visitLabeledStatement(LabeledStatement node) { 287 Statement visitLabeledStatement(LabeledStatement node) {
280 if (node.next is Jump) { 288 if (node.next is Jump) {
281 // Eliminate label if next is a break or continue statement 289 // Eliminate label if next is a break or continue statement
282 // Breaks to this label are redirected to the outer label. 290 // Breaks to this label are redirected to the outer label.
283 // Note that breakCount for the two labels is updated proactively here 291 // Note that breakCount for the two labels is updated proactively here
284 // so breaks can reliably tell if they should inline their target. 292 // so breaks can reliably tell if they should inline their target.
285 Jump next = node.next; 293 Jump next = node.next;
286 Jump newJump = redirect(next); 294 Jump newJump = redirect(next);
287 labelRedirects[node.label] = newJump; 295 labelRedirects[node.label] = newJump;
288 newJump.target.useCount += node.label.useCount - 1; 296 newJump.target.useCount += node.label.useCount - 1;
289 node.label.useCount = 0; 297 node.label.useCount = 0;
290 Statement result = visitStatement(node.body); 298 Statement result = visitStatement(node.body);
291 labelRedirects.remove(node.label); // Save some space. 299 labelRedirects.remove(node.label); // Save some space.
292 return result; 300 return result;
293 } 301 }
294 302
303 safeForHandlers.add(node.label);
295 node.body = visitStatement(node.body); 304 node.body = visitStatement(node.body);
305 safeForHandlers.removeLast();
296 306
297 if (node.label.useCount == 0) { 307 if (node.label.useCount == 0) {
298 // Eliminate the label if next was inlined at a break 308 // Eliminate the label if next was inlined at a break
299 return node.body; 309 return node.body;
300 } 310 }
301 311
302 // Do not propagate assignments into the successor statements, since they 312 // Do not propagate assignments into the successor statements, since they
303 // may be overwritten by assignments in the body. 313 // may be overwritten by assignments in the body.
304 List<Assign> savedEnvironment = environment; 314 List<Assign> savedEnvironment = environment;
305 environment = <Assign>[]; 315 environment = <Assign>[];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 assert(environment.isEmpty); 361 assert(environment.isEmpty);
352 environment = savedEnvironment; 362 environment = savedEnvironment;
353 return node; 363 return node;
354 } 364 }
355 365
356 Statement visitWhileCondition(WhileCondition node) { 366 Statement visitWhileCondition(WhileCondition node) {
357 // Not introduced yet 367 // Not introduced yet
358 throw "Unexpected WhileCondition in StatementRewriter"; 368 throw "Unexpected WhileCondition in StatementRewriter";
359 } 369 }
360 370
371 Statement visitTryStatement(TryStatement node) {
372 List<Label> saved = safeForHandlers;
373 safeForHandlers = <Label>[];
374 node.tryBody = visitStatement(node.tryBody);
375 safeForHandlers = saved;
376 node.catchBody = visitStatement(node.catchBody);
377 return node;
378 }
379
361 Expression visitConstant(Constant node) { 380 Expression visitConstant(Constant node) {
362 return node; 381 return node;
363 } 382 }
364 383
365 Expression visitThis(This node) { 384 Expression visitThis(This node) {
366 return node; 385 return node;
367 } 386 }
368 387
369 Expression visitReifyTypeVar(ReifyTypeVar node) { 388 Expression visitReifyTypeVar(ReifyTypeVar node) {
370 return node; 389 return node;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 } 609 }
591 610
592 Expression makeCondition(Expression e, bool polarity) { 611 Expression makeCondition(Expression e, bool polarity) {
593 return polarity ? e : new Not(e); 612 return polarity ? e : new Not(e);
594 } 613 }
595 614
596 Statement getBranch(If node, bool polarity) { 615 Statement getBranch(If node, bool polarity) {
597 return polarity ? node.thenStatement : node.elseStatement; 616 return polarity ? node.thenStatement : node.elseStatement;
598 } 617 }
599 } 618 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698