Index: runtime/vm/ast.h |
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h |
index 7c1279b4fa58df4e01c3b4a5025664d3e6afa18f..95865d083b03d7b71ced72a08e0c5ce42ce02e23 100644 |
--- a/runtime/vm/ast.h |
+++ b/runtime/vm/ast.h |
@@ -17,6 +17,7 @@ namespace dart { |
#define FOR_EACH_NODE(V) \ |
V(Await) \ |
+ V(AwaitMarker) \ |
V(Return) \ |
V(Literal) \ |
V(Type) \ |
@@ -168,6 +169,48 @@ class AwaitNode : public AstNode { |
}; |
+// AwaitMarker nodes are used to generate markers that the FlowGraphBuilder |
+// relies on. They can occur in two kinds: |
+// 1) kNewContinuationState: A marker indicating that a new await state needs to |
+// be added to a function preamble. This type also triggers storing of the |
+// current context. |
+// 2) kTargetForContinuation: A marker indicating an entry point for the most |
+// recent generated state. |
+// |
+// In general it is expected (ASSERT) that the different kinds of markers reach |
+// the FlowGraphBuilder in alternating order. That is: |
+// <new state> -> <other nodes> -> <target> -> <other nodes> -> |
+// <new state> -> ... |
+class AwaitMarkerNode : public AstNode { |
+ public: |
+ enum MarkerType { |
+ kNewContinuationState, |
+ kTargetForContinuation, |
+ }; |
+ |
+ explicit AwaitMarkerNode(MarkerType marker_type) |
+ : AstNode(Scanner::kNoSourcePos), |
+ marker_type_(marker_type) { } |
+ |
+ void VisitChildren(AstNodeVisitor* visitor) const { } |
+ |
+ MarkerType marker_type() const { |
+ return marker_type_; |
+ } |
+ |
+ LocalScope* scope() const { return scope_; } |
+ void set_scope(LocalScope* scope) { scope_ = scope; } |
+ |
+ DECLARE_COMMON_NODE_FUNCTIONS(AwaitMarkerNode); |
+ |
+ private: |
+ MarkerType marker_type_; |
+ LocalScope* scope_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AwaitMarkerNode); |
+}; |
+ |
+ |
class SequenceNode : public AstNode { |
public: |
SequenceNode(intptr_t token_pos, LocalScope* scope) |
@@ -536,24 +579,31 @@ class PrimaryNode : public AstNode { |
DISALLOW_IMPLICIT_CONSTRUCTORS(PrimaryNode); |
}; |
- |
-// TODO(mlippautz): Implement return nodes that are used to return from a |
-// continuation. |
+// Return nodes can be of different types: |
+// * A regular return node that in the case of async functions gets replaced |
+// with appropriate completer calls. This kind is generated by dart code. |
+// * A continuation return that just returns from a function. This kind is |
+// generated by AST transformers. |
class ReturnNode : public AstNode { |
public: |
+ enum ReturnType { |
+ kRegular, |
+ kContinuation, |
+ }; |
+ |
// Return from a void function returns the null object. |
explicit ReturnNode(intptr_t token_pos) |
: AstNode(token_pos), |
value_(new LiteralNode(token_pos, Instance::ZoneHandle())), |
inlined_finally_list_(), |
- is_regular_return_(true) { } |
+ return_type_(kRegular) { } |
// Return from a non-void function. |
ReturnNode(intptr_t token_pos, |
AstNode* value) |
: AstNode(token_pos), |
value_(value), |
inlined_finally_list_(), |
- is_regular_return_(true) { |
+ return_type_(kRegular) { |
ASSERT(value_ != NULL); |
} |
@@ -578,8 +628,8 @@ class ReturnNode : public AstNode { |
void set_scope(LocalScope* scope) { scope_ = scope; } |
LocalScope* scope() const { return scope_; } |
- // Returns false if the return node is used to return from a continuation. |
- bool is_regular_return() const { return is_regular_return_; } |
+ ReturnType return_type() const { return return_type_; } |
+ void set_return_type(ReturnType type) { return_type_ = type; } |
DECLARE_COMMON_NODE_FUNCTIONS(ReturnNode); |
@@ -587,7 +637,7 @@ class ReturnNode : public AstNode { |
AstNode* value_; |
GrowableArray<InlinedFinallyNode*> inlined_finally_list_; |
LocalScope* scope_; |
- bool is_regular_return_; |
+ ReturnType return_type_; |
DISALLOW_COPY_AND_ASSIGN(ReturnNode); |
}; |