OLD | NEW |
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 library tree_ir_nodes; | 5 library tree_ir_nodes; |
6 | 6 |
7 import '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; |
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 final FunctionDefinition definition; | 439 final FunctionDefinition definition; |
440 | 440 |
441 FunctionExpression(this.definition); | 441 FunctionExpression(this.definition); |
442 | 442 |
443 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); | 443 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); |
444 accept1(ExpressionVisitor1 visitor, arg) { | 444 accept1(ExpressionVisitor1 visitor, arg) { |
445 return visitor.visitFunctionExpression(this, arg); | 445 return visitor.visitFunctionExpression(this, arg); |
446 } | 446 } |
447 } | 447 } |
448 | 448 |
449 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition]. | 449 /// A [LabeledStatement] or [WhileTrue] or [For]. |
450 abstract class JumpTarget extends Statement { | 450 abstract class JumpTarget extends Statement { |
451 Label get label; | 451 Label get label; |
452 Statement get body; | 452 Statement get body; |
453 } | 453 } |
454 | 454 |
455 /** | 455 /** |
456 * A labeled statement. Breaks to the label within the labeled statement | 456 * A labeled statement. Breaks to the label within the labeled statement |
457 * target the successor statement. | 457 * target the successor statement. |
458 */ | 458 */ |
459 class LabeledStatement extends JumpTarget { | 459 class LabeledStatement extends JumpTarget { |
460 Statement next; | 460 Statement next; |
461 final Label label; | 461 final Label label; |
462 Statement body; | 462 Statement body; |
463 | 463 |
464 LabeledStatement(this.label, this.body, this.next) { | 464 LabeledStatement(this.label, this.body, this.next) { |
465 assert(label.binding == null); | 465 assert(label.binding == null); |
466 label.binding = this; | 466 label.binding = this; |
467 } | 467 } |
468 | 468 |
469 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); | 469 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); |
470 accept1(StatementVisitor1 visitor, arg) { | 470 accept1(StatementVisitor1 visitor, arg) { |
471 return visitor.visitLabeledStatement(this, arg); | 471 return visitor.visitLabeledStatement(this, arg); |
472 } | 472 } |
473 } | 473 } |
474 | 474 |
475 /// A [WhileTrue] or [WhileCondition] loop. | 475 /// A [WhileTrue] or [For] loop. |
476 abstract class Loop extends JumpTarget { | 476 abstract class Loop extends JumpTarget { |
477 } | 477 } |
478 | 478 |
479 /** | 479 /** |
480 * A labeled while(true) loop. | 480 * A labeled while(true) loop. |
481 */ | 481 */ |
482 class WhileTrue extends Loop { | 482 class WhileTrue extends Loop { |
483 final Label label; | 483 final Label label; |
484 Statement body; | 484 Statement body; |
485 | 485 |
486 WhileTrue(this.label, this.body) { | 486 WhileTrue(this.label, this.body) { |
487 assert(label.binding == null); | 487 assert(label.binding == null); |
488 label.binding = this; | 488 label.binding = this; |
489 } | 489 } |
490 | 490 |
491 Statement get next => null; | 491 Statement get next => null; |
492 void set next(Statement s) => throw 'UNREACHABLE'; | 492 void set next(Statement s) => throw 'UNREACHABLE'; |
493 | 493 |
494 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); | 494 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); |
495 accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg); | 495 accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg); |
496 } | 496 } |
497 | 497 |
498 /** | 498 /** |
499 * A while loop with a condition. If the condition is false, control resumes | 499 * A loop with a condition and update expressions. If there are any update |
500 * at the [next] statement. | 500 * expressions, this generates a for loop, otherwise a while loop. |
| 501 * |
| 502 * When the condition is false, control resumes at the [next] statement. |
501 * | 503 * |
502 * It is NOT valid to target this statement with a [Break]. | 504 * It is NOT valid to target this statement with a [Break]. |
503 * The only way to reach [next] is for the condition to evaluate to false. | 505 * The only way to reach [next] is for the condition to evaluate to false. |
504 * | 506 * |
505 * [WhileCondition] statements are introduced in the [LoopRewriter] and is | 507 * [For] statements are introduced in the [LoopRewriter] and are |
506 * assumed not to occur before then. | 508 * assumed not to occur before then. |
507 */ | 509 */ |
508 class WhileCondition extends Loop { | 510 class For extends Loop { |
509 final Label label; | 511 final Label label; |
510 Expression condition; | 512 Expression condition; |
| 513 List<Expression> updates; |
511 Statement body; | 514 Statement body; |
512 Statement next; | 515 Statement next; |
513 | 516 |
514 WhileCondition(this.label, this.condition, this.body, | 517 For(this.label, |
515 this.next) { | 518 this.condition, |
| 519 this.updates, |
| 520 this.body, |
| 521 this.next) { |
516 assert(label.binding == null); | 522 assert(label.binding == null); |
517 label.binding = this; | 523 label.binding = this; |
518 } | 524 } |
519 | 525 |
520 accept(StatementVisitor visitor) => visitor.visitWhileCondition(this); | 526 accept(StatementVisitor visitor) => visitor.visitFor(this); |
521 accept1(StatementVisitor1 visitor, arg) { | 527 accept1(StatementVisitor1 visitor, arg) { |
522 return visitor.visitWhileCondition(this, arg); | 528 return visitor.visitFor(this, arg); |
523 } | 529 } |
524 } | 530 } |
525 | 531 |
526 /// A [Break] or [Continue] statement. | 532 /// A [Break] or [Continue] statement. |
527 abstract class Jump extends Statement { | 533 abstract class Jump extends Statement { |
528 Label get target; | 534 Label get target; |
529 } | 535 } |
530 | 536 |
531 /** | 537 /** |
532 * A break from an enclosing [LabeledStatement]. The break targets the | 538 * A break from an enclosing [LabeledStatement]. The break targets the |
533 * labeled statement's successor statement. | 539 * labeled statement's successor statement. |
534 */ | 540 */ |
535 class Break extends Jump { | 541 class Break extends Jump { |
536 final Label target; | 542 final Label target; |
537 | 543 |
538 Statement get next => null; | 544 Statement get next => null; |
539 void set next(Statement s) => throw 'UNREACHABLE'; | 545 void set next(Statement s) => throw 'UNREACHABLE'; |
540 | 546 |
541 Break(this.target) { | 547 Break(this.target) { |
542 ++target.useCount; | 548 ++target.useCount; |
543 } | 549 } |
544 | 550 |
545 accept(StatementVisitor visitor) => visitor.visitBreak(this); | 551 accept(StatementVisitor visitor) => visitor.visitBreak(this); |
546 accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg); | 552 accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg); |
547 } | 553 } |
548 | 554 |
549 /** | 555 /** |
550 * A continue to an enclosing [WhileTrue] or [WhileCondition] loop. | 556 * A continue to an enclosing [WhileTrue] or [For] loop. |
551 * The continue targets the loop's body. | 557 * The continue targets the loop's body. |
552 */ | 558 */ |
553 class Continue extends Jump { | 559 class Continue extends Jump { |
554 final Label target; | 560 final Label target; |
555 | 561 |
556 Statement get next => null; | 562 Statement get next => null; |
557 void set next(Statement s) => throw 'UNREACHABLE'; | 563 void set next(Statement s) => throw 'UNREACHABLE'; |
558 | 564 |
559 Continue(this.target) { | 565 Continue(this.target) { |
560 ++target.useCount; | 566 ++target.useCount; |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 abstract class StatementVisitor<S> { | 1012 abstract class StatementVisitor<S> { |
1007 S visitStatement(Statement node) => node.accept(this); | 1013 S visitStatement(Statement node) => node.accept(this); |
1008 S visitLabeledStatement(LabeledStatement node); | 1014 S visitLabeledStatement(LabeledStatement node); |
1009 S visitReturn(Return node); | 1015 S visitReturn(Return node); |
1010 S visitThrow(Throw node); | 1016 S visitThrow(Throw node); |
1011 S visitRethrow(Rethrow node); | 1017 S visitRethrow(Rethrow node); |
1012 S visitBreak(Break node); | 1018 S visitBreak(Break node); |
1013 S visitContinue(Continue node); | 1019 S visitContinue(Continue node); |
1014 S visitIf(If node); | 1020 S visitIf(If node); |
1015 S visitWhileTrue(WhileTrue node); | 1021 S visitWhileTrue(WhileTrue node); |
1016 S visitWhileCondition(WhileCondition node); | 1022 S visitFor(For node); |
1017 S visitExpressionStatement(ExpressionStatement node); | 1023 S visitExpressionStatement(ExpressionStatement node); |
1018 S visitTry(Try node); | 1024 S visitTry(Try node); |
1019 S visitUnreachable(Unreachable node); | 1025 S visitUnreachable(Unreachable node); |
1020 S visitForeignStatement(ForeignStatement node); | 1026 S visitForeignStatement(ForeignStatement node); |
1021 } | 1027 } |
1022 | 1028 |
1023 abstract class StatementVisitor1<S, A> { | 1029 abstract class StatementVisitor1<S, A> { |
1024 S visitStatement(Statement node, A arg) => node.accept1(this, arg); | 1030 S visitStatement(Statement node, A arg) => node.accept1(this, arg); |
1025 S visitLabeledStatement(LabeledStatement node, A arg); | 1031 S visitLabeledStatement(LabeledStatement node, A arg); |
1026 S visitReturn(Return node, A arg); | 1032 S visitReturn(Return node, A arg); |
1027 S visitThrow(Throw node, A arg); | 1033 S visitThrow(Throw node, A arg); |
1028 S visitRethrow(Rethrow node, A arg); | 1034 S visitRethrow(Rethrow node, A arg); |
1029 S visitBreak(Break node, A arg); | 1035 S visitBreak(Break node, A arg); |
1030 S visitContinue(Continue node, A arg); | 1036 S visitContinue(Continue node, A arg); |
1031 S visitIf(If node, A arg); | 1037 S visitIf(If node, A arg); |
1032 S visitWhileTrue(WhileTrue node, A arg); | 1038 S visitWhileTrue(WhileTrue node, A arg); |
1033 S visitWhileCondition(WhileCondition node, A arg); | 1039 S visitFor(For node, A arg); |
1034 S visitExpressionStatement(ExpressionStatement node, A arg); | 1040 S visitExpressionStatement(ExpressionStatement node, A arg); |
1035 S visitTry(Try node, A arg); | 1041 S visitTry(Try node, A arg); |
1036 S visitUnreachable(Unreachable node, A arg); | 1042 S visitUnreachable(Unreachable node, A arg); |
1037 S visitForeignStatement(ForeignStatement node, A arg); | 1043 S visitForeignStatement(ForeignStatement node, A arg); |
1038 } | 1044 } |
1039 | 1045 |
1040 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { | 1046 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
1041 visitExpression(Expression e) => e.accept(this); | 1047 visitExpression(Expression e) => e.accept(this); |
1042 visitStatement(Statement s) => s.accept(this); | 1048 visitStatement(Statement s) => s.accept(this); |
1043 | 1049 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 visitIf(If node) { | 1139 visitIf(If node) { |
1134 visitExpression(node.condition); | 1140 visitExpression(node.condition); |
1135 visitStatement(node.thenStatement); | 1141 visitStatement(node.thenStatement); |
1136 visitStatement(node.elseStatement); | 1142 visitStatement(node.elseStatement); |
1137 } | 1143 } |
1138 | 1144 |
1139 visitWhileTrue(WhileTrue node) { | 1145 visitWhileTrue(WhileTrue node) { |
1140 visitStatement(node.body); | 1146 visitStatement(node.body); |
1141 } | 1147 } |
1142 | 1148 |
1143 visitWhileCondition(WhileCondition node) { | 1149 visitFor(For node) { |
1144 visitExpression(node.condition); | 1150 visitExpression(node.condition); |
| 1151 node.updates.forEach(visitExpression); |
1145 visitStatement(node.body); | 1152 visitStatement(node.body); |
1146 visitStatement(node.next); | 1153 visitStatement(node.next); |
1147 } | 1154 } |
1148 | 1155 |
1149 visitExpressionStatement(ExpressionStatement inputNode) { | 1156 visitExpressionStatement(ExpressionStatement inputNode) { |
1150 // Iterate over chains of expression statements to avoid deep recursion. | 1157 // Iterate over chains of expression statements to avoid deep recursion. |
1151 Statement node = inputNode; | 1158 Statement node = inputNode; |
1152 while (node is ExpressionStatement) { | 1159 while (node is ExpressionStatement) { |
1153 ExpressionStatement stmt = node; | 1160 ExpressionStatement stmt = node; |
1154 visitExpression(stmt.expression); | 1161 visitExpression(stmt.expression); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 node.thenStatement = visitStatement(node.thenStatement); | 1371 node.thenStatement = visitStatement(node.thenStatement); |
1365 node.elseStatement = visitStatement(node.elseStatement); | 1372 node.elseStatement = visitStatement(node.elseStatement); |
1366 return node; | 1373 return node; |
1367 } | 1374 } |
1368 | 1375 |
1369 visitWhileTrue(WhileTrue node) { | 1376 visitWhileTrue(WhileTrue node) { |
1370 node.body = visitStatement(node.body); | 1377 node.body = visitStatement(node.body); |
1371 return node; | 1378 return node; |
1372 } | 1379 } |
1373 | 1380 |
1374 visitWhileCondition(WhileCondition node) { | 1381 visitFor(For node) { |
1375 node.condition = visitExpression(node.condition); | 1382 node.condition = visitExpression(node.condition); |
| 1383 _replaceExpressions(node.updates); |
1376 node.body = visitStatement(node.body); | 1384 node.body = visitStatement(node.body); |
1377 node.next = visitStatement(node.next); | 1385 node.next = visitStatement(node.next); |
1378 return node; | 1386 return node; |
1379 } | 1387 } |
1380 | 1388 |
1381 visitExpressionStatement(ExpressionStatement node) { | 1389 visitExpressionStatement(ExpressionStatement node) { |
1382 // Iterate over chains of expression statements to avoid deep recursion. | 1390 // Iterate over chains of expression statements to avoid deep recursion. |
1383 Statement first = node; | 1391 Statement first = node; |
1384 while (true) { | 1392 while (true) { |
1385 node.expression = visitExpression(node.expression); | 1393 node.expression = visitExpression(node.expression); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1526 | 1534 |
1527 /// Number of uses of the current fallthrough target. | 1535 /// Number of uses of the current fallthrough target. |
1528 int get useCount => _stack.last.useCount; | 1536 int get useCount => _stack.last.useCount; |
1529 | 1537 |
1530 /// Indicate that a statement will fall through to the current fallthrough | 1538 /// Indicate that a statement will fall through to the current fallthrough |
1531 /// target. | 1539 /// target. |
1532 void use() { | 1540 void use() { |
1533 ++_stack.last.useCount; | 1541 ++_stack.last.useCount; |
1534 } | 1542 } |
1535 } | 1543 } |
OLD | NEW |