| Index: src/parsing/parser-base.h
 | 
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
 | 
| index 075286e273bc8aba8e9bafe22f6cc7c4b4fd59c3..2f5427d5bd0f514d8f4ba52dcfab9c2ef81096f3 100644
 | 
| --- a/src/parsing/parser-base.h
 | 
| +++ b/src/parsing/parser-base.h
 | 
| @@ -1193,6 +1193,8 @@ class ParserBase {
 | 
|    // Magical syntax support.
 | 
|    ExpressionT ParseV8Intrinsic(bool* ok);
 | 
|  
 | 
| +  ExpressionT ParseDoExpression(bool* ok);
 | 
| +
 | 
|    StatementT ParseDebuggerStatement(bool* ok);
 | 
|  
 | 
|    StatementT ParseExpressionOrLabelledStatement(
 | 
| @@ -1205,6 +1207,11 @@ class ParserBase {
 | 
|    StatementT ParseReturnStatement(bool* ok);
 | 
|    StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
 | 
|                                  bool* ok);
 | 
| +  StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
 | 
| +                                   bool* ok);
 | 
| +  StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
 | 
| +                                 bool* ok);
 | 
| +  StatementT ParseThrowStatement(bool* ok);
 | 
|  
 | 
|    bool IsNextLetKeyword();
 | 
|    bool IsTrivialExpression();
 | 
| @@ -1754,7 +1761,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
 | 
|      case Token::DO:
 | 
|        if (allow_harmony_do_expressions()) {
 | 
|          BindingPatternUnexpectedToken();
 | 
| -        return impl()->ParseDoExpression(ok);
 | 
| +        return ParseDoExpression(ok);
 | 
|        }
 | 
|        break;
 | 
|  
 | 
| @@ -3986,6 +3993,18 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic(
 | 
|    return impl()->NewV8Intrinsic(name, args, pos, ok);
 | 
|  }
 | 
|  
 | 
| +template <typename Impl>
 | 
| +typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression(
 | 
| +    bool* ok) {
 | 
| +  // AssignmentExpression ::
 | 
| +  //     do '{' StatementList '}'
 | 
| +
 | 
| +  int pos = peek_position();
 | 
| +  Expect(Token::DO, CHECK_OK);
 | 
| +  BlockT block = ParseBlock(nullptr, CHECK_OK);
 | 
| +  return impl()->RewriteDoExpression(block, pos, ok);
 | 
| +}
 | 
| +
 | 
|  // Redefinition of CHECK_OK for parsing statements.
 | 
|  #undef CHECK_OK
 | 
|  #define CHECK_OK CHECK_OK_CUSTOM(NullStatement)
 | 
| @@ -4168,9 +4187,9 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
 | 
|      case Token::IF:
 | 
|        return ParseIfStatement(labels, ok);
 | 
|      case Token::DO:
 | 
| -      return impl()->ParseDoWhileStatement(labels, ok);
 | 
| +      return ParseDoWhileStatement(labels, ok);
 | 
|      case Token::WHILE:
 | 
| -      return impl()->ParseWhileStatement(labels, ok);
 | 
| +      return ParseWhileStatement(labels, ok);
 | 
|      case Token::FOR:
 | 
|        return impl()->ParseForStatement(labels, ok);
 | 
|      case Token::CONTINUE:
 | 
| @@ -4233,7 +4252,7 @@ ParserBase<Impl>::ParseStatementAsUnlabelled(
 | 
|      case Token::RETURN:
 | 
|        return ParseReturnStatement(ok);
 | 
|      case Token::THROW:
 | 
| -      return impl()->ParseThrowStatement(ok);
 | 
| +      return ParseThrowStatement(ok);
 | 
|      case Token::TRY:
 | 
|        return impl()->ParseTryStatement(ok);
 | 
|      default:
 | 
| @@ -4565,6 +4584,69 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
 | 
|    return factory()->NewWithStatement(with_scope, expr, body, pos);
 | 
|  }
 | 
|  
 | 
| +template <typename Impl>
 | 
| +typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
 | 
| +    ZoneList<const AstRawString*>* labels, bool* ok) {
 | 
| +  // DoStatement ::
 | 
| +  //   'do' Statement 'while' '(' Expression ')' ';'
 | 
| +
 | 
| +  auto loop = factory()->NewDoWhileStatement(labels, peek_position());
 | 
| +  typename Types::Target target(this, loop);
 | 
| +
 | 
| +  Expect(Token::DO, CHECK_OK);
 | 
| +  StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
 | 
| +  Expect(Token::WHILE, CHECK_OK);
 | 
| +  Expect(Token::LPAREN, CHECK_OK);
 | 
| +
 | 
| +  ExpressionT cond = ParseExpression(true, CHECK_OK);
 | 
| +  Expect(Token::RPAREN, CHECK_OK);
 | 
| +
 | 
| +  // Allow do-statements to be terminated with and without
 | 
| +  // semi-colons. This allows code such as 'do;while(0)return' to
 | 
| +  // parse, which would not be the case if we had used the
 | 
| +  // ExpectSemicolon() functionality here.
 | 
| +  Check(Token::SEMICOLON);
 | 
| +
 | 
| +  return impl()->InitializeLoop(loop, cond, body);
 | 
| +}
 | 
| +
 | 
| +template <typename Impl>
 | 
| +typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
 | 
| +    ZoneList<const AstRawString*>* labels, bool* ok) {
 | 
| +  // WhileStatement ::
 | 
| +  //   'while' '(' Expression ')' Statement
 | 
| +
 | 
| +  auto loop = factory()->NewWhileStatement(labels, peek_position());
 | 
| +  typename Types::Target target(this, loop);
 | 
| +
 | 
| +  Expect(Token::WHILE, CHECK_OK);
 | 
| +  Expect(Token::LPAREN, CHECK_OK);
 | 
| +  ExpressionT cond = ParseExpression(true, CHECK_OK);
 | 
| +  Expect(Token::RPAREN, CHECK_OK);
 | 
| +  StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
 | 
| +
 | 
| +  return impl()->InitializeLoop(loop, cond, body);
 | 
| +}
 | 
| +
 | 
| +template <typename Impl>
 | 
| +typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement(
 | 
| +    bool* ok) {
 | 
| +  // ThrowStatement ::
 | 
| +  //   'throw' Expression ';'
 | 
| +
 | 
| +  Expect(Token::THROW, CHECK_OK);
 | 
| +  int pos = position();
 | 
| +  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
 | 
| +    ReportMessage(MessageTemplate::kNewlineAfterThrow);
 | 
| +    *ok = false;
 | 
| +    return impl()->NullStatement();
 | 
| +  }
 | 
| +  ExpressionT exception = ParseExpression(true, CHECK_OK);
 | 
| +  ExpectSemicolon(CHECK_OK);
 | 
| +
 | 
| +  return impl()->NewThrowStatement(exception, pos);
 | 
| +}
 | 
| +
 | 
|  #undef CHECK_OK
 | 
|  #undef CHECK_OK_CUSTOM
 | 
|  
 | 
| 
 |