blob: 11adfdb0f4027637465d33db1326c2b1f965dc50 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017// Base class for all control builders. Also provides a common interface for
18// control builders to handle 'break' and 'continue' statements when they are
19// used to model breakable statements.
20class ControlBuilder {
21 public:
22 explicit ControlBuilder(StructuredGraphBuilder* builder)
23 : builder_(builder) {}
24 virtual ~ControlBuilder() {}
25
26 // Interface for break and continue.
27 virtual void Break() { UNREACHABLE(); }
28 virtual void Continue() { UNREACHABLE(); }
29
30 protected:
31 typedef StructuredGraphBuilder Builder;
32 typedef StructuredGraphBuilder::Environment Environment;
33
Emily Bernierd0a1eb72015-03-24 16:35:39 -040034 Zone* zone() const { return builder_->local_zone(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 Environment* environment() { return builder_->environment(); }
36 void set_environment(Environment* env) { builder_->set_environment(env); }
37
38 Builder* builder_;
39};
40
41
42// Tracks control flow for a conditional statement.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043class IfBuilder FINAL : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044 public:
45 explicit IfBuilder(StructuredGraphBuilder* builder)
46 : ControlBuilder(builder),
47 then_environment_(NULL),
48 else_environment_(NULL) {}
49
50 // Primitive control commands.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051 void If(Node* condition, BranchHint hint = BranchHint::kNone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052 void Then();
53 void Else();
54 void End();
55
56 private:
57 Environment* then_environment_; // Environment after the 'then' body.
58 Environment* else_environment_; // Environment for the 'else' body.
59};
60
61
62// Tracks control flow for an iteration statement.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040063class LoopBuilder FINAL : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064 public:
65 explicit LoopBuilder(StructuredGraphBuilder* builder)
66 : ControlBuilder(builder),
67 loop_environment_(NULL),
68 continue_environment_(NULL),
69 break_environment_(NULL) {}
70
71 // Primitive control commands.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040072 void BeginLoop(BitVector* assigned);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073 void EndBody();
74 void EndLoop();
75
76 // Primitive support for break and continue.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040077 void Continue() FINAL;
78 void Break() FINAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079
80 // Compound control command for conditional break.
81 void BreakUnless(Node* condition);
82
83 private:
84 Environment* loop_environment_; // Environment of the loop header.
85 Environment* continue_environment_; // Environment after the loop body.
86 Environment* break_environment_; // Environment after the loop exits.
87};
88
89
90// Tracks control flow for a switch statement.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091class SwitchBuilder FINAL : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092 public:
93 explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
94 : ControlBuilder(builder),
95 body_environment_(NULL),
96 label_environment_(NULL),
97 break_environment_(NULL),
98 body_environments_(case_count, zone()) {}
99
100 // Primitive control commands.
101 void BeginSwitch();
102 void BeginLabel(int index, Node* condition);
103 void EndLabel();
104 void DefaultAt(int index);
105 void BeginCase(int index);
106 void EndCase();
107 void EndSwitch();
108
109 // Primitive support for break.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 void Break() FINAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111
112 // The number of cases within a switch is statically known.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 size_t case_count() const { return body_environments_.size(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114
115 private:
116 Environment* body_environment_; // Environment after last case body.
117 Environment* label_environment_; // Environment for next label condition.
118 Environment* break_environment_; // Environment after the switch exits.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400119 ZoneVector<Environment*> body_environments_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120};
121
122
123// Tracks control flow for a block statement.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400124class BlockBuilder FINAL : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125 public:
126 explicit BlockBuilder(StructuredGraphBuilder* builder)
127 : ControlBuilder(builder), break_environment_(NULL) {}
128
129 // Primitive control commands.
130 void BeginBlock();
131 void EndBlock();
132
133 // Primitive support for break.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400134 void Break() FINAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135
136 private:
137 Environment* break_environment_; // Environment after the block exits.
138};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400139
140} // namespace compiler
141} // namespace internal
142} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143
144#endif // V8_COMPILER_CONTROL_BUILDERS_H_