Skip to content

Commit 9faaadb

Browse files
committed
[JSC] Generator declaration should not be allowed in single statement context
https://bugs.webkit.org/show_bug.cgi?id=216720 Reviewed by Ross Kirsling. JSTests: * stress/generator-syntax.js: (testSyntaxError.gen): * test262/expectations.yaml: Source/JavaScriptCore: Generator declaration in single statement context (like the following code) should be syntax error. We already made async function / async generator function syntax error. We should apply the same rule to generator declaration too. if (false) function * gen() { } * parser/Parser.cpp: (JSC::Parser<LexerType>::parseSingleFunction): (JSC::Parser<LexerType>::parseStatement): (JSC::Parser<LexerType>::parseFunctionDeclarationStatement): (JSC::Parser<LexerType>::parseFunctionDeclaration): (JSC::Parser<LexerType>::parseExportDeclaration): * parser/Parser.h: Canonical link: https://commits.webkit.org/229530@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267306 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent cadc612 commit 9faaadb

6 files changed

Lines changed: 52 additions & 28 deletions

File tree

JSTests/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2020-09-18 Yusuke Suzuki <ysuzuki@apple.com>
2+
3+
[JSC] Generator declaration should not be allowed in single statement context
4+
https://bugs.webkit.org/show_bug.cgi?id=216720
5+
6+
Reviewed by Ross Kirsling.
7+
8+
* stress/generator-syntax.js:
9+
(testSyntaxError.gen):
10+
* test262/expectations.yaml:
11+
112
2020-09-18 Caio Lima <ticaiolima@gmail.com>
213

314
[ARMv7][MIPS] Test gaderning September version

