1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_CONTROL_BUILDERS_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_CONTROL_BUILDERS_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/ast-graph-builder.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Base class for all control builders. Also provides a common interface for 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// control builders to handle 'break' statements when they are used to model 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// breakable statements. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ControlBuilder { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {} 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~ControlBuilder() {} 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Interface for break. 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void Break() { UNREACHABLE(); } 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typedef AstGraphBuilder Builder; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typedef AstGraphBuilder::Environment Environment; 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Zone* zone() const { return builder_->local_zone(); } 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* environment() { return builder_->environment(); } 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_environment(Environment* env) { builder_->set_environment(env); } 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); } 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Builder* builder_; 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for a conditional statement. 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IfBuilder final : public ControlBuilder { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit IfBuilder(AstGraphBuilder* builder) 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ControlBuilder(builder), 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch then_environment_(nullptr), 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch else_environment_(nullptr) {} 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void If(Node* condition, BranchHint hint = BranchHint::kNone); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Then(); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Else(); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void End(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* then_environment_; // Environment after the 'then' body. 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* else_environment_; // Environment for the 'else' body. 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for an iteration statement. 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LoopBuilder final : public ControlBuilder { 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit LoopBuilder(AstGraphBuilder* builder) 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ControlBuilder(builder), 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch loop_environment_(nullptr), 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch continue_environment_(nullptr), 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break_environment_(nullptr) {} 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BeginLoop(BitVector* assigned, bool is_osr = false); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Continue(); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBody(); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndLoop(); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Primitive support for break. 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compound control commands for conditional break. 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BreakUnless(Node* condition); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakWhen(Node* condition); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* loop_environment_; // Environment of the loop header. 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* continue_environment_; // Environment after the loop body. 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the loop exits. 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for a switch statement. 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SwitchBuilder final : public ControlBuilder { 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit SwitchBuilder(AstGraphBuilder* builder, int case_count) 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ControlBuilder(builder), 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch body_environment_(nullptr), 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch label_environment_(nullptr), 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break_environment_(nullptr), 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_environments_(case_count, zone()) {} 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginSwitch(); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginLabel(int index, Node* condition); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndLabel(); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DefaultAt(int index); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginCase(int index); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndCase(); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndSwitch(); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive support for break. 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The number of cases within a switch is statically known. 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t case_count() const { return body_environments_.size(); } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* body_environment_; // Environment after last case body. 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* label_environment_; // Environment for next label condition. 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the switch exits. 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneVector<Environment*> body_environments_; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for a block statement. 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BlockBuilder final : public ControlBuilder { 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit BlockBuilder(AstGraphBuilder* builder) 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlBuilder(builder), break_environment_(nullptr) {} 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginBlock(); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBlock(); 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive support for break. 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compound control commands for conditional break. 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakWhen(Node* condition, BranchHint = BranchHint::kNone); 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the block exits. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Tracks control flow for a try-catch statement. 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TryCatchBuilder final : public ControlBuilder { 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit TryCatchBuilder(AstGraphBuilder* builder) 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlBuilder(builder), 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch catch_environment_(nullptr), 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exit_environment_(nullptr), 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exception_node_(nullptr) {} 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Primitive control commands. 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BeginTry(); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Throw(Node* exception); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndTry(); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndCatch(); 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns the exception value inside the 'catch' body. 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetExceptionNode() const { return exception_node_; } 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* catch_environment_; // Environment for the 'catch' body. 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* exit_environment_; // Environment after the statement. 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_node_; // Node for exception in 'catch' body. 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Tracks control flow for a try-finally statement. 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TryFinallyBuilder final : public ControlBuilder { 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit TryFinallyBuilder(AstGraphBuilder* builder) 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlBuilder(builder), 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch finally_environment_(nullptr), 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch token_node_(nullptr), 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_node_(nullptr) {} 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Primitive control commands. 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BeginTry(); 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LeaveTry(Node* token, Node* value); 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndTry(Node* token, Node* value); 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndFinally(); 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns the dispatch token value inside the 'finally' body. 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetDispatchTokenNode() const { return token_node_; } 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Returns the saved result value inside the 'finally' body. 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetResultValueNode() const { return value_node_; } 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* finally_environment_; // Environment for the 'finally' body. 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* token_node_; // Node for token in 'finally' body. 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value_node_; // Node for value in 'finally' body. 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_CONTROL_BUILDERS_H_ 200