Index: runtime/vm/flow_graph_builder.h |
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h |
index 08b0a8b52fde0e052115467cb20f1fe1a3f15006..f787d4629e3e379ad12db4cfe43b90841ce62363 100644 |
--- a/runtime/vm/flow_graph_builder.h |
+++ b/runtime/vm/flow_graph_builder.h |
@@ -106,6 +106,8 @@ class InlineExitCollector: public ZoneAllocated { |
}; |
+class NestedStatement; |
srdjan
2013/11/13 17:17:08
Typically all forward class declarations are done
Kevin Millikin (Google)
2013/11/13 17:47:22
I'll move it.
|
+ |
// Build a flow graph from a parsed function's AST. |
class FlowGraphBuilder: public ValueObject { |
public: |
@@ -170,11 +172,15 @@ class FlowGraphBuilder: public ValueObject { |
intptr_t args_pushed() const { return args_pushed_; } |
void add_args_pushed(intptr_t n) { args_pushed_ += n; } |
+ NestedStatement* nesting_stack() const { return nesting_stack_; } |
+ |
// When compiling for OSR, remove blocks that are not reachable from the |
// OSR entry point. |
void PruneUnreachable(); |
private: |
+ friend class NestedStatement; // Explicit access to nesting_stack_. |
+ |
intptr_t parameter_count() const { |
return num_copied_params_ + num_non_copied_params_; |
} |
@@ -204,6 +210,9 @@ class FlowGraphBuilder: public ValueObject { |
// Outgoing argument stack height. |
intptr_t args_pushed_; |
+ // A stack of enclosing nested statements. |
+ NestedStatement* nesting_stack_; |
+ |
// The deopt id of the OSR entry or Isolate::kNoDeoptId if not compiling |
// for OSR. |
const intptr_t osr_id_; |
@@ -212,6 +221,42 @@ class FlowGraphBuilder: public ValueObject { |
}; |
+// Base class for a stack of enclosing statements of interest (e.g., |
+// blocks (breakable) and loops (continuable)). |
+class NestedStatement : public ValueObject { |
Florian Schneider
2013/11/13 17:42:58
Do you actually need to declare NestedStatement he
Kevin Millikin (Google)
2013/11/13 17:47:22
It does look like a forward declaration is enough.
|
+ public: |
+ NestedStatement(FlowGraphBuilder* owner, const SourceLabel* label) |
+ : owner_(owner), |
+ label_(label), |
+ outer_(owner->nesting_stack_), |
+ break_target_(NULL) { |
+ // Push on the owner's nesting stack. |
+ owner->nesting_stack_ = this; |
+ } |
+ |
+ virtual ~NestedStatement() { |
+ // Pop from the owner's nesting stack. |
+ ASSERT(owner_->nesting_stack_ == this); |
+ owner_->nesting_stack_ = outer_; |
+ } |
+ |
+ FlowGraphBuilder* owner() const { return owner_; } |
+ const SourceLabel* label() const { return label_; } |
+ NestedStatement* outer() const { return outer_; } |
+ JoinEntryInstr* break_target() const { return break_target_; } |
+ |
+ virtual JoinEntryInstr* BreakTargetFor(SourceLabel* label); |
+ virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); |
+ |
+ private: |
+ FlowGraphBuilder* owner_; |
+ const SourceLabel* label_; |
+ NestedStatement* outer_; |
+ |
+ JoinEntryInstr* break_target_; |
+}; |
+ |
+ |
class TestGraphVisitor; |
// Translate an AstNode to a control-flow graph fragment for its effects |