Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index dd8b402024834247cfcb252ab61acdc44667a5a8..9918e8518096044441006ae7a39ec0fe137b169d 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3058,15 +3058,24 @@ void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
set_current_block(osr_entry); |
int osr_entry_id = statement->OsrEntryId(); |
- // We want the correct environment at the OsrEntry instruction. Build |
- // it explicitly. The expression stack should be empty. |
- ASSERT(environment()->ExpressionStackIsEmpty()); |
- for (int i = 0; i < environment()->length(); ++i) { |
+ int first_expression_index = environment()->first_expression_index(); |
+ int length = environment()->length(); |
+ for (int i = 0; i < first_expression_index; ++i) { |
HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
AddInstruction(osr_value); |
environment()->Bind(i, osr_value); |
} |
+ if (first_expression_index != length) { |
+ environment()->Drop(length - first_expression_index); |
+ for (int i = first_expression_index; i < length; ++i) { |
+ HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
+ AddInstruction(osr_value); |
+ environment()->Push(osr_value); |
+ } |
+ } |
+ |
+ |
AddSimulate(osr_entry_id); |
AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
HContext* context = new(zone()) HContext; |
@@ -3274,15 +3283,17 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
HForInCacheArray::cast(array)->set_index_cache( |
HForInCacheArray::cast(index_cache)); |
+ PreProcessOsrEntry(stmt); |
HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
current_block()->Goto(loop_entry); |
set_current_block(loop_entry); |
- HValue* index = Top(); |
+ HValue* index = environment()->ExpressionStackAt(0); |
+ HValue* limit = environment()->ExpressionStackAt(1); |
// Check that we still have more keys. |
HCompareIDAndBranch* compare_index = |
- new(zone()) HCompareIDAndBranch(index, array_length, Token::LT); |
+ new(zone()) HCompareIDAndBranch(index, limit, Token::LT); |
compare_index->SetInputRepresentation(Representation::Integer32()); |
HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
@@ -3299,11 +3310,15 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
HValue* key = AddInstruction( |
new(zone()) HLoadKeyedFastElement( |
- array, index, HLoadKeyedFastElement::OMIT_HOLE_CHECK)); |
+ environment()->ExpressionStackAt(2), // Enum cache. |
+ environment()->ExpressionStackAt(0), // Iteration index. |
+ HLoadKeyedFastElement::OMIT_HOLE_CHECK)); |
// Check if the expected map still matches that of the enumerable. |
// If not just deoptimize. |
- AddInstruction(new(zone()) HCheckMapValue(enumerable, map)); |
+ AddInstruction(new(zone()) HCheckMapValue( |
+ environment()->ExpressionStackAt(4), |
+ environment()->ExpressionStackAt(3))); |
Bind(each_var, key); |
@@ -7440,9 +7455,8 @@ bool HEnvironment::HasExpressionAt(int index) const { |
bool HEnvironment::ExpressionStackIsEmpty() const { |
- int first_expression = parameter_count() + specials_count() + local_count(); |
- ASSERT(length() >= first_expression); |
- return length() == first_expression; |
+ ASSERT(length() >= first_expression_index()); |
+ return length() == first_expression_index(); |
} |