| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'cps_fragment.dart' show CpsFragment; | 7 import 'cps_fragment.dart' show CpsFragment; |
| 8 import '../constants/values.dart' as values; | 8 import '../constants/values.dart' as values; |
| 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 abstract class Expression extends Node { | 57 abstract class Expression extends Node { |
| 58 InteriorNode get parent; // Only InteriorNodes may contain expressions. | 58 InteriorNode get parent; // Only InteriorNodes may contain expressions. |
| 59 | 59 |
| 60 Expression plug(Expression expr) => throw 'impossible'; | 60 Expression plug(Expression expr) => throw 'impossible'; |
| 61 | 61 |
| 62 /// The next expression in the basic block. | 62 /// The next expression in the basic block. |
| 63 /// | 63 /// |
| 64 /// For [InteriorExpression]s this is the body, for [CallExpressions] it is | 64 /// For [InteriorExpression]s this is the body, for [CallExpressions] it is |
| 65 /// the body of the continuation, and for [TailExpressions] it is `null`. | 65 /// the body of the continuation, and for [TailExpressions] it is `null`. |
| 66 Expression get next; | 66 Expression get next; |
| 67 |
| 68 accept(BlockVisitor visitor); |
| 67 } | 69 } |
| 68 | 70 |
| 69 /// Represents a node with a child node, which can be accessed through the | 71 /// Represents a node with a child node, which can be accessed through the |
| 70 /// `body` member. A typical usage is when removing a node from the CPS graph: | 72 /// `body` member. A typical usage is when removing a node from the CPS graph: |
| 71 /// | 73 /// |
| 72 /// Node child = node.body; | 74 /// Node child = node.body; |
| 73 /// InteriorNode parent = node.parent; | 75 /// InteriorNode parent = node.parent; |
| 74 /// | 76 /// |
| 75 /// child.parent = parent; | 77 /// child.parent = parent; |
| 76 /// parent.body = child; | 78 /// parent.body = child; |
| 77 abstract class InteriorNode extends Node { | 79 abstract class InteriorNode extends Node { |
| 78 Expression get body; | 80 Expression get body; |
| 79 void set body(Expression body); | 81 void set body(Expression body); |
| 82 |
| 83 accept(BlockVisitor visitor); |
| 80 } | 84 } |
| 81 | 85 |
| 82 /// An expression that creates new bindings and continues evaluation in | 86 /// An expression that creates new bindings and continues evaluation in |
| 83 /// a subexpression. | 87 /// a subexpression. |
| 84 /// | 88 /// |
| 85 /// The interior expressions are [LetPrim], [LetCont], [LetHandler], and | 89 /// The interior expressions are [LetPrim], [LetCont], [LetHandler], and |
| 86 /// [LetMutable]. | 90 /// [LetMutable]. |
| 87 abstract class InteriorExpression extends Expression implements InteriorNode { | 91 abstract class InteriorExpression extends Expression implements InteriorNode { |
| 88 Expression get next => body; | 92 Expression get next => body; |
| 89 | 93 |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 Primitive primitive; | 367 Primitive primitive; |
| 364 Expression body; | 368 Expression body; |
| 365 | 369 |
| 366 LetPrim(this.primitive, [this.body = null]); | 370 LetPrim(this.primitive, [this.body = null]); |
| 367 | 371 |
| 368 Expression plug(Expression expr) { | 372 Expression plug(Expression expr) { |
| 369 assert(body == null); | 373 assert(body == null); |
| 370 return body = expr; | 374 return body = expr; |
| 371 } | 375 } |
| 372 | 376 |
| 373 accept(Visitor visitor) => visitor.visitLetPrim(this); | 377 accept(BlockVisitor visitor) => visitor.visitLetPrim(this); |
| 374 | 378 |
| 375 void setParentPointers() { | 379 void setParentPointers() { |
| 376 primitive.parent = this; | 380 primitive.parent = this; |
| 377 if (body != null) body.parent = this; | 381 if (body != null) body.parent = this; |
| 378 } | 382 } |
| 379 } | 383 } |
| 380 | 384 |
| 381 /// Binding continuations. | 385 /// Binding continuations. |
| 382 /// | 386 /// |
| 383 /// let cont k0(v0 ...) = E0 | 387 /// let cont k0(v0 ...) = E0 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 403 | 407 |
| 404 LetCont.many(this.continuations, this.body); | 408 LetCont.many(this.continuations, this.body); |
| 405 | 409 |
| 406 Expression plug(Expression expr) { | 410 Expression plug(Expression expr) { |
| 407 assert(continuations != null && | 411 assert(continuations != null && |
| 408 continuations.isNotEmpty && | 412 continuations.isNotEmpty && |
| 409 continuations.first.body == null); | 413 continuations.first.body == null); |
| 410 return continuations.first.body = expr; | 414 return continuations.first.body = expr; |
| 411 } | 415 } |
| 412 | 416 |
| 413 accept(Visitor visitor) => visitor.visitLetCont(this); | 417 accept(BlockVisitor visitor) => visitor.visitLetCont(this); |
| 414 | 418 |
| 415 void setParentPointers() { | 419 void setParentPointers() { |
| 416 _setParentsOnNodes(continuations, this); | 420 _setParentsOnNodes(continuations, this); |
| 417 if (body != null) body.parent = this; | 421 if (body != null) body.parent = this; |
| 418 } | 422 } |
| 419 } | 423 } |
| 420 | 424 |
| 421 // Binding an exception handler. | 425 // Binding an exception handler. |
| 422 // | 426 // |
| 423 // let handler h(v0, v1) = E0 in E1 | 427 // let handler h(v0, v1) = E0 in E1 |
| 424 // | 428 // |
| 425 // The handler is a two-argument (exception, stack trace) continuation which | 429 // The handler is a two-argument (exception, stack trace) continuation which |
| 426 // is implicitly the error continuation of all the code in its body E1. | 430 // is implicitly the error continuation of all the code in its body E1. |
| 427 // [LetHandler] differs from a [LetCont] binding in that it (1) has the | 431 // [LetHandler] differs from a [LetCont] binding in that it (1) has the |
| 428 // runtime semantics of pushing/popping a handler from the dynamic exception | 432 // runtime semantics of pushing/popping a handler from the dynamic exception |
| 429 // handler stack and (2) it does not have any explicit invocations. | 433 // handler stack and (2) it does not have any explicit invocations. |
| 430 class LetHandler extends InteriorExpression { | 434 class LetHandler extends InteriorExpression { |
| 431 Continuation handler; | 435 Continuation handler; |
| 432 Expression body; | 436 Expression body; |
| 433 | 437 |
| 434 LetHandler(this.handler, this.body); | 438 LetHandler(this.handler, this.body); |
| 435 | 439 |
| 436 accept(Visitor visitor) => visitor.visitLetHandler(this); | 440 accept(BlockVisitor visitor) => visitor.visitLetHandler(this); |
| 437 | 441 |
| 438 void setParentPointers() { | 442 void setParentPointers() { |
| 439 handler.parent = this; | 443 handler.parent = this; |
| 440 if (body != null) body.parent = this; | 444 if (body != null) body.parent = this; |
| 441 } | 445 } |
| 442 } | 446 } |
| 443 | 447 |
| 444 /// Binding mutable variables. | 448 /// Binding mutable variables. |
| 445 /// | 449 /// |
| 446 /// let mutable v = P in E | 450 /// let mutable v = P in E |
| 447 /// | 451 /// |
| 448 /// [MutableVariable]s can be seen as ref cells that are not first-class | 452 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 449 /// values. They are therefore not [Primitive]s and not bound by [LetPrim] | 453 /// values. They are therefore not [Primitive]s and not bound by [LetPrim] |
| 450 /// to prevent unrestricted use of references to them. During one-pass | 454 /// to prevent unrestricted use of references to them. During one-pass |
| 451 /// construction, a [LetMutable] with an empty body is use to represent the | 455 /// construction, a [LetMutable] with an empty body is use to represent the |
| 452 /// one-hole context 'let mutable v = P in []'. | 456 /// one-hole context 'let mutable v = P in []'. |
| 453 class LetMutable extends InteriorExpression { | 457 class LetMutable extends InteriorExpression { |
| 454 final MutableVariable variable; | 458 final MutableVariable variable; |
| 455 final Reference<Primitive> value; | 459 final Reference<Primitive> value; |
| 456 Expression body; | 460 Expression body; |
| 457 | 461 |
| 458 LetMutable(this.variable, Primitive value) | 462 LetMutable(this.variable, Primitive value) |
| 459 : this.value = new Reference<Primitive>(value); | 463 : this.value = new Reference<Primitive>(value); |
| 460 | 464 |
| 461 Expression plug(Expression expr) { | 465 Expression plug(Expression expr) { |
| 462 return body = expr; | 466 return body = expr; |
| 463 } | 467 } |
| 464 | 468 |
| 465 accept(Visitor visitor) => visitor.visitLetMutable(this); | 469 accept(BlockVisitor visitor) => visitor.visitLetMutable(this); |
| 466 | 470 |
| 467 void setParentPointers() { | 471 void setParentPointers() { |
| 468 variable.parent = this; | 472 variable.parent = this; |
| 469 value.parent = this; | 473 value.parent = this; |
| 470 if (body != null) body.parent = this; | 474 if (body != null) body.parent = this; |
| 471 } | 475 } |
| 472 } | 476 } |
| 473 | 477 |
| 474 enum CallingConvention { | 478 enum CallingConvention { |
| 475 /// JS receiver is the Dart receiver, there are no extra arguments. | 479 /// JS receiver is the Dart receiver, there are no extra arguments. |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 | 1049 |
| 1046 /// Throw a value. | 1050 /// Throw a value. |
| 1047 /// | 1051 /// |
| 1048 /// Throw is an expression, i.e., it always occurs in tail position with | 1052 /// Throw is an expression, i.e., it always occurs in tail position with |
| 1049 /// respect to a body or expression. | 1053 /// respect to a body or expression. |
| 1050 class Throw extends TailExpression { | 1054 class Throw extends TailExpression { |
| 1051 Reference<Primitive> value; | 1055 Reference<Primitive> value; |
| 1052 | 1056 |
| 1053 Throw(Primitive value) : value = new Reference<Primitive>(value); | 1057 Throw(Primitive value) : value = new Reference<Primitive>(value); |
| 1054 | 1058 |
| 1055 accept(Visitor visitor) => visitor.visitThrow(this); | 1059 accept(BlockVisitor visitor) => visitor.visitThrow(this); |
| 1056 | 1060 |
| 1057 void setParentPointers() { | 1061 void setParentPointers() { |
| 1058 value.parent = this; | 1062 value.parent = this; |
| 1059 } | 1063 } |
| 1060 } | 1064 } |
| 1061 | 1065 |
| 1062 /// Rethrow | 1066 /// Rethrow |
| 1063 /// | 1067 /// |
| 1064 /// Rethrow can only occur inside a continuation bound by [LetHandler]. It | 1068 /// Rethrow can only occur inside a continuation bound by [LetHandler]. It |
| 1065 /// implicitly throws the exception parameter of the enclosing handler with | 1069 /// implicitly throws the exception parameter of the enclosing handler with |
| 1066 /// the same stack trace as the enclosing handler. | 1070 /// the same stack trace as the enclosing handler. |
| 1067 class Rethrow extends TailExpression { | 1071 class Rethrow extends TailExpression { |
| 1068 accept(Visitor visitor) => visitor.visitRethrow(this); | 1072 accept(BlockVisitor visitor) => visitor.visitRethrow(this); |
| 1069 void setParentPointers() {} | 1073 void setParentPointers() {} |
| 1070 } | 1074 } |
| 1071 | 1075 |
| 1072 /// An expression that is known to be unreachable. | 1076 /// An expression that is known to be unreachable. |
| 1073 /// | 1077 /// |
| 1074 /// This can be placed as the body of a call continuation, when the caller is | 1078 /// This can be placed as the body of a call continuation, when the caller is |
| 1075 /// known never to invoke it, e.g. because the calling expression always throws. | 1079 /// known never to invoke it, e.g. because the calling expression always throws. |
| 1076 class Unreachable extends TailExpression { | 1080 class Unreachable extends TailExpression { |
| 1077 accept(Visitor visitor) => visitor.visitUnreachable(this); | 1081 accept(BlockVisitor visitor) => visitor.visitUnreachable(this); |
| 1078 void setParentPointers() {} | 1082 void setParentPointers() {} |
| 1079 } | 1083 } |
| 1080 | 1084 |
| 1081 /// Gets the value from a [MutableVariable]. | 1085 /// Gets the value from a [MutableVariable]. |
| 1082 /// | 1086 /// |
| 1083 /// [MutableVariable]s can be seen as ref cells that are not first-class | 1087 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 1084 /// values. A [LetPrim] with a [GetMutable] can then be seen as: | 1088 /// values. A [LetPrim] with a [GetMutable] can then be seen as: |
| 1085 /// | 1089 /// |
| 1086 /// let prim p = ![variable] in [body] | 1090 /// let prim p = ![variable] in [body] |
| 1087 /// | 1091 /// |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 /// in later. | 1160 /// in later. |
| 1157 /// | 1161 /// |
| 1158 /// Used as a placeholder for a jump whose target is not yet created | 1162 /// Used as a placeholder for a jump whose target is not yet created |
| 1159 /// (e.g., in the translation of break and continue). | 1163 /// (e.g., in the translation of break and continue). |
| 1160 InvokeContinuation.uninitialized({this.isRecursive: false, | 1164 InvokeContinuation.uninitialized({this.isRecursive: false, |
| 1161 this.isEscapingTry: false}) | 1165 this.isEscapingTry: false}) |
| 1162 : continuation = null, | 1166 : continuation = null, |
| 1163 arguments = null, | 1167 arguments = null, |
| 1164 sourceInformation = null; | 1168 sourceInformation = null; |
| 1165 | 1169 |
| 1166 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); | 1170 accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this); |
| 1167 | 1171 |
| 1168 void setParentPointers() { | 1172 void setParentPointers() { |
| 1169 if (continuation != null) continuation.parent = this; | 1173 if (continuation != null) continuation.parent = this; |
| 1170 if (arguments != null) _setParentsOnList(arguments, this); | 1174 if (arguments != null) _setParentsOnList(arguments, this); |
| 1171 } | 1175 } |
| 1172 } | 1176 } |
| 1173 | 1177 |
| 1174 /// Choose between a pair of continuations based on a condition value. | 1178 /// Choose between a pair of continuations based on a condition value. |
| 1175 /// | 1179 /// |
| 1176 /// The two continuations must not declare any parameters. | 1180 /// The two continuations must not declare any parameters. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1195 isStrictCheck = true; | 1199 isStrictCheck = true; |
| 1196 | 1200 |
| 1197 Branch.loose(Primitive condition, | 1201 Branch.loose(Primitive condition, |
| 1198 Continuation trueCont, | 1202 Continuation trueCont, |
| 1199 Continuation falseCont) | 1203 Continuation falseCont) |
| 1200 : this.condition = new Reference<Primitive>(condition), | 1204 : this.condition = new Reference<Primitive>(condition), |
| 1201 trueContinuation = new Reference<Continuation>(trueCont), | 1205 trueContinuation = new Reference<Continuation>(trueCont), |
| 1202 falseContinuation = new Reference<Continuation>(falseCont), | 1206 falseContinuation = new Reference<Continuation>(falseCont), |
| 1203 this.isStrictCheck = false; | 1207 this.isStrictCheck = false; |
| 1204 | 1208 |
| 1205 accept(Visitor visitor) => visitor.visitBranch(this); | 1209 accept(BlockVisitor visitor) => visitor.visitBranch(this); |
| 1206 | 1210 |
| 1207 void setParentPointers() { | 1211 void setParentPointers() { |
| 1208 condition.parent = this; | 1212 condition.parent = this; |
| 1209 trueContinuation.parent = this; | 1213 trueContinuation.parent = this; |
| 1210 falseContinuation.parent = this; | 1214 falseContinuation.parent = this; |
| 1211 } | 1215 } |
| 1212 } | 1216 } |
| 1213 | 1217 |
| 1214 /// Directly assigns to a field on a given object. | 1218 /// Directly assigns to a field on a given object. |
| 1215 class SetField extends Primitive { | 1219 class SetField extends Primitive { |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 bool isRecursive; | 1693 bool isRecursive; |
| 1690 | 1694 |
| 1691 bool get isReturnContinuation => body == null; | 1695 bool get isReturnContinuation => body == null; |
| 1692 | 1696 |
| 1693 Continuation(this.parameters, {this.isRecursive: false}); | 1697 Continuation(this.parameters, {this.isRecursive: false}); |
| 1694 | 1698 |
| 1695 Continuation.retrn() | 1699 Continuation.retrn() |
| 1696 : parameters = <Parameter>[new Parameter(null)], | 1700 : parameters = <Parameter>[new Parameter(null)], |
| 1697 isRecursive = false; | 1701 isRecursive = false; |
| 1698 | 1702 |
| 1699 accept(Visitor visitor) => visitor.visitContinuation(this); | 1703 accept(BlockVisitor visitor) => visitor.visitContinuation(this); |
| 1700 | 1704 |
| 1701 void setParentPointers() { | 1705 void setParentPointers() { |
| 1702 _setParentsOnNodes(parameters, this); | 1706 _setParentsOnNodes(parameters, this); |
| 1703 if (body != null) body.parent = this; | 1707 if (body != null) body.parent = this; |
| 1704 } | 1708 } |
| 1705 } | 1709 } |
| 1706 | 1710 |
| 1707 /// Common interface for [Primitive] and [MutableVariable]. | 1711 /// Common interface for [Primitive] and [MutableVariable]. |
| 1708 abstract class Variable<T extends Variable<T>> extends Definition<T> { | 1712 abstract class Variable<T extends Variable<T>> extends Definition<T> { |
| 1709 /// Type of value held in the variable. | 1713 /// Type of value held in the variable. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 final List<Parameter> parameters; | 1748 final List<Parameter> parameters; |
| 1745 final Continuation returnContinuation; | 1749 final Continuation returnContinuation; |
| 1746 Expression body; | 1750 Expression body; |
| 1747 | 1751 |
| 1748 FunctionDefinition(this.element, | 1752 FunctionDefinition(this.element, |
| 1749 this.thisParameter, | 1753 this.thisParameter, |
| 1750 this.parameters, | 1754 this.parameters, |
| 1751 this.returnContinuation, | 1755 this.returnContinuation, |
| 1752 this.body); | 1756 this.body); |
| 1753 | 1757 |
| 1754 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); | 1758 accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this); |
| 1755 | 1759 |
| 1756 void setParentPointers() { | 1760 void setParentPointers() { |
| 1757 if (thisParameter != null) thisParameter.parent = this; | 1761 if (thisParameter != null) thisParameter.parent = this; |
| 1758 _setParentsOnNodes(parameters, this); | 1762 _setParentsOnNodes(parameters, this); |
| 1759 returnContinuation.parent = this; | 1763 returnContinuation.parent = this; |
| 1760 if (body != null) body.parent = this; | 1764 if (body != null) body.parent = this; |
| 1761 } | 1765 } |
| 1762 } | 1766 } |
| 1763 | 1767 |
| 1764 /// Converts the internal representation of a type to a Dart object of type | 1768 /// Converts the internal representation of a type to a Dart object of type |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 node.parent = parent; | 1890 node.parent = parent; |
| 1887 } | 1891 } |
| 1888 } | 1892 } |
| 1889 | 1893 |
| 1890 void _setParentsOnList(List<Reference> nodes, Node parent) { | 1894 void _setParentsOnList(List<Reference> nodes, Node parent) { |
| 1891 for (Reference node in nodes) { | 1895 for (Reference node in nodes) { |
| 1892 node.parent = parent; | 1896 node.parent = parent; |
| 1893 } | 1897 } |
| 1894 } | 1898 } |
| 1895 | 1899 |
| 1896 abstract class Visitor<T> { | 1900 /// Visitor for block-level traversals that do not need to dispatch on |
| 1901 /// primitives. |
| 1902 abstract class BlockVisitor<T> { |
| 1903 const BlockVisitor(); |
| 1904 |
| 1905 T visit(Node node) => node.accept(this); |
| 1906 |
| 1907 // Block headers. |
| 1908 T visitFunctionDefinition(FunctionDefinition node) => null; |
| 1909 T visitContinuation(Continuation node) => null; |
| 1910 |
| 1911 // Interior expressions. |
| 1912 T visitLetPrim(LetPrim node) => null; |
| 1913 T visitLetCont(LetCont node) => null; |
| 1914 T visitLetHandler(LetHandler node) => null; |
| 1915 T visitLetMutable(LetMutable node) => null; |
| 1916 |
| 1917 // Tail expressions. |
| 1918 T visitInvokeContinuation(InvokeContinuation node) => null; |
| 1919 T visitThrow(Throw node) => null; |
| 1920 T visitRethrow(Rethrow node) => null; |
| 1921 T visitBranch(Branch node) => null; |
| 1922 T visitUnreachable(Unreachable node) => null; |
| 1923 |
| 1924 /// Visits block-level nodes in lexical post-order (not post-dominator order). |
| 1925 /// |
| 1926 /// Continuations and function definitions are considered "block headers". |
| 1927 /// The block itself is the sequence of interior expressions in the body, |
| 1928 /// terminated by a tail expression. |
| 1929 /// |
| 1930 /// Each block is visited starting with its tail expression, then every |
| 1931 /// interior expression from bottom to top, and finally the block header |
| 1932 /// is visited. |
| 1933 /// |
| 1934 /// Blocks are visited in post-order, so the body of a continuation is always |
| 1935 /// processed before its non-recursive invocation sites. |
| 1936 /// |
| 1937 /// The IR may be transformed during the traversal, but only the original |
| 1938 /// nodes will be visited. |
| 1939 static void traverseInPostOrder(FunctionDefinition root, BlockVisitor v) { |
| 1940 List<Continuation> stack = <Continuation>[]; |
| 1941 List<Node> nodes = <Node>[]; |
| 1942 void walkBlock(InteriorNode block) { |
| 1943 nodes.add(block); |
| 1944 Expression node = block.body; |
| 1945 nodes.add(node); |
| 1946 while (node.next != null) { |
| 1947 if (node is LetCont) { |
| 1948 stack.addAll(node.continuations); |
| 1949 } else if (node is LetHandler) { |
| 1950 stack.add(node.handler); |
| 1951 } |
| 1952 node = node.next; |
| 1953 nodes.add(node); |
| 1954 } |
| 1955 } |
| 1956 walkBlock(root); |
| 1957 while (stack.isNotEmpty) { |
| 1958 walkBlock(stack.removeLast()); |
| 1959 } |
| 1960 nodes.reversed.forEach(v.visit); |
| 1961 } |
| 1962 } |
| 1963 |
| 1964 abstract class Visitor<T> implements BlockVisitor<T> { |
| 1897 const Visitor(); | 1965 const Visitor(); |
| 1898 | 1966 |
| 1899 T visit(Node node); | 1967 T visit(Node node); |
| 1900 | 1968 |
| 1901 // Concrete classes. | |
| 1902 T visitFunctionDefinition(FunctionDefinition node); | |
| 1903 | |
| 1904 // Expressions. | |
| 1905 T visitLetPrim(LetPrim node); | |
| 1906 T visitLetCont(LetCont node); | |
| 1907 T visitLetHandler(LetHandler node); | |
| 1908 T visitLetMutable(LetMutable node); | |
| 1909 T visitInvokeContinuation(InvokeContinuation node); | |
| 1910 T visitThrow(Throw node); | |
| 1911 T visitRethrow(Rethrow node); | |
| 1912 T visitBranch(Branch node); | |
| 1913 T visitUnreachable(Unreachable node); | |
| 1914 | |
| 1915 // Definitions. | 1969 // Definitions. |
| 1916 T visitInvokeStatic(InvokeStatic node); | 1970 T visitInvokeStatic(InvokeStatic node); |
| 1917 T visitInvokeMethod(InvokeMethod node); | 1971 T visitInvokeMethod(InvokeMethod node); |
| 1918 T visitInvokeMethodDirectly(InvokeMethodDirectly node); | 1972 T visitInvokeMethodDirectly(InvokeMethodDirectly node); |
| 1919 T visitInvokeConstructor(InvokeConstructor node); | 1973 T visitInvokeConstructor(InvokeConstructor node); |
| 1920 T visitTypeCast(TypeCast node); | 1974 T visitTypeCast(TypeCast node); |
| 1921 T visitSetMutable(SetMutable node); | 1975 T visitSetMutable(SetMutable node); |
| 1922 T visitSetStatic(SetStatic node); | 1976 T visitSetStatic(SetStatic node); |
| 1923 T visitSetField(SetField node); | 1977 T visitSetField(SetField node); |
| 1924 T visitGetLazyStatic(GetLazyStatic node); | 1978 T visitGetLazyStatic(GetLazyStatic node); |
| 1925 T visitAwait(Await node); | 1979 T visitAwait(Await node); |
| 1926 T visitYield(Yield node); | 1980 T visitYield(Yield node); |
| 1927 T visitLiteralList(LiteralList node); | 1981 T visitLiteralList(LiteralList node); |
| 1928 T visitLiteralMap(LiteralMap node); | 1982 T visitLiteralMap(LiteralMap node); |
| 1929 T visitConstant(Constant node); | 1983 T visitConstant(Constant node); |
| 1930 T visitGetMutable(GetMutable node); | 1984 T visitGetMutable(GetMutable node); |
| 1931 T visitParameter(Parameter node); | 1985 T visitParameter(Parameter node); |
| 1932 T visitContinuation(Continuation node); | |
| 1933 T visitMutableVariable(MutableVariable node); | 1986 T visitMutableVariable(MutableVariable node); |
| 1934 T visitGetStatic(GetStatic node); | 1987 T visitGetStatic(GetStatic node); |
| 1935 T visitInterceptor(Interceptor node); | 1988 T visitInterceptor(Interceptor node); |
| 1936 T visitCreateInstance(CreateInstance node); | 1989 T visitCreateInstance(CreateInstance node); |
| 1937 T visitGetField(GetField node); | 1990 T visitGetField(GetField node); |
| 1938 T visitCreateBox(CreateBox node); | 1991 T visitCreateBox(CreateBox node); |
| 1939 T visitReifyRuntimeType(ReifyRuntimeType node); | 1992 T visitReifyRuntimeType(ReifyRuntimeType node); |
| 1940 T visitReadTypeVariable(ReadTypeVariable node); | 1993 T visitReadTypeVariable(ReadTypeVariable node); |
| 1941 T visitTypeExpression(TypeExpression node); | 1994 T visitTypeExpression(TypeExpression node); |
| 1942 T visitCreateInvocationMirror(CreateInvocationMirror node); | 1995 T visitCreateInvocationMirror(CreateInvocationMirror node); |
| 1943 T visitTypeTest(TypeTest node); | 1996 T visitTypeTest(TypeTest node); |
| 1944 T visitTypeTestViaFlag(TypeTestViaFlag node); | 1997 T visitTypeTestViaFlag(TypeTestViaFlag node); |
| 1945 T visitApplyBuiltinOperator(ApplyBuiltinOperator node); | 1998 T visitApplyBuiltinOperator(ApplyBuiltinOperator node); |
| 1946 T visitApplyBuiltinMethod(ApplyBuiltinMethod node); | 1999 T visitApplyBuiltinMethod(ApplyBuiltinMethod node); |
| 1947 T visitGetLength(GetLength node); | 2000 T visitGetLength(GetLength node); |
| 1948 T visitGetIndex(GetIndex node); | 2001 T visitGetIndex(GetIndex node); |
| 1949 T visitSetIndex(SetIndex node); | 2002 T visitSetIndex(SetIndex node); |
| 1950 T visitRefinement(Refinement node); | 2003 T visitRefinement(Refinement node); |
| 1951 T visitBoundsCheck(BoundsCheck node); | 2004 T visitBoundsCheck(BoundsCheck node); |
| 1952 T visitNullCheck(NullCheck node); | 2005 T visitNullCheck(NullCheck node); |
| 1953 | |
| 1954 // Support for literal foreign code. | |
| 1955 T visitForeignCode(ForeignCode node); | 2006 T visitForeignCode(ForeignCode node); |
| 1956 } | 2007 } |
| 1957 | 2008 |
| 1958 /// Recursively visits all children of a CPS term. | 2009 /// Recursively visits all children of a CPS term. |
| 1959 /// | 2010 /// |
| 1960 /// The user of the class is responsible for avoiding stack overflows from | 2011 /// The user of the class is responsible for avoiding stack overflows from |
| 1961 /// deep recursion, e.g. by overriding methods to cut off recursion at certain | 2012 /// deep recursion, e.g. by overriding methods to cut off recursion at certain |
| 1962 /// points. | 2013 /// points. |
| 1963 /// | 2014 /// |
| 1964 /// All recursive invocations occur through the [visit] method, which the | 2015 /// All recursive invocations occur through the [visit] method, which the |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2788 plug(new Branch.loose(_definitions.getCopy(node.condition), | 2839 plug(new Branch.loose(_definitions.getCopy(node.condition), |
| 2789 _copies[node.trueContinuation.definition], | 2840 _copies[node.trueContinuation.definition], |
| 2790 _copies[node.falseContinuation.definition]) | 2841 _copies[node.falseContinuation.definition]) |
| 2791 ..isStrictCheck = node.isStrictCheck); | 2842 ..isStrictCheck = node.isStrictCheck); |
| 2792 } | 2843 } |
| 2793 | 2844 |
| 2794 visitUnreachable(Unreachable node) { | 2845 visitUnreachable(Unreachable node) { |
| 2795 plug(new Unreachable()); | 2846 plug(new Unreachable()); |
| 2796 } | 2847 } |
| 2797 } | 2848 } |
| OLD | NEW |