summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/control-builders.h
blob: 695282be8aab0901a3d252ba70aa95b4a634d3d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_CONTROL_BUILDERS_H_
#define V8_COMPILER_CONTROL_BUILDERS_H_

#include "src/v8.h"

#include "src/compiler/graph-builder.h"
#include "src/compiler/node.h"

namespace v8 {
namespace internal {
namespace compiler {


// Base class for all control builders. Also provides a common interface for
// control builders to handle 'break' and 'continue' statements when they are
// used to model breakable statements.
class ControlBuilder {
 public:
  explicit ControlBuilder(StructuredGraphBuilder* builder)
      : builder_(builder) {}
  virtual ~ControlBuilder() {}

  // Interface for break and continue.
  virtual void Break() { UNREACHABLE(); }
  virtual void Continue() { UNREACHABLE(); }

 protected:
  typedef StructuredGraphBuilder Builder;
  typedef StructuredGraphBuilder::Environment Environment;

  Zone* zone() const { return builder_->zone(); }
  Environment* environment() { return builder_->environment(); }
  void set_environment(Environment* env) { builder_->set_environment(env); }

  Builder* builder_;
};


// Tracks control flow for a conditional statement.
class IfBuilder : public ControlBuilder {
 public:
  explicit IfBuilder(StructuredGraphBuilder* builder)
      : ControlBuilder(builder),
        then_environment_(NULL),
        else_environment_(NULL) {}

  // Primitive control commands.
  void If(Node* condition);
  void Then();
  void Else();
  void End();

 private:
  Environment* then_environment_;  // Environment after the 'then' body.
  Environment* else_environment_;  // Environment for the 'else' body.
};


// Tracks control flow for an iteration statement.
class LoopBuilder : public ControlBuilder {
 public:
  explicit LoopBuilder(StructuredGraphBuilder* builder)
      : ControlBuilder(builder),
        loop_environment_(NULL),
        continue_environment_(NULL),
        break_environment_(NULL) {}

  // Primitive control commands.
  void BeginLoop();
  void EndBody();
  void EndLoop();

  // Primitive support for break and continue.
  virtual void Continue();
  virtual void Break();

  // Compound control command for conditional break.
  void BreakUnless(Node* condition);

 private:
  Environment* loop_environment_;      // Environment of the loop header.
  Environment* continue_environment_;  // Environment after the loop body.
  Environment* break_environment_;     // Environment after the loop exits.
};


// Tracks control flow for a switch statement.
class SwitchBuilder : public ControlBuilder {
 public:
  explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
      : ControlBuilder(builder),
        body_environment_(NULL),
        label_environment_(NULL),
        break_environment_(NULL),
        body_environments_(case_count, zone()) {}

  // Primitive control commands.
  void BeginSwitch();
  void BeginLabel(int index, Node* condition);
  void EndLabel();
  void DefaultAt(int index);
  void BeginCase(int index);
  void EndCase();
  void EndSwitch();

  // Primitive support for break.
  virtual void Break();

  // The number of cases within a switch is statically known.
  int case_count() const { return body_environments_.capacity(); }

 private:
  Environment* body_environment_;   // Environment after last case body.
  Environment* label_environment_;  // Environment for next label condition.
  Environment* break_environment_;  // Environment after the switch exits.
  ZoneList<Environment*> body_environments_;
};


// Tracks control flow for a block statement.
class BlockBuilder : public ControlBuilder {
 public:
  explicit BlockBuilder(StructuredGraphBuilder* builder)
      : ControlBuilder(builder), break_environment_(NULL) {}

  // Primitive control commands.
  void BeginBlock();
  void EndBlock();

  // Primitive support for break.
  virtual void Break();

 private:
  Environment* break_environment_;  // Environment after the block exits.
};
}
}
}  // namespace v8::internal::compiler

#endif  // V8_COMPILER_CONTROL_BUILDERS_H_