| 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 |