| Index: src/parser.cc
 | 
| diff --git a/src/parser.cc b/src/parser.cc
 | 
| index b80e701577c6ee1e1272e1c4ba40c0986499bd4c..b4ab623829b9657382ab58bcbe347ce4b31d3dff 100644
 | 
| --- a/src/parser.cc
 | 
| +++ b/src/parser.cc
 | 
| @@ -486,14 +486,13 @@ class Parser::BlockState BASE_EMBEDDED {
 | 
|  
 | 
|  Parser::FunctionState::FunctionState(Parser* parser,
 | 
|                                       Scope* scope,
 | 
| -                                     bool is_generator,
 | 
|                                       Isolate* isolate)
 | 
|      : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
 | 
|        next_handler_index_(0),
 | 
|        expected_property_count_(0),
 | 
| -      is_generator_(is_generator),
 | 
|        only_simple_this_property_assignments_(false),
 | 
|        this_property_assignments_(isolate->factory()->empty_fixed_array()),
 | 
| +      generator_object_variable_(NULL),
 | 
|        parser_(parser),
 | 
|        outer_function_state_(parser->current_function_state_),
 | 
|        outer_scope_(parser->top_scope_),
 | 
| @@ -642,9 +641,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
 | 
|      }
 | 
|      ParsingModeScope parsing_mode(this, mode);
 | 
|  
 | 
| -    bool is_generator = false;
 | 
|      // Enters 'scope'.
 | 
| -    FunctionState function_state(this, scope, is_generator, isolate());
 | 
| +    FunctionState function_state(this, scope, isolate());
 | 
|  
 | 
|      top_scope_->SetLanguageMode(info->language_mode());
 | 
|      ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
 | 
| @@ -758,8 +756,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source,
 | 
|        scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
 | 
|                                             zone());
 | 
|      }
 | 
| -    bool is_generator = false;  // Top scope is not a generator.
 | 
| -    FunctionState function_state(this, scope, is_generator, isolate());
 | 
| +    FunctionState function_state(this, scope, isolate());
 | 
|      ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
 | 
|      ASSERT(scope->language_mode() != EXTENDED_MODE ||
 | 
|             info()->is_extended_mode());
 | 
| @@ -3103,8 +3100,11 @@ Expression* Parser::ParseYieldExpression(bool* ok) {
 | 
|    int position = scanner().peek_location().beg_pos;
 | 
|    Expect(Token::YIELD, CHECK_OK);
 | 
|    bool is_yield_star = Check(Token::MUL);
 | 
| +  Expression* generator_object = factory()->NewVariableProxy(
 | 
| +      current_function_state_->generator_object_variable());
 | 
|    Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
 | 
| -  return factory()->NewYield(expression, is_yield_star, position);
 | 
| +  return factory()->NewYield(generator_object, expression, is_yield_star,
 | 
| +                             position);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -4389,11 +4389,24 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
 | 
|        : FunctionLiteral::kNotGenerator;
 | 
|    AstProperties ast_properties;
 | 
|    // Parse function body.
 | 
| -  { FunctionState function_state(this, scope, is_generator, isolate());
 | 
| +  { FunctionState function_state(this, scope, isolate());
 | 
|      top_scope_->SetScopeName(function_name);
 | 
| -    // For generators, allocating variables in contexts is currently a win
 | 
| -    // because it minimizes the work needed to suspend and resume an activation.
 | 
| -    if (is_generator) top_scope_->ForceContextAllocation();
 | 
| +
 | 
| +    if (is_generator) {
 | 
| +      // For generators, allocating variables in contexts is currently a win
 | 
| +      // because it minimizes the work needed to suspend and resume an
 | 
| +      // activation.
 | 
| +      top_scope_->ForceContextAllocation();
 | 
| +
 | 
| +      // Calling a generator returns a generator object.  That object is stored
 | 
| +      // in a temporary variable, a definition that is used by "yield"
 | 
| +      // expressions.  Presence of a variable for the generator object in the
 | 
| +      // FunctionState indicates that this function is a generator.
 | 
| +      Handle<String> tempname = isolate()->factory()->InternalizeOneByteString(
 | 
| +          STATIC_ASCII_VECTOR(".generator_object"));
 | 
| +      Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
 | 
| +      function_state.set_generator_object_variable(temp);
 | 
| +    }
 | 
|  
 | 
|      //  FormalParameterList ::
 | 
|      //    '(' (Identifier)*[','] ')'
 | 
| @@ -4551,6 +4564,26 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
 | 
|                                       RelocInfo::kNoPosition)),
 | 
|                                       zone());
 | 
|        }
 | 
| +
 | 
| +      // For generators, allocate and yield an iterator on function entry.
 | 
| +      if (is_generator) {
 | 
| +        ZoneList<Expression*>* arguments =
 | 
| +            new(zone()) ZoneList<Expression*>(0, zone());
 | 
| +        CallRuntime* allocation = factory()->NewCallRuntime(
 | 
| +            isolate()->factory()->empty_string(),
 | 
| +            Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
 | 
| +            arguments);
 | 
| +        VariableProxy* init_proxy = factory()->NewVariableProxy(
 | 
| +            current_function_state_->generator_object_variable());
 | 
| +        Assignment* assignment = factory()->NewAssignment(
 | 
| +            Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
 | 
| +        VariableProxy* get_proxy = factory()->NewVariableProxy(
 | 
| +            current_function_state_->generator_object_variable());
 | 
| +        Yield* yield = factory()->NewYield(
 | 
| +            get_proxy, assignment, false, RelocInfo::kNoPosition);
 | 
| +        body->Add(factory()->NewExpressionStatement(yield), zone());
 | 
| +      }
 | 
| +
 | 
|        ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
 | 
|  
 | 
|        materialized_literal_count = function_state.materialized_literal_count();
 | 
| 
 |