| Index: src/parsing/preparser.cc
|
| diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc
|
| index b5d5c287282a993c8c50ebb295dd22567abd2cd2..f1ef8ab60b384b9adac6b9e7e17aec20d8589d0d 100644
|
| --- a/src/parsing/preparser.cc
|
| +++ b/src/parsing/preparser.cc
|
| @@ -12,8 +12,8 @@
|
| #include "src/hashmap.h"
|
| #include "src/list.h"
|
| #include "src/parsing/parser-base.h"
|
| -#include "src/parsing/preparse-data.h"
|
| #include "src/parsing/preparse-data-format.h"
|
| +#include "src/parsing/preparse-data.h"
|
| #include "src/parsing/preparser.h"
|
| #include "src/unicode.h"
|
| #include "src/utils.h"
|
| @@ -681,11 +681,27 @@ PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
|
| // This is not handled during preparsing.
|
|
|
| Token::Value tok = peek();
|
| + int tail_call_position = -1;
|
| + if (FLAG_harmony_explicit_tailcalls && tok == Token::CONTINUE) {
|
| + Consume(Token::CONTINUE);
|
| + tail_call_position = position();
|
| + tok = peek();
|
| + }
|
| if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| tok != Token::SEMICOLON &&
|
| tok != Token::RBRACE &&
|
| tok != Token::EOS) {
|
| ParseExpression(true, CHECK_OK);
|
| + if (tail_call_position >= 0) {
|
| + if (!function_state_->collect_expressions_in_tail_position()) {
|
| + Scanner::Location loc(tail_call_position, tail_call_position + 1);
|
| + ReportMessageAt(loc, MessageTemplate::kTailCallInTryBlock);
|
| + *ok = false;
|
| + return Statement::Default();
|
| + }
|
| + function_state_->AddExpressionInTailPosition(
|
| + PreParserExpression::Default(), tail_call_position);
|
| + }
|
| }
|
| ExpectSemicolon(CHECK_OK);
|
| return Statement::Jump();
|
| @@ -936,7 +952,10 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
|
|
| Expect(Token::TRY, CHECK_OK);
|
|
|
| - ParseBlock(CHECK_OK);
|
| + {
|
| + DontCollectExpressionsInTailPositionScope no_tail_calls(function_state_);
|
| + ParseBlock(CHECK_OK);
|
| + }
|
|
|
| Token::Value tok = peek();
|
| if (tok != Token::CATCH && tok != Token::FINALLY) {
|
| @@ -944,6 +963,8 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
| *ok = false;
|
| return Statement::Default();
|
| }
|
| + List<TailCallExpression> expressions_in_tail_position_in_catch_block;
|
| + bool catch_block_exists = false;
|
| if (tok == Token::CATCH) {
|
| Consume(Token::CATCH);
|
| Expect(Token::LPAREN, CHECK_OK);
|
| @@ -953,6 +974,9 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
| ValidateBindingPattern(&pattern_classifier, CHECK_OK);
|
| Expect(Token::RPAREN, CHECK_OK);
|
| {
|
| + CollectExpressionsInTailPositionToListScope
|
| + collect_expressions_in_tail_position_scope(
|
| + function_state_, &expressions_in_tail_position_in_catch_block);
|
| BlockState block_state(&scope_, catch_scope);
|
| Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
|
| {
|
| @@ -960,11 +984,22 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
| ParseBlock(CHECK_OK);
|
| }
|
| }
|
| + catch_block_exists = true;
|
| tok = peek();
|
| }
|
| if (tok == Token::FINALLY) {
|
| Consume(Token::FINALLY);
|
| ParseBlock(CHECK_OK);
|
| + if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
|
| + expressions_in_tail_position_in_catch_block.length() > 0) {
|
| + // TODO(ishell): update chapter number.
|
| + // ES8 XX.YY.ZZ
|
| + int pos = expressions_in_tail_position_in_catch_block[0].pos;
|
| + ReportMessageAt(Scanner::Location(pos, pos + 1),
|
| + MessageTemplate::kTailCallInCatchBlock);
|
| + *ok = false;
|
| + return Statement::Default();
|
| + }
|
| }
|
| return Statement::Default();
|
| }
|
|
|