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), 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break_environment_(nullptr), 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch assigned_(nullptr) {} 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BeginLoop(BitVector* assigned, bool is_osr = false); 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Continue(); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBody(); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndLoop(); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Primitive support for break. 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Loop exit support. Used to introduce explicit loop exit control 79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // node and variable markers. 80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ExitLoop(Node** extra_value_to_rename = nullptr); 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compound control commands for conditional break. 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BreakUnless(Node* condition); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakWhen(Node* condition); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* loop_environment_; // Environment of the loop header. 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* continue_environment_; // Environment after the loop body. 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the loop exits. 90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BitVector* assigned_; // Assigned values in the environment. 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for a switch statement. 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SwitchBuilder final : public ControlBuilder { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit SwitchBuilder(AstGraphBuilder* builder, int case_count) 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ControlBuilder(builder), 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch body_environment_(nullptr), 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch label_environment_(nullptr), 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break_environment_(nullptr), 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_environments_(case_count, zone()) {} 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginSwitch(); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginLabel(int index, Node* condition); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndLabel(); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DefaultAt(int index); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginCase(int index); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndCase(); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndSwitch(); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive support for break. 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The number of cases within a switch is statically known. 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t case_count() const { return body_environments_.size(); } 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* body_environment_; // Environment after last case body. 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* label_environment_; // Environment for next label condition. 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the switch exits. 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneVector<Environment*> body_environments_; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tracks control flow for a block statement. 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BlockBuilder final : public ControlBuilder { 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit BlockBuilder(AstGraphBuilder* builder) 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlBuilder(builder), break_environment_(nullptr) {} 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive control commands. 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BeginBlock(); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBlock(); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Primitive support for break. 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Break() final; 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compound control commands for conditional break. 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakWhen(Node* condition, BranchHint = BranchHint::kNone); 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment* break_environment_; // Environment after the block exits. 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_CONTROL_BUILDERS_H_ 153