JSTests/stress/generator-syntax.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,7 @@ function* gen(b) {
166166
const b = 1;
167167
}
168168
`, `SyntaxError: Cannot declare a const variable twice: 'b'.`);
169+
170+
testSyntaxError(`
171+
if (false) function* gen() {}
172+
`, `SyntaxError: Unexpected token '*'. Cannot use generator function declaration in single-statement context.`);

JSTests/test262/expectations.yaml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3270,22 +3270,12 @@ test/language/statements/generators/scope-body-lex-distinct.js:
32703270
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
32713271
test/language/statements/generators/scope-param-rest-elem-var-open.js:
32723272
default: 'Test262Error: Expected SameValue(«outside», «inside») to be true'
3273-
test/language/statements/if/if-gen-else-gen.js:
3274-
default: 'Test262: This statement should not be evaluated.'
3275-
test/language/statements/if/if-gen-else-stmt.js:
3276-
default: 'Test262: This statement should not be evaluated.'
3277-
test/language/statements/if/if-gen-no-else.js:
3278-
default: 'Test262: This statement should not be evaluated.'
3279-
test/language/statements/if/if-stmt-else-gen.js:
3280-
default: 'Test262: This statement should not be evaluated.'
32813273
test/language/statements/labeled/decl-async-function.js:
32823274
default: 'Test262: This statement should not be evaluated.'
32833275
strict mode: 'Test262: This statement should not be evaluated.'
32843276
test/language/statements/labeled/decl-async-generator.js:
32853277
default: 'Test262: This statement should not be evaluated.'
32863278
strict mode: 'Test262: This statement should not be evaluated.'
3287-
test/language/statements/labeled/decl-gen.js:
3288-
default: 'Test262: This statement should not be evaluated.'
32893279
test/language/statements/labeled/let-array-with-newline.js:
32903280
default: 'Test262: This statement should not be evaluated.'
32913281
test/language/statements/labeled/value-await-non-module-escaped.js:

Source/JavaScriptCore/ChangeLog

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
2020-09-18 Yusuke Suzuki <ysuzuki@apple.com>
2+
3+
[JSC] Generator declaration should not be allowed in single statement context
4+
https://bugs.webkit.org/show_bug.cgi?id=216720
5+
6+
Reviewed by Ross Kirsling.
7+
8+
Generator declaration in single statement context (like the following code) should be syntax error.
9+
We already made async function / async generator function syntax error. We should apply the same rule
10+
to generator declaration too.
11+
12+
if (false)
13+
function * gen() { }
14+
15+
* parser/Parser.cpp:
16+
(JSC::Parser<LexerType>::parseSingleFunction):
17+
(JSC::Parser<LexerType>::parseStatement):
18+
(JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
19+
(JSC::Parser<LexerType>::parseFunctionDeclaration):
20+
(JSC::Parser<LexerType>::parseExportDeclaration):
21+
* parser/Parser.h:
22+
123
2020-09-18 Yusuke Suzuki <ysuzuki@apple.com>
224

325
[JSC] PreciseAllocation's isNewlyAllocated flag should be propagated from isMarked at GC begin phase to make isLive correct

Source/JavaScriptCore/parser/Parser.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSingleFu
624624
TreeStatement statement = 0;
625625
switch (m_token.m_type) {
626626
case FUNCTION:
627-
statement = parseFunctionDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::Standard, functionConstructorParametersEndPosition);
627+
statement = parseFunctionDeclaration(context, FunctionDeclarationType::Declaration, ExportType::NotExported, DeclarationDefaultContext::Standard, functionConstructorParametersEndPosition);
628628
break;
629629
case IDENT:
630630
if (*m_token.m_data.ident == m_vm.propertyNames->async && !m_token.m_data.escaped) {
@@ -1911,8 +1911,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
19111911
shouldSetPauseLocation = true;
19121912
break;
19131913
case FUNCTION: {
1914-
const bool isAsync = false;
1915-
result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
1914+
result = parseFunctionDeclarationStatement(context, parentAllowsFunctionDeclarationAsStatement);
19161915
break;
19171916
}
19181917
case SEMICOLON: {
@@ -2023,7 +2022,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
20232022
}
20242023

20252024
template <typename LexerType>
2026-
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement)
2025+
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool parentAllowsFunctionDeclarationAsStatement)
20272026
{
20282027
semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode");
20292028
failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
@@ -2033,9 +2032,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
20332032
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
20342033
DepthManager statementDepth(&m_statementDepth);
20352034
m_statementDepth = 1;
2036-
if (isAsync)
2037-
return parseAsyncFunctionDeclaration(context);
2038-
return parseFunctionDeclaration(context);
2035+
return parseFunctionDeclaration(context, FunctionDeclarationType::Statement);
20392036
}
20402037

20412038
// Any function declaration that isn't in a block is a syntax error unless it's
@@ -2055,11 +2052,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
20552052
JSTokenLocation location(tokenLocation());
20562053
int start = tokenLine();
20572054

2058-
TreeStatement function = 0;
2059-
if (!isAsync)
2060-
function = parseFunctionDeclaration(context);
2061-
else
2062-
function = parseAsyncFunctionDeclaration(context);
2055+
TreeStatement function = parseFunctionDeclaration(context, FunctionDeclarationType::Statement);
20632056
propagateError();
20642057
failIfFalse(function, "Expected valid function statement after 'function' keyword");
20652058
TreeSourceElements sourceElements = context.createSourceElements();
@@ -2679,15 +2672,18 @@ static NO_RETURN_DUE_TO_CRASH FunctionMetadataNode* getMetadata(ParserFunctionIn
26792672
static FunctionMetadataNode* getMetadata(ParserFunctionInfo<ASTBuilder>& info) { return info.body; }
26802673

26812674
template <typename LexerType>
2682-
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext, Optional<int> functionConstructorParametersEndPosition)
2675+
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, FunctionDeclarationType declarationType, ExportType exportType, DeclarationDefaultContext declarationDefaultContext, Optional<int> functionConstructorParametersEndPosition)
26832676
{
26842677
ASSERT(match(FUNCTION));
26852678
JSTokenLocation location(tokenLocation());
26862679
unsigned functionKeywordStart = tokenStart();
26872680
next();
26882681
SourceParseMode parseMode = SourceParseMode::NormalFunctionMode;
2689-
if (consume(TIMES))
2682+
if (match(TIMES)) {
2683+
failIfTrue(declarationType == FunctionDeclarationType::Statement, "Cannot use generator function declaration in single-statement context");
2684+
next();
26902685
parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
2686+
}
26912687

26922688
ParserFunctionInfo<TreeBuilder> functionInfo;
26932689
FunctionNameRequirements requirements = FunctionNameRequirements::Named;
@@ -3610,7 +3606,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
36103606
ASSERT(match(FUNCTION));
36113607
DepthManager statementDepth(&m_statementDepth);
36123608
m_statementDepth = 1;
3613-
result = parseFunctionDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
3609+
result = parseFunctionDeclaration(context, FunctionDeclarationType::Declaration, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
36143610
} else if (match(CLASSTOKEN)) {
36153611
result = parseClassDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
36163612
} else {
@@ -3727,7 +3723,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
37273723
case FUNCTION: {
37283724
DepthManager statementDepth(&m_statementDepth);
37293725
m_statementDepth = 1;
3730-
result = parseFunctionDeclaration(context, ExportType::Exported);
3726+
result = parseFunctionDeclaration(context, FunctionDeclarationType::Declaration, ExportType::Exported);
37313727
break;
37323728
}
37333729

Source/JavaScriptCore/parser/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,8 +1717,9 @@ class Parser {
17171717
template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = nullptr);
17181718
enum class ExportType { Exported, NotExported };
17191719
template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
1720-
template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1721-
template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement);
1720+
enum class FunctionDeclarationType { Declaration, Statement };
1721+
template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, FunctionDeclarationType = FunctionDeclarationType::Declaration, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1722+
template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool parentAllowsFunctionDeclarationAsStatement);
17221723
template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
17231724
template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
17241725
template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);

0 commit comments

Comments
 (0)