Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 374b59c7a7e9b4e78707bd57d0ce94ad266e6bdf..9e1d8fdcf3069a4dfbe0645360973f3e34e1f63e 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -3060,6 +3060,48 @@ WhileStatement* Parser::ParseWhileStatement( |
} |
+// !%_IsSpecObject(result = iterator.next()) && |
+// %ThrowIteratorResultNotAnObject(result) |
+Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
+ Variable* result, int pos) { |
+ Expression* next_literal = factory()->NewStringLiteral( |
+ ast_value_factory()->next_string(), RelocInfo::kNoPosition); |
+ Expression* next_property = |
+ factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition); |
+ ZoneList<Expression*>* next_arguments = |
+ new (zone()) ZoneList<Expression*>(0, zone()); |
+ Expression* next_call = |
+ factory()->NewCall(next_property, next_arguments, pos); |
+ Expression* result_proxy = factory()->NewVariableProxy(result); |
+ Expression* left = |
+ factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
+ |
+ // %_IsSpecObject(...) |
+ ZoneList<Expression*>* is_spec_object_args = |
+ new (zone()) ZoneList<Expression*>(1, zone()); |
+ is_spec_object_args->Add(left, zone()); |
+ Expression* is_spec_object_call = factory()->NewCallRuntime( |
+ ast_value_factory()->is_spec_object_string(), |
+ Runtime::FunctionForId(Runtime::kInlineIsSpecObject), is_spec_object_args, |
+ pos); |
+ |
+ // %ThrowIteratorResultNotAnObject(result) |
+ Expression* result_proxy_again = factory()->NewVariableProxy(result); |
+ ZoneList<Expression*>* throw_arguments = |
+ new (zone()) ZoneList<Expression*>(1, zone()); |
+ throw_arguments->Add(result_proxy_again, zone()); |
+ Expression* throw_call = factory()->NewCallRuntime( |
+ ast_value_factory()->throw_iterator_result_not_an_object_string(), |
+ Runtime::FunctionForId(Runtime::kThrowIteratorResultNotAnObject), |
+ throw_arguments, pos); |
+ |
+ return factory()->NewBinaryOperation( |
+ Token::AND, |
+ factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), |
+ throw_call, pos); |
+} |
+ |
+ |
void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
Expression* each, |
Expression* subject, |
@@ -3087,41 +3129,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
{ |
// result = iterator.next() |
Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
- Expression* next_literal = factory()->NewStringLiteral( |
- ast_value_factory()->next_string(), RelocInfo::kNoPosition); |
- Expression* next_property = factory()->NewProperty( |
- iterator_proxy, next_literal, RelocInfo::kNoPosition); |
- ZoneList<Expression*>* next_arguments = |
- new (zone()) ZoneList<Expression*>(0, zone()); |
- Expression* next_call = factory()->NewCall(next_property, next_arguments, |
- subject->position()); |
- Expression* result_proxy = factory()->NewVariableProxy(result); |
- next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy, |
- next_call, subject->position()); |
- |
- // %_IsSpecObject(...) |
- ZoneList<Expression*>* is_spec_object_args = |
- new (zone()) ZoneList<Expression*>(1, zone()); |
- is_spec_object_args->Add(next_result, zone()); |
- Expression* is_spec_object_call = factory()->NewCallRuntime( |
- ast_value_factory()->is_spec_object_string(), |
- Runtime::FunctionForId(Runtime::kInlineIsSpecObject), |
- is_spec_object_args, subject->position()); |
- |
- // %ThrowIteratorResultNotAnObject(result) |
- Expression* result_proxy_again = factory()->NewVariableProxy(result); |
- ZoneList<Expression*>* throw_arguments = |
- new (zone()) ZoneList<Expression*>(1, zone()); |
- throw_arguments->Add(result_proxy_again, zone()); |
- Expression* throw_call = factory()->NewCallRuntime( |
- ast_value_factory()->throw_iterator_result_not_an_object_string(), |
- Runtime::FunctionForId(Runtime::kThrowIteratorResultNotAnObject), |
- throw_arguments, subject->position()); |
- |
- next_result = factory()->NewBinaryOperation( |
- Token::AND, factory()->NewUnaryOperation( |
- Token::NOT, is_spec_object_call, subject->position()), |
- throw_call, subject->position()); |
+ next_result = |
+ BuildIteratorNextResult(iterator_proxy, result, subject->position()); |
} |
// result.done |