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