|
Lines 74-80
a/Source/JavaScriptCore/parser/Parser.cpp_sec1
|
| 74 |
semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__, " in strict mode"); \ |
74 |
semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__, " in strict mode"); \ |
| 75 |
if (m_token.m_type == RESERVED || m_token.m_type == RESERVED_IF_STRICT) \ |
75 |
if (m_token.m_type == RESERVED || m_token.m_type == RESERVED_IF_STRICT) \ |
| 76 |
semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \ |
76 |
semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \ |
| 77 |
if (m_token.m_type & KeywordTokenFlag) \ |
77 |
if (isDisallowedIdentifierAwait(m_token)) \ |
|
|
78 |
semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \ |
| 79 |
else if (m_token.m_type & KeywordTokenFlag) \ |
| 78 |
semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \ |
80 |
semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \ |
| 79 |
} while (0) |
81 |
} while (0) |
| 80 |
|
82 |
|
|
Lines 230-235
Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode
a/Source/JavaScriptCore/parser/Parser.cpp_sec2
|
| 230 |
if (strictMode == JSParserStrictMode::Strict) |
232 |
if (strictMode == JSParserStrictMode::Strict) |
| 231 |
scope->setStrictMode(); |
233 |
scope->setStrictMode(); |
| 232 |
|
234 |
|
|
|
235 |
m_allowsAwait = true; |
| 236 |
|
| 233 |
next(); |
237 |
next(); |
| 234 |
} |
238 |
} |
| 235 |
|
239 |
|
|
Lines 248-263
String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
a/Source/JavaScriptCore/parser/Parser.cpp_sec3
|
| 248 |
scope->setIsLexicalScope(); |
252 |
scope->setIsLexicalScope(); |
| 249 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); |
253 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); |
| 250 |
|
254 |
|
| 251 |
bool isArrowFunctionBodyExpression = false; |
255 |
bool isArrowFunctionBodyExpression = parseMode == SourceParseMode::AsyncArrowFunctionBodyMode && !match(OPENBRACE); |
| 252 |
if (m_lexer->isReparsingFunction()) { |
256 |
if (m_lexer->isReparsingFunction()) { |
| 253 |
ParserFunctionInfo<ASTBuilder> functionInfo; |
257 |
ParserFunctionInfo<ASTBuilder> functionInfo; |
| 254 |
if (parseMode == SourceParseMode::GeneratorBodyMode) |
258 |
if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode)) |
| 255 |
functionInfo.parameters = createGeneratorParameters(context); |
259 |
functionInfo.parameters = createGeneratorParameters(context); |
| 256 |
else |
260 |
else |
| 257 |
parseFunctionParameters(context, parseMode, functionInfo); |
261 |
parseFunctionParameters(context, parseMode, functionInfo); |
| 258 |
m_parameters = functionInfo.parameters; |
262 |
m_parameters = functionInfo.parameters; |
| 259 |
|
263 |
|
| 260 |
if (parseMode == SourceParseMode::ArrowFunctionMode && !hasError()) { |
264 |
if ((parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !hasError()) { |
| 261 |
// The only way we could have an error wile reparsing is if we run out of stack space. |
265 |
// The only way we could have an error wile reparsing is if we run out of stack space. |
| 262 |
RELEASE_ASSERT(match(ARROWFUNCTION)); |
266 |
RELEASE_ASSERT(match(ARROWFUNCTION)); |
| 263 |
next(); |
267 |
next(); |
|
Lines 274-289
String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
a/Source/JavaScriptCore/parser/Parser.cpp_sec4
|
| 274 |
SourceElements* sourceElements = nullptr; |
278 |
SourceElements* sourceElements = nullptr; |
| 275 |
// The only way we can error this early is if we reparse a function and we run out of stack space. |
279 |
// The only way we can error this early is if we reparse a function and we run out of stack space. |
| 276 |
if (!hasError()) { |
280 |
if (!hasError()) { |
| 277 |
if (isArrowFunctionBodyExpression) |
281 |
if (isAsyncFunctionWrapperParseMode(parseMode)) |
|
|
282 |
sourceElements = parseAsyncFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode); |
| 283 |
else if (isArrowFunctionBodyExpression) |
| 278 |
sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context); |
284 |
sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context); |
| 279 |
else if (isModuleParseMode(parseMode)) |
285 |
else if (isModuleParseMode(parseMode)) |
| 280 |
sourceElements = parseModuleSourceElements(context, parseMode); |
286 |
sourceElements = parseModuleSourceElements(context, parseMode); |
| 281 |
else { |
287 |
else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) |
| 282 |
if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) |
288 |
sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode); |
| 283 |
sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode); |
289 |
else |
| 284 |
else |
290 |
sourceElements = parseSourceElements(context, CheckForStrictMode); |
| 285 |
sourceElements = parseSourceElements(context, CheckForStrictMode); |
|
|
| 286 |
} |
| 287 |
} |
291 |
} |
| 288 |
|
292 |
|
| 289 |
bool validEnding; |
293 |
bool validEnding; |
|
Lines 312-318
String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
a/Source/JavaScriptCore/parser/Parser.cpp_sec5
|
| 312 |
for (auto& entry : capturedVariables) |
316 |
for (auto& entry : capturedVariables) |
| 313 |
varDeclarations.markVariableAsCaptured(entry); |
317 |
varDeclarations.markVariableAsCaptured(entry); |
| 314 |
|
318 |
|
| 315 |
if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) { |
319 |
if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) { |
| 316 |
if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl())) |
320 |
if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl())) |
| 317 |
context.propagateArgumentsUse(); |
321 |
context.propagateArgumentsUse(); |
| 318 |
} |
322 |
} |
|
Lines 361-367
template <typename LexerType>
a/Source/JavaScriptCore/parser/Parser.cpp_sec6
|
| 361 |
bool Parser<LexerType>::isArrowFunctionParameters() |
365 |
bool Parser<LexerType>::isArrowFunctionParameters() |
| 362 |
{ |
366 |
{ |
| 363 |
bool isOpenParen = match(OPENPAREN); |
367 |
bool isOpenParen = match(OPENPAREN); |
| 364 |
bool isIdent = match(IDENT); |
368 |
bool isIdent = matchSpecIdentifier(); |
| 365 |
|
369 |
|
| 366 |
if (!isOpenParen && !isIdent) |
370 |
if (!isOpenParen && !isIdent) |
| 367 |
return false; |
371 |
return false; |
|
Lines 534-539
template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseGenerato
a/Source/JavaScriptCore/parser/Parser.cpp_sec7
|
| 534 |
} |
538 |
} |
| 535 |
|
539 |
|
| 536 |
template <typename LexerType> |
540 |
template <typename LexerType> |
|
|
541 |
template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode) |
| 542 |
{ |
| 543 |
ASSERT(isAsyncFunctionWrapperParseMode(parseMode)); |
| 544 |
auto sourceElements = context.createSourceElements(); |
| 545 |
|
| 546 |
unsigned functionKeywordStart = tokenStart(); |
| 547 |
JSTokenLocation startLocation(tokenLocation()); |
| 548 |
JSTextPosition start = tokenStartPosition(); |
| 549 |
unsigned startColumn = tokenColumn(); |
| 550 |
int functionNameStart = m_token.m_location.startOffset; |
| 551 |
int parametersStart = m_token.m_location.startOffset; |
| 552 |
|
| 553 |
ParserFunctionInfo<TreeBuilder> info; |
| 554 |
info.name = &m_vm->propertyNames->nullIdentifier; |
| 555 |
info.parameters = createGeneratorParameters(context); |
| 556 |
info.startOffset = parametersStart; |
| 557 |
info.startLine = tokenLine(); |
| 558 |
info.parameterCount = 4; // generator, state, value, resume mode |
| 559 |
SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode ? SourceParseMode::AsyncArrowFunctionBodyMode : SourceParseMode::AsyncFunctionBodyMode; |
| 560 |
{ |
| 561 |
AutoPopScopeRef asyncFunctionBodyScope(this, pushScope()); |
| 562 |
asyncFunctionBodyScope->setSourceParseMode(innerParseMode); |
| 563 |
SyntaxChecker asyncFunctionContext(const_cast<VM*>(m_vm), m_lexer.get()); |
| 564 |
if (isArrowFunctionBodyExpression) |
| 565 |
failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(asyncFunctionContext), "Cannot parse the body of async arrow function"); |
| 566 |
else |
| 567 |
failIfFalse(parseSourceElements(asyncFunctionContext, mode), "Cannot parse the body of async function"); |
| 568 |
popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo); |
| 569 |
} |
| 570 |
|
| 571 |
info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression); |
| 572 |
|
| 573 |
info.endLine = tokenLine(); |
| 574 |
info.endOffset = m_token.m_data.offset; |
| 575 |
info.bodyStartColumn = startColumn; |
| 576 |
|
| 577 |
auto functionExpr = context.createFunctionExpr(startLocation, info); |
| 578 |
auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line); |
| 579 |
context.appendStatement(sourceElements, statement); |
| 580 |
|
| 581 |
return sourceElements; |
| 582 |
} |
| 583 |
|
| 584 |
template <typename LexerType> |
| 537 |
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength) |
585 |
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength) |
| 538 |
{ |
586 |
{ |
| 539 |
// The grammar is documented here: |
587 |
// The grammar is documented here: |
|
Lines 542-547
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
a/Source/JavaScriptCore/parser/Parser.cpp_sec8
|
| 542 |
m_statementDepth++; |
590 |
m_statementDepth++; |
| 543 |
TreeStatement result = 0; |
591 |
TreeStatement result = 0; |
| 544 |
bool shouldSetEndOffset = true; |
592 |
bool shouldSetEndOffset = true; |
|
|
593 |
|
| 594 |
if (UNLIKELY(match(ASYNC))) { |
| 595 |
SavePoint beforeAsync = createSavePoint(); |
| 596 |
next(); |
| 597 |
if (match(FUNCTION) && !m_lexer->prevTerminator()) { |
| 598 |
result = parseAsyncFunctionDeclaration(context); |
| 599 |
failIfFalse(result, "Failed to parse async function declaration"); |
| 600 |
context.setEndOffset(result, m_lastTokenEndPosition.offset); |
| 601 |
return result; |
| 602 |
} |
| 603 |
restoreSavePoint(beforeAsync); |
| 604 |
} |
| 605 |
|
| 545 |
switch (m_token.m_type) { |
606 |
switch (m_token.m_type) { |
| 546 |
case CONSTTOKEN: |
607 |
case CONSTTOKEN: |
| 547 |
result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration); |
608 |
result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration); |
|
Lines 556-562
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
a/Source/JavaScriptCore/parser/Parser.cpp_sec9
|
| 556 |
// For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`. |
617 |
// For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`. |
| 557 |
// But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration |
618 |
// But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration |
| 558 |
// to raise consistent errors between "var", "const" and "let". |
619 |
// to raise consistent errors between "var", "const" and "let". |
| 559 |
if (!(match(IDENT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET)) |
620 |
if (!(match(IDENT) || match(ASYNC) || match(AWAIT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET)) |
| 560 |
shouldParseVariableDeclaration = false; |
621 |
shouldParseVariableDeclaration = false; |
| 561 |
restoreSavePoint(savePoint); |
622 |
restoreSavePoint(savePoint); |
| 562 |
} |
623 |
} |
|
Lines 575-580
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
a/Source/JavaScriptCore/parser/Parser.cpp_sec10
|
| 575 |
case FUNCTION: |
636 |
case FUNCTION: |
| 576 |
result = parseFunctionDeclaration(context); |
637 |
result = parseFunctionDeclaration(context); |
| 577 |
break; |
638 |
break; |
|
|
639 |
|
| 578 |
default: |
640 |
default: |
| 579 |
m_statementDepth--; // parseStatement() increments the depth. |
641 |
m_statementDepth--; // parseStatement() increments the depth. |
| 580 |
result = parseStatement(context, directive, directiveLiteralLength); |
642 |
result = parseStatement(context, directive, directiveLiteralLength); |
|
Lines 674-679
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
a/Source/JavaScriptCore/parser/Parser.cpp_sec11
|
| 674 |
if (matchSpecIdentifier()) { |
736 |
if (matchSpecIdentifier()) { |
| 675 |
failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), |
737 |
failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), |
| 676 |
"Can't use 'let' as an identifier name for a LexicalDeclaration"); |
738 |
"Can't use 'let' as an identifier name for a LexicalDeclaration"); |
|
|
739 |
semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason()); |
| 677 |
JSTextPosition varStart = tokenStartPosition(); |
740 |
JSTextPosition varStart = tokenStartPosition(); |
| 678 |
JSTokenLocation varStartLocation(tokenLocation()); |
741 |
JSTokenLocation varStartLocation(tokenLocation()); |
| 679 |
identStart = varStart; |
742 |
identStart = varStart; |
|
Lines 1000-1005
template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
a/Source/JavaScriptCore/parser/Parser.cpp_sec12
|
| 1000 |
reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing); |
1063 |
reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing); |
| 1001 |
failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode"); |
1064 |
failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode"); |
| 1002 |
} |
1065 |
} |
|
|
1066 |
semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason()); |
| 1003 |
innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier); |
1067 |
innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier); |
| 1004 |
} |
1068 |
} |
| 1005 |
} else { |
1069 |
} else { |
|
Lines 1067-1072
template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
a/Source/JavaScriptCore/parser/Parser.cpp_sec13
|
| 1067 |
failWithMessage("Expected a parameter pattern or a ')' in parameter list"); |
1131 |
failWithMessage("Expected a parameter pattern or a ')' in parameter list"); |
| 1068 |
} |
1132 |
} |
| 1069 |
failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); |
1133 |
failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); |
|
|
1134 |
semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason()); |
| 1070 |
pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier); |
1135 |
pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier); |
| 1071 |
next(); |
1136 |
next(); |
| 1072 |
break; |
1137 |
break; |
|
Lines 1667-1672
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
a/Source/JavaScriptCore/parser/Parser.cpp_sec14
|
| 1667 |
// These tokens imply the end of a set of source elements |
1732 |
// These tokens imply the end of a set of source elements |
| 1668 |
return 0; |
1733 |
return 0; |
| 1669 |
case IDENT: |
1734 |
case IDENT: |
|
|
1735 |
case ASYNC: |
| 1736 |
case AWAIT: |
| 1670 |
case YIELD: |
1737 |
case YIELD: |
| 1671 |
result = parseExpressionOrLabelStatement(context); |
1738 |
result = parseExpressionOrLabelStatement(context); |
| 1672 |
break; |
1739 |
break; |
|
Lines 1709-1714
template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeB
a/Source/JavaScriptCore/parser/Parser.cpp_sec15
|
| 1709 |
if (match(DOTDOTDOT)) { |
1776 |
if (match(DOTDOTDOT)) { |
| 1710 |
next(); |
1777 |
next(); |
| 1711 |
failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier"); |
1778 |
failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier"); |
|
|
1779 |
semanticFailIfTrue(!m_allowsAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function"); |
| 1712 |
declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter); |
1780 |
declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter); |
| 1713 |
propagateError(); |
1781 |
propagateError(); |
| 1714 |
JSTextPosition identifierStart = tokenStartPosition(); |
1782 |
JSTextPosition identifierStart = tokenStartPosition(); |
|
Lines 1775-1780
static const char* stringForFunctionMode(SourceParseMode mode)
a/Source/JavaScriptCore/parser/Parser.cpp_sec16
|
| 1775 |
return "generator function"; |
1843 |
return "generator function"; |
| 1776 |
case SourceParseMode::ArrowFunctionMode: |
1844 |
case SourceParseMode::ArrowFunctionMode: |
| 1777 |
return "arrow function"; |
1845 |
return "arrow function"; |
|
|
1846 |
case SourceParseMode::AsyncFunctionMode: |
| 1847 |
case SourceParseMode::AsyncFunctionBodyMode: |
| 1848 |
return "async function"; |
| 1849 |
case SourceParseMode::AsyncMethodMode: |
| 1850 |
return "async method"; |
| 1851 |
case SourceParseMode::AsyncArrowFunctionBodyMode: |
| 1852 |
case SourceParseMode::AsyncArrowFunctionMode: |
| 1853 |
return "async arrow function"; |
| 1778 |
case SourceParseMode::ProgramMode: |
1854 |
case SourceParseMode::ProgramMode: |
| 1779 |
case SourceParseMode::ModuleAnalyzeMode: |
1855 |
case SourceParseMode::ModuleAnalyzeMode: |
| 1780 |
case SourceParseMode::ModuleEvaluateMode: |
1856 |
case SourceParseMode::ModuleEvaluateMode: |
|
Lines 1794-1801
template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>
a/Source/JavaScriptCore/parser/Parser.cpp_sec17
|
| 1794 |
functionInfo.startOffset = parametersStart; |
1870 |
functionInfo.startOffset = parametersStart; |
| 1795 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters); |
1871 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters); |
| 1796 |
|
1872 |
|
| 1797 |
if (mode == SourceParseMode::ArrowFunctionMode) { |
1873 |
if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) { |
| 1798 |
if (!match(IDENT) && !match(OPENPAREN)) { |
1874 |
if (!matchSpecIdentifier() && !match(OPENPAREN)) { |
| 1799 |
semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); |
1875 |
semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); |
| 1800 |
failWithMessage("Expected an arrow function input parameter"); |
1876 |
failWithMessage("Expected an arrow function input parameter"); |
| 1801 |
} else { |
1877 |
} else { |
|
Lines 1887-1892
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec18
|
| 1887 |
RELEASE_ASSERT(isFunctionParseMode(mode)); |
1963 |
RELEASE_ASSERT(isFunctionParseMode(mode)); |
| 1888 |
|
1964 |
|
| 1889 |
bool upperScopeIsGenerator = currentScope()->isGenerator(); |
1965 |
bool upperScopeIsGenerator = currentScope()->isGenerator(); |
|
|
1966 |
bool upperScopeIsAsync = currentScope()->isAsyncFunctionBoundary(); |
| 1967 |
bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token); |
| 1968 |
const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr; |
| 1890 |
AutoPopScopeRef functionScope(this, pushScope()); |
1969 |
AutoPopScopeRef functionScope(this, pushScope()); |
| 1891 |
functionScope->setSourceParseMode(mode); |
1970 |
functionScope->setSourceParseMode(mode); |
| 1892 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); |
1971 |
SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); |
|
Lines 1898-1909
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec19
|
| 1898 |
int startColumn; |
1977 |
int startColumn; |
| 1899 |
FunctionBodyType functionBodyType; |
1978 |
FunctionBodyType functionBodyType; |
| 1900 |
|
1979 |
|
| 1901 |
if (mode == SourceParseMode::ArrowFunctionMode) { |
1980 |
if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) { |
| 1902 |
startLocation = tokenLocation(); |
1981 |
startLocation = tokenLocation(); |
| 1903 |
functionInfo.startLine = tokenLine(); |
1982 |
functionInfo.startLine = tokenLine(); |
| 1904 |
startColumn = tokenColumn(); |
1983 |
startColumn = tokenColumn(); |
| 1905 |
|
1984 |
|
| 1906 |
parametersStart = parseFunctionParameters(context, mode, functionInfo); |
1985 |
{ |
|
|
1986 |
AllowAwaitOverride allowAwait(this, !isAsyncFunctionParseMode(mode)); |
| 1987 |
parametersStart = parseFunctionParameters(context, mode, functionInfo); |
| 1988 |
} |
| 1907 |
propagateError(); |
1989 |
propagateError(); |
| 1908 |
|
1990 |
|
| 1909 |
matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration"); |
1991 |
matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration"); |
|
Lines 1933-1951
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec20
|
| 1933 |
// GeneratorExpression : |
2015 |
// GeneratorExpression : |
| 1934 |
// function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody } |
2016 |
// function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody } |
| 1935 |
// |
2017 |
// |
| 1936 |
// The name of FunctionExpression can accept "yield" even in the context of generator. |
2018 |
// The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator. |
| 1937 |
if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode) |
2019 |
if (functionDefinitionType == FunctionDefinitionType::Expression && (mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::AsyncFunctionMode)) |
| 1938 |
upperScopeIsGenerator = false; |
2020 |
upperScopeIsGenerator = false; |
| 1939 |
|
2021 |
|
| 1940 |
if (matchSpecIdentifier(upperScopeIsGenerator)) { |
2022 |
if (matchSpecIdentifier(upperScopeIsGenerator)) { |
|
|
2023 |
bool allowsAwait = mode != SourceParseMode::AsyncFunctionMode; |
| 2024 |
if (functionDefinitionType == FunctionDefinitionType::Declaration) |
| 2025 |
allowsAwait = upperScopeIsAsync; |
| 1941 |
functionInfo.name = m_token.m_data.ident; |
2026 |
functionInfo.name = m_token.m_data.ident; |
| 1942 |
m_parserState.lastFunctionName = functionInfo.name; |
2027 |
m_parserState.lastFunctionName = functionInfo.name; |
|
|
2028 |
if (allowsAwait) |
| 2029 |
semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason); |
| 2030 |
else |
| 2031 |
semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare async function named 'await'"); |
| 2032 |
|
| 1943 |
next(); |
2033 |
next(); |
| 1944 |
if (!nameIsInContainingScope) |
2034 |
if (!nameIsInContainingScope) |
| 1945 |
failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); |
2035 |
failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); |
| 1946 |
} else if (requirements == FunctionNeedsName) { |
2036 |
} else if (requirements == FunctionNeedsName) { |
| 1947 |
if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode) |
2037 |
semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name"); |
| 1948 |
semanticFail("Function statements must have a name"); |
2038 |
semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name"); |
| 1949 |
semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); |
2039 |
semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); |
| 1950 |
failDueToUnexpectedToken(); |
2040 |
failDueToUnexpectedToken(); |
| 1951 |
return false; |
2041 |
return false; |
|
Lines 1955-1961
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec21
|
| 1955 |
functionInfo.startLine = tokenLine(); |
2045 |
functionInfo.startLine = tokenLine(); |
| 1956 |
startColumn = tokenColumn(); |
2046 |
startColumn = tokenColumn(); |
| 1957 |
|
2047 |
|
| 1958 |
parametersStart = parseFunctionParameters(context, mode, functionInfo); |
2048 |
{ |
|
|
2049 |
AllowAwaitOverride allowAwait(this, !isAsyncFunctionParseMode(mode)); |
| 2050 |
parametersStart = parseFunctionParameters(context, mode, functionInfo); |
| 2051 |
} |
| 1959 |
propagateError(); |
2052 |
propagateError(); |
| 1960 |
|
2053 |
|
| 1961 |
matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); |
2054 |
matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); |
|
Lines 2010-2016
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec22
|
| 2010 |
m_lexer->setLineNumber(m_token.m_location.line); |
2103 |
m_lexer->setLineNumber(m_token.m_location.line); |
| 2011 |
functionInfo.endOffset = cachedInfo->endFunctionOffset; |
2104 |
functionInfo.endOffset = cachedInfo->endFunctionOffset; |
| 2012 |
|
2105 |
|
| 2013 |
if (mode == SourceParseMode::ArrowFunctionMode) |
2106 |
if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) |
| 2014 |
functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock; |
2107 |
functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock; |
| 2015 |
else |
2108 |
else |
| 2016 |
functionBodyType = StandardFunctionBodyBlock; |
2109 |
functionBodyType = StandardFunctionBodyBlock; |
|
Lines 2037-2054
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec23
|
| 2037 |
return parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode); |
2130 |
return parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode); |
| 2038 |
}; |
2131 |
}; |
| 2039 |
|
2132 |
|
| 2040 |
if (mode == SourceParseMode::GeneratorWrapperFunctionMode) { |
2133 |
if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) { |
| 2041 |
AutoPopScopeRef generatorBodyScope(this, pushScope()); |
2134 |
AutoPopScopeRef generatorBodyScope(this, pushScope()); |
| 2042 |
generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode); |
2135 |
SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode; |
|
|
2136 |
if (isAsyncFunctionWrapperParseMode(mode)) { |
| 2137 |
innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode |
| 2138 |
? SourceParseMode::AsyncArrowFunctionBodyMode |
| 2139 |
: SourceParseMode::AsyncFunctionBodyMode; |
| 2140 |
} |
| 2141 |
generatorBodyScope->setSourceParseMode(innerParseMode); |
| 2043 |
functionInfo.body = performParsingFunctionBody(); |
2142 |
functionInfo.body = performParsingFunctionBody(); |
| 2044 |
|
2143 |
|
| 2045 |
// When a generator has a "use strict" directive, a generator function wrapping it should be strict mode. |
2144 |
// When a generator has a "use strict" directive, a generator function wrapping it should be strict mode. |
| 2046 |
if (generatorBodyScope->strictMode()) |
2145 |
if (generatorBodyScope->strictMode()) |
| 2047 |
functionScope->setStrictMode(); |
2146 |
functionScope->setStrictMode(); |
| 2048 |
|
2147 |
|
| 2049 |
semanticFailIfTrue(generatorBodyScope->hasDirectSuper(), "Cannot call super() outside of a class constructor"); |
2148 |
if (mode != SourceParseMode::AsyncArrowFunctionMode) { |
| 2050 |
if (generatorBodyScope->needsSuperBinding()) |
2149 |
semanticFailIfTrue(generatorBodyScope->hasDirectSuper(), "Cannot call super() outside of a class constructor"); |
| 2051 |
semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class"); |
2150 |
if (generatorBodyScope->needsSuperBinding()) |
|
|
2151 |
semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class"); |
| 2152 |
} else { |
| 2153 |
if (generatorBodyScope->hasDirectSuper()) |
| 2154 |
functionScope->setHasDirectSuper(); |
| 2155 |
if (generatorBodyScope->needsSuperBinding()) |
| 2156 |
functionScope->setNeedsSuperBinding(); |
| 2157 |
} |
| 2052 |
|
2158 |
|
| 2053 |
popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo); |
2159 |
popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo); |
| 2054 |
} else |
2160 |
} else |
|
Lines 2058-2064
template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
a/Source/JavaScriptCore/parser/Parser.cpp_sec24
|
| 2058 |
failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); |
2164 |
failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); |
| 2059 |
context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); |
2165 |
context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); |
| 2060 |
if (functionScope->strictMode() && functionInfo.name) { |
2166 |
if (functionScope->strictMode() && functionInfo.name) { |
| 2061 |
RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode); |
2167 |
RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)); |
| 2062 |
semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); |
2168 |
semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); |
| 2063 |
semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); |
2169 |
semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); |
| 2064 |
} |
2170 |
} |
|
Lines 2167-2172
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
a/Source/JavaScriptCore/parser/Parser.cpp_sec25
|
| 2167 |
} |
2273 |
} |
| 2168 |
|
2274 |
|
| 2169 |
template <typename LexerType> |
2275 |
template <typename LexerType> |
|
|
2276 |
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType) |
| 2277 |
{ |
| 2278 |
ASSERT(match(FUNCTION)); |
| 2279 |
JSTokenLocation location(tokenLocation()); |
| 2280 |
unsigned functionKeywordStart = tokenStart(); |
| 2281 |
next(); |
| 2282 |
ParserFunctionInfo<TreeBuilder> functionInfo; |
| 2283 |
SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; |
| 2284 |
|
| 2285 |
failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function"); |
| 2286 |
failIfFalse(functionInfo.name, "Async function statements must have a name"); |
| 2287 |
|
| 2288 |
std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name); |
| 2289 |
DeclarationResultMask declarationResult = functionDeclaration.first; |
| 2290 |
failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode"); |
| 2291 |
if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) |
| 2292 |
internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode"); |
| 2293 |
if (exportType == ExportType::Exported) { |
| 2294 |
semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'"); |
| 2295 |
currentScope()->moduleScopeData().exportBinding(*functionInfo.name); |
| 2296 |
} |
| 2297 |
|
| 2298 |
TreeStatement result = context.createFuncDeclStatement(location, functionInfo); |
| 2299 |
if (TreeBuilder::CreatesAST) |
| 2300 |
functionDeclaration.second->appendFunction(getMetadata(functionInfo)); |
| 2301 |
return result; |
| 2302 |
} |
| 2303 |
|
| 2304 |
template <typename LexerType> |
| 2170 |
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType) |
2305 |
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType) |
| 2171 |
{ |
2306 |
{ |
| 2172 |
ASSERT(match(CLASSTOKEN)); |
2307 |
ASSERT(match(CLASSTOKEN)); |
|
Lines 2247-2252
template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
a/Source/JavaScriptCore/parser/Parser.cpp_sec26
|
| 2247 |
|
2382 |
|
| 2248 |
// For backwards compatibility, "static" is a non-reserved keyword in non-strict mode. |
2383 |
// For backwards compatibility, "static" is a non-reserved keyword in non-strict mode. |
| 2249 |
bool isStaticMethod = false; |
2384 |
bool isStaticMethod = false; |
|
|
2385 |
bool isAsyncMethod = false; |
| 2250 |
if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) { |
2386 |
if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) { |
| 2251 |
SavePoint savePoint = createSavePoint(); |
2387 |
SavePoint savePoint = createSavePoint(); |
| 2252 |
next(); |
2388 |
next(); |
|
Lines 2257-2262
template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
a/Source/JavaScriptCore/parser/Parser.cpp_sec27
|
| 2257 |
isStaticMethod = true; |
2393 |
isStaticMethod = true; |
| 2258 |
} |
2394 |
} |
| 2259 |
|
2395 |
|
|
|
2396 |
if (match(ASYNC)) { |
| 2397 |
SavePoint beforeAsync = createSavePoint(); |
| 2398 |
next(); |
| 2399 |
if (!m_lexer->prevTerminator() && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) |
| 2400 |
isAsyncMethod = true; |
| 2401 |
else |
| 2402 |
restoreSavePoint(beforeAsync); |
| 2403 |
} |
| 2404 |
|
| 2260 |
// FIXME: Figure out a way to share more code with parseProperty. |
2405 |
// FIXME: Figure out a way to share more code with parseProperty. |
| 2261 |
const CommonIdentifiers& propertyNames = *m_vm->propertyNames; |
2406 |
const CommonIdentifiers& propertyNames = *m_vm->propertyNames; |
| 2262 |
const Identifier* ident = &propertyNames.nullIdentifier; |
2407 |
const Identifier* ident = &propertyNames.nullIdentifier; |
|
Lines 2265-2271
template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
a/Source/JavaScriptCore/parser/Parser.cpp_sec28
|
| 2265 |
bool isSetter = false; |
2410 |
bool isSetter = false; |
| 2266 |
bool isGenerator = false; |
2411 |
bool isGenerator = false; |
| 2267 |
#if ENABLE(ES6_GENERATORS) |
2412 |
#if ENABLE(ES6_GENERATORS) |
| 2268 |
if (consume(TIMES)) |
2413 |
if (!isAsyncMethod && consume(TIMES)) |
| 2269 |
isGenerator = true; |
2414 |
isGenerator = true; |
| 2270 |
#endif |
2415 |
#endif |
| 2271 |
switch (m_token.m_type) { |
2416 |
switch (m_token.m_type) { |
|
Lines 2279-2285
template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
a/Source/JavaScriptCore/parser/Parser.cpp_sec29
|
| 2279 |
ident = m_token.m_data.ident; |
2424 |
ident = m_token.m_data.ident; |
| 2280 |
ASSERT(ident); |
2425 |
ASSERT(ident); |
| 2281 |
next(); |
2426 |
next(); |
| 2282 |
if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) { |
2427 |
if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) { |
| 2283 |
isGetter = *ident == propertyNames.get; |
2428 |
isGetter = *ident == propertyNames.get; |
| 2284 |
isSetter = *ident == propertyNames.set; |
2429 |
isSetter = *ident == propertyNames.set; |
| 2285 |
} |
2430 |
} |
|
Lines 2312-2318
template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
a/Source/JavaScriptCore/parser/Parser.cpp_sec30
|
| 2312 |
ParserFunctionInfo<TreeBuilder> methodInfo; |
2457 |
ParserFunctionInfo<TreeBuilder> methodInfo; |
| 2313 |
bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; |
2458 |
bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; |
| 2314 |
SourceParseMode parseMode = SourceParseMode::MethodMode; |
2459 |
SourceParseMode parseMode = SourceParseMode::MethodMode; |
| 2315 |
if (isGenerator) { |
2460 |
if (isAsyncMethod) { |
|
|
2461 |
isConstructor = false; |
| 2462 |
parseMode = SourceParseMode::AsyncMethodMode; |
| 2463 |
semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'"); |
| 2464 |
semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'"); |
| 2465 |
} else if (isGenerator) { |
| 2316 |
isConstructor = false; |
2466 |
isConstructor = false; |
| 2317 |
parseMode = SourceParseMode::GeneratorWrapperFunctionMode; |
2467 |
parseMode = SourceParseMode::GeneratorWrapperFunctionMode; |
| 2318 |
semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'"); |
2468 |
semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'"); |
|
Lines 2394-2402
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
a/Source/JavaScriptCore/parser/Parser.cpp_sec31
|
| 2394 |
return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line); |
2544 |
return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line); |
| 2395 |
} |
2545 |
} |
| 2396 |
const Identifier* ident = m_token.m_data.ident; |
2546 |
const Identifier* ident = m_token.m_data.ident; |
|
|
2547 |
const bool isDisallowedLabelAwait = isDisallowedIdentifierAwait(m_token); |
| 2397 |
JSTextPosition end = tokenEndPosition(); |
2548 |
JSTextPosition end = tokenEndPosition(); |
| 2398 |
next(); |
2549 |
next(); |
| 2399 |
consumeOrFail(COLON, "Labels must be followed by a ':'"); |
2550 |
consumeOrFail(COLON, "Labels must be followed by a ':'"); |
|
|
2551 |
semanticFailIfTrue(isDisallowedLabelAwait, "Can't use 'await' as a label ", disallowedIdentifierAwaitReason()); |
| 2400 |
if (!m_syntaxAlreadyValidated) { |
2552 |
if (!m_syntaxAlreadyValidated) { |
| 2401 |
// This is O(N^2) over the current list of consecutive labels, but I |
2553 |
// This is O(N^2) over the current list of consecutive labels, but I |
| 2402 |
// have never seen more than one label in a row in the real world. |
2554 |
// have never seen more than one label in a row in the real world. |
|
Lines 2743-2748
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
a/Source/JavaScriptCore/parser/Parser.cpp_sec32
|
| 2743 |
JSTokenLocation exportLocation(tokenLocation()); |
2895 |
JSTokenLocation exportLocation(tokenLocation()); |
| 2744 |
next(); |
2896 |
next(); |
| 2745 |
|
2897 |
|
|
|
2898 |
bool isAsyncFunctionExport = false; |
| 2899 |
|
| 2746 |
switch (m_token.m_type) { |
2900 |
switch (m_token.m_type) { |
| 2747 |
case TIMES: { |
2901 |
case TIMES: { |
| 2748 |
// export * FromClause ; |
2902 |
// export * FromClause ; |
|
Lines 2769-2774
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
a/Source/JavaScriptCore/parser/Parser.cpp_sec33
|
| 2769 |
const Identifier* localName = nullptr; |
2923 |
const Identifier* localName = nullptr; |
| 2770 |
SavePoint savePoint = createSavePoint(); |
2924 |
SavePoint savePoint = createSavePoint(); |
| 2771 |
|
2925 |
|
|
|
2926 |
if (UNLIKELY(match(ASYNC))) { |
| 2927 |
next(); |
| 2928 |
if (match(FUNCTION) && !m_lexer->prevTerminator()) |
| 2929 |
isAsyncFunctionExport = true; |
| 2930 |
else |
| 2931 |
restoreSavePoint(savePoint); |
| 2932 |
} |
| 2933 |
|
| 2772 |
bool startsWithFunction = match(FUNCTION); |
2934 |
bool startsWithFunction = match(FUNCTION); |
| 2773 |
if (startsWithFunction |
2935 |
if (startsWithFunction |
| 2774 |
#if ENABLE(ES6_CLASS_SYNTAX) |
2936 |
#if ENABLE(ES6_CLASS_SYNTAX) |
|
Lines 2780-2786
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
a/Source/JavaScriptCore/parser/Parser.cpp_sec34
|
| 2780 |
|
2942 |
|
| 2781 |
#if ENABLE(ES6_GENERATORS) |
2943 |
#if ENABLE(ES6_GENERATORS) |
| 2782 |
// ES6 Generators |
2944 |
// ES6 Generators |
| 2783 |
if (startsWithFunction && match(TIMES)) |
2945 |
if (!isAsyncFunctionExport && startsWithFunction && match(TIMES)) |
| 2784 |
next(); |
2946 |
next(); |
| 2785 |
#endif |
2947 |
#endif |
| 2786 |
if (match(IDENT)) |
2948 |
if (match(IDENT)) |
|
Lines 2793-2798
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
a/Source/JavaScriptCore/parser/Parser.cpp_sec35
|
| 2793 |
DepthManager statementDepth(&m_statementDepth); |
2955 |
DepthManager statementDepth(&m_statementDepth); |
| 2794 |
m_statementDepth = 1; |
2956 |
m_statementDepth = 1; |
| 2795 |
result = parseFunctionDeclaration(context); |
2957 |
result = parseFunctionDeclaration(context); |
|
|
2958 |
} if (isAsyncFunctionExport) { |
| 2959 |
ASSERT(match(ASYNC)); |
| 2960 |
next(); |
| 2961 |
DepthManager statementDepth(&m_statementDepth); |
| 2962 |
m_statementDepth = 1; |
| 2963 |
result = parseAsyncFunctionDeclaration(context); |
| 2796 |
} |
2964 |
} |
| 2797 |
#if ENABLE(ES6_CLASS_SYNTAX) |
2965 |
#if ENABLE(ES6_CLASS_SYNTAX) |
| 2798 |
else { |
2966 |
else { |
|
Lines 2917-2922
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
a/Source/JavaScriptCore/parser/Parser.cpp_sec36
|
| 2917 |
#endif |
3085 |
#endif |
| 2918 |
|
3086 |
|
| 2919 |
default: |
3087 |
default: |
|
|
3088 |
if (UNLIKELY(match(ASYNC))) { |
| 3089 |
SavePoint beforeAsync = createSavePoint(); |
| 3090 |
next(); |
| 3091 |
if (match(FUNCTION) && !m_lexer->prevTerminator()) { |
| 3092 |
result = parseAsyncFunctionDeclaration(context, ExportType::Exported); |
| 3093 |
break; |
| 3094 |
} |
| 3095 |
restoreSavePoint(beforeAsync); |
| 3096 |
} |
| 2920 |
failWithMessage("Expected either a declaration or a variable statement"); |
3097 |
failWithMessage("Expected either a declaration or a variable statement"); |
| 2921 |
break; |
3098 |
break; |
| 2922 |
} |
3099 |
} |
|
Lines 2987-2994
template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
a/Source/JavaScriptCore/parser/Parser.cpp_sec37
|
| 2987 |
int initialNonLHSCount = m_parserState.nonLHSCount; |
3164 |
int initialNonLHSCount = m_parserState.nonLHSCount; |
| 2988 |
bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET); |
3165 |
bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET); |
| 2989 |
#if ENABLE(ES6_ARROWFUNCTION_SYNTAX) |
3166 |
#if ENABLE(ES6_ARROWFUNCTION_SYNTAX) |
|
|
3167 |
bool isAsyncArrow = false; |
| 3168 |
SavePoint beforeAsyncKeyword = createSavePoint(); |
| 3169 |
if (UNLIKELY(match(ASYNC))) { |
| 3170 |
next(); |
| 3171 |
if (m_lexer->prevTerminator() || !(match(OPENPAREN) || matchSpecIdentifier())) |
| 3172 |
restoreSavePoint(beforeAsyncKeyword); |
| 3173 |
else |
| 3174 |
isAsyncArrow = true; |
| 3175 |
} |
| 3176 |
|
| 2990 |
bool wasOpenParen = match(OPENPAREN); |
3177 |
bool wasOpenParen = match(OPENPAREN); |
| 2991 |
bool isValidArrowFunctionStart = match(OPENPAREN) || match(IDENT); |
3178 |
bool isValidArrowFunctionStart = match(OPENPAREN) || matchSpecIdentifier(); |
| 2992 |
SavePoint savePoint = createSavePoint(); |
3179 |
SavePoint savePoint = createSavePoint(); |
| 2993 |
size_t usedVariablesSize; |
3180 |
size_t usedVariablesSize; |
| 2994 |
if (wasOpenParen) { |
3181 |
if (wasOpenParen) { |
|
Lines 3002-3012
template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
a/Source/JavaScriptCore/parser/Parser.cpp_sec38
|
| 3002 |
return parseYieldExpression(context); |
3189 |
return parseYieldExpression(context); |
| 3003 |
#endif |
3190 |
#endif |
| 3004 |
|
3191 |
|
|
|
3192 |
tryParseConditional: |
| 3005 |
TreeExpression lhs = parseConditionalExpression(context); |
3193 |
TreeExpression lhs = parseConditionalExpression(context); |
| 3006 |
|
3194 |
|
| 3007 |
#if ENABLE(ES6_ARROWFUNCTION_SYNTAX) |
3195 |
#if ENABLE(ES6_ARROWFUNCTION_SYNTAX) |
| 3008 |
if (isValidArrowFunctionStart && !match(EOFTOK)) { |
3196 |
if (isValidArrowFunctionStart && !match(EOFTOK)) { |
| 3009 |
bool isArrowFunctionToken = match(ARROWFUNCTION); |
3197 |
bool isArrowFunctionToken = match(ARROWFUNCTION); |
|
|
3198 |
|
| 3010 |
if (!lhs || isArrowFunctionToken) { |
3199 |
if (!lhs || isArrowFunctionToken) { |
| 3011 |
SavePoint errorRestorationSavePoint = createSavePointForError(); |
3200 |
SavePoint errorRestorationSavePoint = createSavePointForError(); |
| 3012 |
String oldErrorMessage = m_errorMessage; |
3201 |
String oldErrorMessage = m_errorMessage; |
|
Lines 3016-3023
template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
a/Source/JavaScriptCore/parser/Parser.cpp_sec39
|
| 3016 |
if (isArrowFunctionParameters()) { |
3205 |
if (isArrowFunctionParameters()) { |
| 3017 |
if (wasOpenParen) |
3206 |
if (wasOpenParen) |
| 3018 |
currentScope()->revertToPreviousUsedVariables(usedVariablesSize); |
3207 |
currentScope()->revertToPreviousUsedVariables(usedVariablesSize); |
| 3019 |
return parseArrowFunctionExpression(context); |
3208 |
return parseArrowFunctionExpression(context, isAsyncArrow); |
| 3020 |
} |
3209 |
} |
|
|
3210 |
|
| 3211 |
if (isAsyncArrow) { |
| 3212 |
// Re-parse without skipping over `async` keyword. |
| 3213 |
m_errorMessage = String(); |
| 3214 |
m_lexer->setErrorMessage(String()); |
| 3215 |
m_lexer->setSawError(false); |
| 3216 |
isValidArrowFunctionStart = false; |
| 3217 |
isAsyncArrow = false; |
| 3218 |
restoreSavePoint(beforeAsyncKeyword); |
| 3219 |
goto tryParseConditional; |
| 3220 |
} |
| 3221 |
|
| 3021 |
restoreSavePointWithError(errorRestorationSavePoint, oldErrorMessage); |
3222 |
restoreSavePointWithError(errorRestorationSavePoint, oldErrorMessage); |
| 3022 |
m_lexer->setErrorMessage(oldLexerErrorMessage); |
3223 |
m_lexer->setErrorMessage(oldLexerErrorMessage); |
| 3023 |
m_lexer->setSawError(hasLexerError); |
3224 |
m_lexer->setSawError(hasLexerError); |
|
Lines 3149-3154
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseYieldExpress
a/Source/JavaScriptCore/parser/Parser.cpp_sec40
|
| 3149 |
} |
3350 |
} |
| 3150 |
|
3351 |
|
| 3151 |
template <typename LexerType> |
3352 |
template <typename LexerType> |
|
|
3353 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAwaitExpression(TreeBuilder& context) |
| 3354 |
{ |
| 3355 |
// AwaitExpression desugared to YieldExpression |
| 3356 |
ASSERT(match(AWAIT)); |
| 3357 |
ASSERT(currentScope()->isAsyncFunction()); |
| 3358 |
failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use await expression within parameters"); |
| 3359 |
JSTokenLocation location(tokenLocation()); |
| 3360 |
JSTextPosition divotStart = tokenStartPosition(); |
| 3361 |
next(); |
| 3362 |
JSTextPosition argumentStart = tokenStartPosition(); |
| 3363 |
TreeExpression argument = parseUnaryExpression(context); |
| 3364 |
failIfFalse(argument, "Failed to parse await expression"); |
| 3365 |
const bool delegate = false; |
| 3366 |
return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition()); |
| 3367 |
} |
| 3368 |
|
| 3369 |
template <typename LexerType> |
| 3152 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context) |
3370 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context) |
| 3153 |
{ |
3371 |
{ |
| 3154 |
JSTokenLocation location(tokenLocation()); |
3372 |
JSTokenLocation location(tokenLocation()); |
|
Lines 3232-3242
template <typename LexerType>
a/Source/JavaScriptCore/parser/Parser.cpp_sec41
|
| 3232 |
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete) |
3450 |
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete) |
| 3233 |
{ |
3451 |
{ |
| 3234 |
bool wasIdent = false; |
3452 |
bool wasIdent = false; |
|
|
3453 |
bool wasAsync = false; |
| 3235 |
bool isGenerator = false; |
3454 |
bool isGenerator = false; |
| 3236 |
#if ENABLE(ES6_GENERATORS) |
3455 |
#if ENABLE(ES6_GENERATORS) |
| 3237 |
if (consume(TIMES)) |
3456 |
if (consume(TIMES)) |
| 3238 |
isGenerator = true; |
3457 |
isGenerator = true; |
| 3239 |
#endif |
3458 |
#endif |
|
|
3459 |
|
| 3460 |
if (UNLIKELY(!isGenerator && match(ASYNC))) { |
| 3461 |
SavePoint beforeAsync = createSavePoint(); |
| 3462 |
next(); |
| 3463 |
if (!m_lexer->prevTerminator() && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) |
| 3464 |
wasAsync = true; |
| 3465 |
else |
| 3466 |
restoreSavePoint(beforeAsync); |
| 3467 |
} |
| 3468 |
|
| 3240 |
switch (m_token.m_type) { |
3469 |
switch (m_token.m_type) { |
| 3241 |
namedProperty: |
3470 |
namedProperty: |
| 3242 |
case IDENT: |
3471 |
case IDENT: |
|
Lines 3259-3265
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
a/Source/JavaScriptCore/parser/Parser.cpp_sec42
|
| 3259 |
} |
3488 |
} |
| 3260 |
|
3489 |
|
| 3261 |
if (match(OPENPAREN)) { |
3490 |
if (match(OPENPAREN)) { |
| 3262 |
auto method = parsePropertyMethod(context, ident, isGenerator); |
3491 |
auto method = parsePropertyMethod(context, ident, isGenerator, wasAsync); |
| 3263 |
propagateError(); |
3492 |
propagateError(); |
| 3264 |
return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete); |
3493 |
return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete); |
| 3265 |
} |
3494 |
} |
|
Lines 3296-3302
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
a/Source/JavaScriptCore/parser/Parser.cpp_sec43
|
| 3296 |
|
3525 |
|
| 3297 |
if (match(OPENPAREN)) { |
3526 |
if (match(OPENPAREN)) { |
| 3298 |
const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName); |
3527 |
const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName); |
| 3299 |
auto method = parsePropertyMethod(context, &ident, isGenerator); |
3528 |
auto method = parsePropertyMethod(context, &ident, isGenerator, wasAsync); |
| 3300 |
propagateError(); |
3529 |
propagateError(); |
| 3301 |
return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete); |
3530 |
return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete); |
| 3302 |
} |
3531 |
} |
|
Lines 3315-3321
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
a/Source/JavaScriptCore/parser/Parser.cpp_sec44
|
| 3315 |
handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name"); |
3544 |
handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name"); |
| 3316 |
|
3545 |
|
| 3317 |
if (match(OPENPAREN)) { |
3546 |
if (match(OPENPAREN)) { |
| 3318 |
auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator); |
3547 |
auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, wasAsync); |
| 3319 |
propagateError(); |
3548 |
propagateError(); |
| 3320 |
return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete); |
3549 |
return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete); |
| 3321 |
} |
3550 |
} |
|
Lines 3334-3345
template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
a/Source/JavaScriptCore/parser/Parser.cpp_sec45
|
| 3334 |
} |
3563 |
} |
| 3335 |
|
3564 |
|
| 3336 |
template <typename LexerType> |
3565 |
template <typename LexerType> |
| 3337 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator) |
3566 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsync) |
| 3338 |
{ |
3567 |
{ |
| 3339 |
JSTokenLocation methodLocation(tokenLocation()); |
3568 |
JSTokenLocation methodLocation(tokenLocation()); |
| 3340 |
unsigned methodStart = tokenStart(); |
3569 |
unsigned methodStart = tokenStart(); |
| 3341 |
ParserFunctionInfo<TreeBuilder> methodInfo; |
3570 |
ParserFunctionInfo<TreeBuilder> methodInfo; |
| 3342 |
SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode; |
3571 |
SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsync ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode; |
| 3343 |
failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); |
3572 |
failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); |
| 3344 |
methodInfo.name = methodName; |
3573 |
methodInfo.name = methodName; |
| 3345 |
return context.createMethodDefinition(methodLocation, methodInfo); |
3574 |
return context.createMethodDefinition(methodLocation, methodInfo); |
|
Lines 3599-3604
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseFunctionExpr
a/Source/JavaScriptCore/parser/Parser.cpp_sec46
|
| 3599 |
} |
3828 |
} |
| 3600 |
|
3829 |
|
| 3601 |
template <typename LexerType> |
3830 |
template <typename LexerType> |
|
|
3831 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAsyncFunctionExpression(TreeBuilder& context) |
| 3832 |
{ |
| 3833 |
ASSERT(match(FUNCTION)); |
| 3834 |
JSTokenLocation location(tokenLocation()); |
| 3835 |
unsigned functionKeywordStart = tokenStart(); |
| 3836 |
next(); |
| 3837 |
ParserFunctionInfo<TreeBuilder> functionInfo; |
| 3838 |
functionInfo.name = &m_vm->propertyNames->nullIdentifier; |
| 3839 |
SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; |
| 3840 |
failIfFalse(parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression"); |
| 3841 |
return context.createFunctionExpr(location, functionInfo); |
| 3842 |
} |
| 3843 |
|
| 3844 |
template <typename LexerType> |
| 3602 |
template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail) |
3845 |
template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail) |
| 3603 |
{ |
3846 |
{ |
| 3604 |
if (!isTemplateHead) { |
3847 |
if (!isTemplateHead) { |
|
Lines 3690-3695
template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
a/Source/JavaScriptCore/parser/Parser.cpp_sec47
|
| 3690 |
currentScope()->setInnerArrowFunctionUsesThis(); |
3933 |
currentScope()->setInnerArrowFunctionUsesThis(); |
| 3691 |
return context.createThisExpr(location, m_thisTDZMode); |
3934 |
return context.createThisExpr(location, m_thisTDZMode); |
| 3692 |
} |
3935 |
} |
|
|
3936 |
case AWAIT: |
| 3693 |
case IDENT: { |
3937 |
case IDENT: { |
| 3694 |
identifierExpression: |
3938 |
identifierExpression: |
| 3695 |
JSTextPosition start = tokenStartPosition(); |
3939 |
JSTextPosition start = tokenStartPosition(); |
|
Lines 3761-3766
template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
a/Source/JavaScriptCore/parser/Parser.cpp_sec48
|
| 3761 |
if (!strictMode() && !currentScope()->isGenerator()) |
4005 |
if (!strictMode() && !currentScope()->isGenerator()) |
| 3762 |
goto identifierExpression; |
4006 |
goto identifierExpression; |
| 3763 |
failDueToUnexpectedToken(); |
4007 |
failDueToUnexpectedToken(); |
|
|
4008 |
case ASYNC: { |
| 4009 |
SavePoint beforeAsync = createSavePoint(); |
| 4010 |
next(); |
| 4011 |
if (match(FUNCTION) && !m_lexer->prevTerminator()) |
| 4012 |
return parseAsyncFunctionExpression(context); |
| 4013 |
restoreSavePoint(beforeAsync); |
| 4014 |
goto identifierExpression; |
| 4015 |
} |
| 3764 |
case LET: |
4016 |
case LET: |
| 3765 |
if (!strictMode()) |
4017 |
if (!strictMode()) |
| 3766 |
goto identifierExpression; |
4018 |
goto identifierExpression; |
|
Lines 3961-3967
endMemberExpression:
a/Source/JavaScriptCore/parser/Parser.cpp_sec49
|
| 3961 |
} |
4213 |
} |
| 3962 |
|
4214 |
|
| 3963 |
template <typename LexerType> |
4215 |
template <typename LexerType> |
| 3964 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context) |
4216 |
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context, bool isAsync) |
| 3965 |
{ |
4217 |
{ |
| 3966 |
JSTokenLocation location; |
4218 |
JSTokenLocation location; |
| 3967 |
|
4219 |
|
|
Lines 3969-3975
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctio
a/Source/JavaScriptCore/parser/Parser.cpp_sec50
|
| 3969 |
location = tokenLocation(); |
4221 |
location = tokenLocation(); |
| 3970 |
ParserFunctionInfo<TreeBuilder> info; |
4222 |
ParserFunctionInfo<TreeBuilder> info; |
| 3971 |
info.name = &m_vm->propertyNames->nullIdentifier; |
4223 |
info.name = &m_vm->propertyNames->nullIdentifier; |
| 3972 |
failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); |
4224 |
SourceParseMode parseMode = isAsync ? SourceParseMode::AsyncArrowFunctionMode : SourceParseMode::ArrowFunctionMode; |
|
|
4225 |
|
| 4226 |
failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); |
| 3973 |
|
4227 |
|
| 3974 |
return context.createArrowFunctionExpr(location, info); |
4228 |
return context.createArrowFunctionExpr(location, info); |
| 3975 |
} |
4229 |
} |
|
Lines 4013-4018
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
a/Source/JavaScriptCore/parser/Parser.cpp_sec51
|
| 4013 |
bool modifiesExpr = false; |
4267 |
bool modifiesExpr = false; |
| 4014 |
bool requiresLExpr = false; |
4268 |
bool requiresLExpr = false; |
| 4015 |
unsigned lastOperator = 0; |
4269 |
unsigned lastOperator = 0; |
|
|
4270 |
|
| 4271 |
if (match(AWAIT) && !isAWAITMaskedAsIDENT()) |
| 4272 |
return parseAwaitExpression(context); |
| 4273 |
|
| 4016 |
while (isUnaryOp(m_token.m_type)) { |
4274 |
while (isUnaryOp(m_token.m_type)) { |
| 4017 |
if (strictMode()) { |
4275 |
if (strictMode()) { |
| 4018 |
switch (m_token.m_type) { |
4276 |
switch (m_token.m_type) { |