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