Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index d21541b281c6b5d9a6aa6a10e1d0c74abf06ad18..a2cf0dc93c8e771f200125ca69e1afc94c5b4687 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -1037,34 +1037,39 @@ void HGraphBuilder::IfBuilder::End() { |
} |
-HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
- HValue* context, |
- LoopBuilder::Direction direction) |
- : builder_(builder), |
- context_(context), |
- direction_(direction), |
- finished_(false) { |
- header_block_ = builder->CreateLoopHeaderBlock(); |
- body_block_ = NULL; |
- exit_block_ = NULL; |
- exit_trampoline_block_ = NULL; |
- increment_amount_ = builder_->graph()->GetConstant1(); |
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder) { |
+ Initialize(builder, NULL, kWhileTrue, NULL); |
} |
-HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
- HValue* context, |
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, |
+ LoopBuilder::Direction direction) { |
+ Initialize(builder, context, direction, builder->graph()->GetConstant1()); |
+} |
+ |
+ |
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, |
LoopBuilder::Direction direction, |
- HValue* increment_amount) |
- : builder_(builder), |
- context_(context), |
- direction_(direction), |
- finished_(false) { |
+ HValue* increment_amount) { |
+ Initialize(builder, context, direction, increment_amount); |
+ increment_amount_ = increment_amount; |
+} |
+ |
+ |
+void HGraphBuilder::LoopBuilder::Initialize(HGraphBuilder* builder, |
+ HValue* context, |
+ Direction direction, |
+ HValue* increment_amount) { |
+ builder_ = builder; |
+ context_ = context; |
+ direction_ = direction; |
+ increment_amount_ = increment_amount; |
+ |
+ finished_ = false; |
header_block_ = builder->CreateLoopHeaderBlock(); |
body_block_ = NULL; |
exit_block_ = NULL; |
exit_trampoline_block_ = NULL; |
- increment_amount_ = increment_amount; |
} |
@@ -1072,6 +1077,7 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( |
HValue* initial, |
HValue* terminating, |
Token::Value token) { |
+ ASSERT(direction_ != kWhileTrue); |
HEnvironment* env = builder_->environment(); |
phi_ = header_block_->AddNewPhi(env->values()->length()); |
phi_->AddInput(initial); |
@@ -1108,12 +1114,26 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( |
} |
+void HGraphBuilder::LoopBuilder::BeginBody(int drop_count) { |
+ ASSERT(direction_ == kWhileTrue); |
+ HEnvironment* env = builder_->environment(); |
+ builder_->GotoNoSimulate(header_block_); |
+ builder_->set_current_block(header_block_); |
+ env->Drop(drop_count); |
+} |
+ |
+ |
void HGraphBuilder::LoopBuilder::Break() { |
if (exit_trampoline_block_ == NULL) { |
// Its the first time we saw a break. |
- HEnvironment* env = exit_block_->last_environment()->Copy(); |
- exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
- builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); |
+ if (direction_ == kWhileTrue) { |
+ HEnvironment* env = builder_->environment()->Copy(); |
+ exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
+ } else { |
+ HEnvironment* env = exit_block_->last_environment()->Copy(); |
+ exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
+ builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); |
+ } |
} |
builder_->GotoNoSimulate(exit_trampoline_block_); |
@@ -1134,8 +1154,11 @@ void HGraphBuilder::LoopBuilder::EndBody() { |
builder_->AddInstruction(increment_); |
} |
- // Push the new increment value on the expression stack to merge into the phi. |
- builder_->environment()->Push(increment_); |
+ if (direction_ != kWhileTrue) { |
+ // Push the new increment value on the expression stack to merge into |
+ // the phi. |
+ builder_->environment()->Push(increment_); |
+ } |
HBasicBlock* last_block = builder_->current_block(); |
builder_->GotoNoSimulate(last_block, header_block_); |
header_block_->loop_information()->RegisterBackEdge(last_block); |