// 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 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_