[parser] Inline ParseStatemantAsUnlabelled into its only useful caller

Tracking labels for most of these statements made no difference: only
try-statements require the special treatment of being wrapped in a
block. The previous code existed to support strong mode, which is
long gone.

This also results in a tiny regression of the error message for
a labelled `continue` statement targeting itself, but I'm not
convinced that anyone would ever intend to label a continue
statement (and Chakra and SpiderMonkey give similarly inaccurate
error messages for this case).

This is effectively a revert of d8bccfe974.

Bug: v8:6092
Change-Id: I25b62e10f6a20597e9686f08df76ba9724249618
Reviewed-on: https://chromium-review.googlesource.com/653380
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47904}
This commit is contained in:
Adam Klein 2017-09-06 16:40:38 -07:00 committed by Commit Bot
parent a6e84a38cc
commit 59798cc800
2 changed files with 18 additions and 41 deletions

View File

@ -1181,8 +1181,6 @@ class ParserBase {
StatementT ParseStatement(ZoneList<const AstRawString*>* labels,
AllowLabelledFunctionStatement allow_function,
bool* ok);
StatementT ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels,
bool* ok);
BlockT ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
// Parse a SubStatement in strict mode, or with an extra block scope in
@ -4867,23 +4865,25 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
}
return ParseForStatement(labels, ok);
case Token::CONTINUE:
return ParseContinueStatement(ok);
case Token::BREAK:
return ParseBreakStatement(labels, ok);
case Token::RETURN:
return ParseReturnStatement(ok);
case Token::THROW:
return ParseThrowStatement(ok);
case Token::TRY: {
// These statements must have their labels preserved in an enclosing
// block, as the corresponding AST nodes do not currently store their
// labels.
// TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
if (labels == nullptr) {
return ParseStatementAsUnlabelled(labels, ok);
} else {
BlockT result = factory()->NewBlock(1, false, labels);
typename Types::Target target(this, result);
StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
result->statements()->Add(statement, zone());
return result;
}
// It is somewhat complicated to have labels on try-statements.
// When breaking out of a try-finally statement, one must take
// great care not to treat it as a fall-through. It is much easier
// just to wrap the entire try-statement in a statement block and
// put the labels there.
if (labels == nullptr) return ParseTryStatement(ok);
BlockT result = factory()->NewBlock(1, false, labels);
typename Types::Target target(this, result);
StatementT statement = ParseTryStatement(CHECK_OK);
result->statements()->Add(statement, zone());
return result;
}
case Token::WITH:
return ParseWithStatement(labels, ok);
@ -4920,29 +4920,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
}
}
// This method parses a subset of statements (break, continue, return, throw,
// try) which are to be grouped because they all require their labeles to be
// preserved in an enclosing block.
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseStatementAsUnlabelled(
ZoneList<const AstRawString*>* labels, bool* ok) {
switch (peek()) {
case Token::CONTINUE:
return ParseContinueStatement(ok);
case Token::BREAK:
return ParseBreakStatement(labels, ok);
case Token::RETURN:
return ParseReturnStatement(ok);
case Token::THROW:
return ParseThrowStatement(ok);
case Token::TRY:
return ParseTryStatement(ok);
default:
UNREACHABLE();
}
}
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
ZoneList<const AstRawString*>* labels, bool* ok) {

View File

@ -42,17 +42,17 @@ PASS if (0) { L:A:{ continue; } } threw exception SyntaxError: Illegal continue
PASS if(0){ L:for(;;) continue L; } is undefined.
PASS if(0){ L:A:for(;;) continue L; } is undefined.
PASS if(0){ A:L:for(;;) continue L; } is undefined.
PASS if(0){ A:for(;;) L:continue L; } threw exception SyntaxError: Illegal continue statement: 'L' does not denote an iteration statement.
PASS if(0){ A:for(;;) L:continue L; } threw exception SyntaxError: Undefined label 'L'.
PASS if(0){ L:for(;;) A:continue L; } is undefined.
PASS if(0){ L:do continue L; while(0); } is undefined.
PASS if(0){ L:A:do continue L; while(0); } is undefined.
PASS if(0){ A:L:do continue L; while(0);} is undefined.
PASS if(0){ A:do L:continue L; while(0); } threw exception SyntaxError: Illegal continue statement: 'L' does not denote an iteration statement.
PASS if(0){ A:do L:continue L; while(0); } threw exception SyntaxError: Undefined label 'L'.
PASS if(0){ L:do A:continue L; while(0); } is undefined.
PASS if(0){ L:while(0) continue L; } is undefined.
PASS if(0){ L:A:while(0) continue L; } is undefined.
PASS if(0){ A:L:while(0) continue L; } is undefined.
PASS if(0){ A:while(0) L:continue L; } threw exception SyntaxError: Illegal continue statement: 'L' does not denote an iteration statement.
PASS if(0){ A:while(0) L:continue L; } threw exception SyntaxError: Undefined label 'L'.
PASS if(0){ L:while(0) A:continue L; } is undefined.
PASS successfullyParsed is true