diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 1f301938a005..ccc8572298d8 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -4577,6 +4577,32 @@ Parser::labeledStatement() return handler.newLabeledStatement(label, pn, begin); } +template +typename ParseHandler::Node +Parser::throwStatement() +{ + JS_ASSERT(tokenStream.isCurrentTokenType(TOK_THROW)); + uint32_t begin = pos().begin; + + /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */ + TokenKind tt = tokenStream.peekTokenSameLine(TSF_OPERAND); + if (tt == TOK_ERROR) + return null(); + if (tt == TOK_EOF || tt == TOK_EOL || tt == TOK_SEMI || tt == TOK_RC) { + report(ParseError, false, null(), JSMSG_SYNTAX_ERROR); + return null(); + } + + Node throwExpr = expr(); + if (!throwExpr) + return null(); + + if (!MatchOrInsertSemicolon(context, &tokenStream)) + return null(); + + return handler.newThrowStatement(throwExpr, TokenPos::make(begin, pos().end)); +} + template typename ParseHandler::Node Parser::tryStatement() @@ -4828,27 +4854,7 @@ Parser::statement(bool canHaveDirectives) return withStatement(); case TOK_THROW: - { - uint32_t begin = pos().begin; - - /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */ - TokenKind tt = tokenStream.peekTokenSameLine(TSF_OPERAND); - if (tt == TOK_ERROR) - return null(); - if (tt == TOK_EOF || tt == TOK_EOL || tt == TOK_SEMI || tt == TOK_RC) { - report(ParseError, false, null(), JSMSG_SYNTAX_ERROR); - return null(); - } - - Node pnexp = expr(); - if (!pnexp) - return null(); - - pn = handler.newThrowStatement(pnexp, TokenPos::make(begin, pos().end)); - if (!pn) - return null(); - break; - } + return throwStatement(); case TOK_TRY: return tryStatement(); diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index f14a10accd87..4bd2b9abe9fc 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -427,6 +427,7 @@ struct Parser : private AutoGCRooter, public StrictModeGetter Node returnStatementOrYieldExpression(); Node withStatement(); Node labeledStatement(); + Node throwStatement(); Node tryStatement(); #if JS_HAS_BLOCK_SCOPE Node letStatement();