| Index: src/preparser.cc | 
| diff --git a/src/preparser.cc b/src/preparser.cc | 
| index c461d8a4bd2e3f5ed0084c6616a3e3d44601dada..9f68317b442ccdbb70b88a5c0528063f1f4f0423 100644 | 
| --- a/src/preparser.cc | 
| +++ b/src/preparser.cc | 
| @@ -53,12 +53,13 @@ int isfinite(double value); | 
| namespace preparser { | 
|  | 
| PreParser::PreParseResult PreParser::PreParseLazyFunction( | 
| -    i::LanguageMode mode, i::ParserRecorder* log) { | 
| +    i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { | 
| log_ = log; | 
| // Lazy functions always have trivial outer scopes (no with/catch scopes). | 
| Scope top_scope(&scope_, kTopLevelScope); | 
| set_language_mode(mode); | 
| Scope function_scope(&scope_, kFunctionScope); | 
| +  function_scope.set_is_generator(is_generator); | 
| ASSERT_EQ(i::Token::LBRACE, scanner_->current_token()); | 
| bool ok = true; | 
| int start_position = scanner_->peek_location().beg_pos; | 
| @@ -154,6 +155,7 @@ PreParser::Statement PreParser::ParseSourceElement(bool* ok) { | 
| // SourceElement: | 
| //    LetDeclaration | 
| //    ConstDeclaration | 
| +  //    GeneratorDeclaration | 
|  | 
| switch (peek()) { | 
| case i::Token::FUNCTION: | 
| @@ -296,10 +298,11 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 
| //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 
| Expect(i::Token::FUNCTION, CHECK_OK); | 
|  | 
| +  bool is_generator = Check(i::Token::MUL); | 
| Identifier identifier = ParseIdentifier(CHECK_OK); | 
| i::Scanner::Location location = scanner_->location(); | 
|  | 
| -  Expression function_value = ParseFunctionLiteral(CHECK_OK); | 
| +  Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); | 
|  | 
| if (function_value.IsStrictFunction() && | 
| !identifier.IsValidStrictVariable()) { | 
| @@ -810,8 +813,13 @@ PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, | 
| bool* ok) { | 
| // AssignmentExpression :: | 
| //   ConditionalExpression | 
| +  //   YieldExpression | 
| //   LeftHandSideExpression AssignmentOperator AssignmentExpression | 
|  | 
| +  if (scope_->is_generator() && peek() == i::Token::YIELD) { | 
| +    return ParseYieldExpression(ok); | 
| +  } | 
| + | 
| i::Scanner::Location before = scanner_->peek_location(); | 
| Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 
|  | 
| @@ -842,6 +850,19 @@ PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, | 
|  | 
|  | 
| // Precedence = 3 | 
| +PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { | 
| +  // YieldExpression :: | 
| +  //   'yield' '*'? AssignmentExpression | 
| +  Consume(i::Token::YIELD); | 
| +  Check(i::Token::MUL); | 
| + | 
| +  ParseAssignmentExpression(false, CHECK_OK); | 
| + | 
| +  return Expression::Default(); | 
| +} | 
| + | 
| + | 
| +// Precedence = 3 | 
| PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, | 
| bool* ok) { | 
| // ConditionalExpression :: | 
| @@ -1034,11 +1055,13 @@ PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( | 
| Expression result = Expression::Default(); | 
| if (peek() == i::Token::FUNCTION) { | 
| Consume(i::Token::FUNCTION); | 
| + | 
| +    bool is_generator = Check(i::Token::MUL); | 
| Identifier identifier = Identifier::Default(); | 
| if (peek_any_identifier()) { | 
| identifier = ParseIdentifier(CHECK_OK); | 
| } | 
| -    result = ParseFunctionLiteral(CHECK_OK); | 
| +    result = ParseFunctionLiteral(is_generator, CHECK_OK); | 
| if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { | 
| StrictModeIdentifierViolation(scanner_->location(), | 
| "strict_function_name", | 
| @@ -1112,6 +1135,7 @@ PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) { | 
|  | 
| case i::Token::FUTURE_RESERVED_WORD: | 
| case i::Token::FUTURE_STRICT_RESERVED_WORD: | 
| +    case i::Token::YIELD: | 
| case i::Token::IDENTIFIER: { | 
| Identifier id = ParseIdentifier(CHECK_OK); | 
| result = Expression::FromIdentifier(id); | 
| @@ -1257,7 +1281,7 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 
| } | 
| PropertyType type = is_getter ? kGetterProperty : kSetterProperty; | 
| CheckDuplicate(&duplicate_finder, name, type, CHECK_OK); | 
| -            ParseFunctionLiteral(CHECK_OK); | 
| +            ParseFunctionLiteral(false, CHECK_OK); | 
| if (peek() != i::Token::RBRACE) { | 
| Expect(i::Token::COMMA, CHECK_OK); | 
| } | 
| @@ -1344,7 +1368,8 @@ PreParser::Arguments PreParser::ParseArguments(bool* ok) { | 
| } | 
|  | 
|  | 
| -PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { | 
| +PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, | 
| +                                                      bool* ok) { | 
| // Function :: | 
| //   '(' FormalParameterList? ')' '{' FunctionBody '}' | 
|  | 
| @@ -1352,6 +1377,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { | 
| ScopeType outer_scope_type = scope_->type(); | 
| bool inside_with = scope_->IsInsideWith(); | 
| Scope function_scope(&scope_, kFunctionScope); | 
| +  function_scope.set_is_generator(is_generator); | 
| //  FormalParameterList :: | 
| //    '(' (Identifier)*[','] ')' | 
| Expect(i::Token::LPAREN, CHECK_OK); | 
| @@ -1497,6 +1523,8 @@ PreParser::Identifier PreParser::GetIdentifierSymbol() { | 
| } else if (scanner_->current_token() == | 
| i::Token::FUTURE_STRICT_RESERVED_WORD) { | 
| return Identifier::FutureStrictReserved(); | 
| +  } else if (scanner_->current_token() == i::Token::YIELD) { | 
| +    return Identifier::Yield(); | 
| } | 
| if (scanner_->is_literal_ascii()) { | 
| // Detect strict-mode poison words. | 
| @@ -1523,6 +1551,14 @@ PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 
| *ok = false; | 
| return GetIdentifierSymbol(); | 
| } | 
| +    case i::Token::YIELD: | 
| +      if (scope_->is_generator()) { | 
| +        // 'yield' in a generator is only valid as part of a YieldExpression. | 
| +        ReportMessageAt(scanner_->location(), "unexpected_token", "yield"); | 
| +        *ok = false; | 
| +        return Identifier::Yield(); | 
| +      } | 
| +      // FALLTHROUGH | 
| case i::Token::FUTURE_STRICT_RESERVED_WORD: | 
| if (!is_classic_mode()) { | 
| i::Scanner::Location location = scanner_->location(); | 
| @@ -1580,7 +1616,7 @@ void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, | 
| const char* type = eval_args_type; | 
| if (identifier.IsFutureReserved()) { | 
| type = "reserved_word"; | 
| -  } else if (identifier.IsFutureStrictReserved()) { | 
| +  } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 
| type = "strict_reserved_word"; | 
| } | 
| if (!is_classic_mode()) { | 
| @@ -1634,7 +1670,8 @@ bool PreParser::peek_any_identifier() { | 
| i::Token::Value next = peek(); | 
| return next == i::Token::IDENTIFIER || | 
| next == i::Token::FUTURE_RESERVED_WORD || | 
| -         next == i::Token::FUTURE_STRICT_RESERVED_WORD; | 
| +         next == i::Token::FUTURE_STRICT_RESERVED_WORD || | 
| +         next == i::Token::YIELD; | 
| } | 
|  | 
|  | 
|  |