1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_CONTROL_BUILDERS_H_
6#define V8_COMPILER_CONTROL_BUILDERS_H_
7
8#include "src/v8.h"
9
10#include "src/compiler/graph-builder.h"
11#include "src/compiler/node.h"
12
13namespace v8 {
14namespace internal {
15namespace compiler {
16
17
18// Base class for all control builders. Also provides a common interface for
19// control builders to handle 'break' and 'continue' statements when they are
20// used to model breakable statements.
21class ControlBuilder {
22 public:
23  explicit ControlBuilder(StructuredGraphBuilder* builder)
24      : builder_(builder) {}
25  virtual ~ControlBuilder() {}
26
27  // Interface for break and continue.
28  virtual void Break() { UNREACHABLE(); }
29  virtual void Continue() { UNREACHABLE(); }
30
31 protected:
32  typedef StructuredGraphBuilder Builder;
33  typedef StructuredGraphBuilder::Environment Environment;
34
35  Zone* zone() const { return builder_->zone(); }
36  Environment* environment() { return builder_->environment(); }
37  void set_environment(Environment* env) { builder_->set_environment(env); }
38
39  Builder* builder_;
40};
41
42
43// Tracks control flow for a conditional statement.
44class IfBuilder : public ControlBuilder {
45 public:
46  explicit IfBuilder(StructuredGraphBuilder* builder)
47      : ControlBuilder(builder),
48        then_environment_(NULL),
49        else_environment_(NULL) {}
50
51  // Primitive control commands.
52  void If(Node* condition);
53  void Then();
54  void Else();
55  void End();
56
57 private:
58  Environment* then_environment_;  // Environment after the 'then' body.
59  Environment* else_environment_;  // Environment for the 'else' body.
60};
61
62
63// Tracks control flow for an iteration statement.
64class LoopBuilder : public ControlBuilder {
65 public:
66  explicit LoopBuilder(StructuredGraphBuilder* builder)
67      : ControlBuilder(builder),
68        loop_environment_(NULL),
69        continue_environment_(NULL),
70        break_environment_(NULL) {}
71
72  // Primitive control commands.
73  void BeginLoop();
74  void EndBody();
75  void EndLoop();
76
77  // Primitive support for break and continue.
78  virtual void Continue();
79  virtual void Break();
80
81  // Compound control command for conditional break.
82  void BreakUnless(Node* condition);
83
84 private:
85  Environment* loop_environment_;      // Environment of the loop header.
86  Environment* continue_environment_;  // Environment after the loop body.
87  Environment* break_environment_;     // Environment after the loop exits.
88};
89
90
91// Tracks control flow for a switch statement.
92class SwitchBuilder : public ControlBuilder {
93 public:
94  explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
95      : ControlBuilder(builder),
96        body_environment_(NULL),
97        label_environment_(NULL),
98        break_environment_(NULL),
99        body_environments_(case_count, zone()) {}
100
101  // Primitive control commands.
102  void BeginSwitch();
103  void BeginLabel(int index, Node* condition);
104  void EndLabel();
105  void DefaultAt(int index);
106  void BeginCase(int index);
107  void EndCase();
108  void EndSwitch();
109
110  // Primitive support for break.
111  virtual void Break();
112
113  // The number of cases within a switch is statically known.
114  int case_count() const { return body_environments_.capacity(); }
115
116 private:
117  Environment* body_environment_;   // Environment after last case body.
118  Environment* label_environment_;  // Environment for next label condition.
119  Environment* break_environment_;  // Environment after the switch exits.
120  ZoneList<Environment*> body_environments_;
121};
122
123
124// Tracks control flow for a block statement.
125class BlockBuilder : public ControlBuilder {
126 public:
127  explicit BlockBuilder(StructuredGraphBuilder* builder)
128      : ControlBuilder(builder), break_environment_(NULL) {}
129
130  // Primitive control commands.
131  void BeginBlock();
132  void EndBlock();
133
134  // Primitive support for break.
135  virtual void Break();
136
137 private:
138  Environment* break_environment_;  // Environment after the block exits.
139};
140}
141}
142}  // namespace v8::internal::compiler
143
144#endif  // V8_COMPILER_CONTROL_BUILDERS_H_
145