blob: 4b5fc3ab1d3fe83e4016ee3fe5315df44afad0e1 [file] [log] [blame]
// 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_->local_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, BranchHint hint = BranchHint::kNone);
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(BitVector* assigned);
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_