// 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. #include "src/compiler/control-builders.h" namespace v8 { namespace internal { namespace compiler { void IfBuilder::If(Node* condition, BranchHint hint) { builder_->NewBranch(condition, hint); else_environment_ = environment()->CopyForConditional(); } void IfBuilder::Then() { builder_->NewIfTrue(); } void IfBuilder::Else() { builder_->NewMerge(); then_environment_ = environment(); set_environment(else_environment_); builder_->NewIfFalse(); } void IfBuilder::End() { then_environment_->Merge(environment()); set_environment(then_environment_); } void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) { loop_environment_ = environment()->CopyForLoop(assigned, is_osr); continue_environment_ = environment()->CopyAsUnreachable(); break_environment_ = environment()->CopyAsUnreachable(); assigned_ = assigned; } void LoopBuilder::Continue() { continue_environment_->Merge(environment()); environment()->MarkAsUnreachable(); } void LoopBuilder::Break() { break_environment_->Merge(environment()); environment()->MarkAsUnreachable(); } void LoopBuilder::EndBody() { continue_environment_->Merge(environment()); set_environment(continue_environment_); } void LoopBuilder::EndLoop() { loop_environment_->Merge(environment()); set_environment(break_environment_); ExitLoop(); } void LoopBuilder::BreakUnless(Node* condition) { IfBuilder control_if(builder_); control_if.If(condition); control_if.Then(); control_if.Else(); Break(); control_if.End(); } void LoopBuilder::BreakWhen(Node* condition) { IfBuilder control_if(builder_); control_if.If(condition); control_if.Then(); Break(); control_if.Else(); control_if.End(); } void LoopBuilder::ExitLoop(Node** extra_value_to_rename) { if (extra_value_to_rename) { environment()->Push(*extra_value_to_rename); } environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(), assigned_); if (extra_value_to_rename) { *extra_value_to_rename = environment()->Pop(); } } void SwitchBuilder::BeginSwitch() { body_environment_ = environment()->CopyAsUnreachable(); label_environment_ = environment()->CopyAsUnreachable(); break_environment_ = environment()->CopyAsUnreachable(); } void SwitchBuilder::BeginLabel(int index, Node* condition) { builder_->NewBranch(condition); label_environment_ = environment()->CopyForConditional(); builder_->NewIfTrue(); body_environments_[index] = environment(); } void SwitchBuilder::EndLabel() { set_environment(label_environment_); builder_->NewIfFalse(); } void SwitchBuilder::DefaultAt(int index) { label_environment_ = environment()->CopyAsUnreachable(); body_environments_[index] = environment(); } void SwitchBuilder::BeginCase(int index) { set_environment(body_environments_[index]); environment()->Merge(body_environment_); } void SwitchBuilder::Break() { break_environment_->Merge(environment()); environment()->MarkAsUnreachable(); } void SwitchBuilder::EndCase() { body_environment_ = environment(); } void SwitchBuilder::EndSwitch() { break_environment_->Merge(label_environment_); break_environment_->Merge(environment()); set_environment(break_environment_); } void BlockBuilder::BeginBlock() { break_environment_ = environment()->CopyAsUnreachable(); } void BlockBuilder::Break() { break_environment_->Merge(environment()); environment()->MarkAsUnreachable(); } void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) { IfBuilder control_if(builder_); control_if.If(condition, hint); control_if.Then(); Break(); control_if.Else(); control_if.End(); } void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) { IfBuilder control_if(builder_); control_if.If(condition, hint); control_if.Then(); control_if.Else(); Break(); control_if.End(); } void BlockBuilder::EndBlock() { break_environment_->Merge(environment()); set_environment(break_environment_); } void TryCatchBuilder::BeginTry() { exit_environment_ = environment()->CopyAsUnreachable(); catch_environment_ = environment()->CopyAsUnreachable(); catch_environment_->Push(the_hole()); } void TryCatchBuilder::Throw(Node* exception) { environment()->Push(exception); catch_environment_->Merge(environment()); environment()->Pop(); environment()->MarkAsUnreachable(); } void TryCatchBuilder::EndTry() { exit_environment_->Merge(environment()); exception_node_ = catch_environment_->Pop(); set_environment(catch_environment_); } void TryCatchBuilder::EndCatch() { exit_environment_->Merge(environment()); set_environment(exit_environment_); } void TryFinallyBuilder::BeginTry() { finally_environment_ = environment()->CopyAsUnreachable(); finally_environment_->Push(the_hole()); finally_environment_->Push(the_hole()); } void TryFinallyBuilder::LeaveTry(Node* token, Node* value) { environment()->Push(value); environment()->Push(token); finally_environment_->Merge(environment()); environment()->Drop(2); } void TryFinallyBuilder::EndTry(Node* fallthrough_token, Node* value) { environment()->Push(value); environment()->Push(fallthrough_token); finally_environment_->Merge(environment()); environment()->Drop(2); token_node_ = finally_environment_->Pop(); value_node_ = finally_environment_->Pop(); set_environment(finally_environment_); } void TryFinallyBuilder::EndFinally() { // Nothing to be done here. } } // namespace compiler } // namespace internal } // namespace v8