Changeset 201523 in webkit


Ignore:
Timestamp:
May 31, 2016 1:57:20 PM (8 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Recover parser performance regression by async support
https://bugs.webkit.org/show_bug.cgi?id=158228

Reviewed by Saam Barati.

This patch recovers parser performance regression caused in r201481.

Compared to the version that reverts r201481, still ~1% regression remains.
But compared to ToT, this patch significantly improves the code-load performance.

In Linux x64 JSCOnly port, with GCC 5.3.1.

reverted v.s. patched.

reverted patched

closure 0.61805+-0.00376 ? 0.62280+-0.00525 ?
jquery 8.03778+-0.02114 8.03453+-0.04646

<geometric> 2.22883+-0.00836 ? 2.23688+-0.00995 ? might be 1.0036x slower

ToT v.s. patched.

baseline patched

closure 0.65490+-0.00351 0.62473+-0.00363 definitely 1.0483x faster
jquery 8.25373+-0.06256 8.04701+-0.03455 definitely 1.0257x faster

<geometric> 2.32488+-0.00921 2.24210+-0.00592 definitely 1.0369x faster

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • bytecode/UnlinkedFunctionExecutable.h:

Extend SourceParseMode.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::isArrowFunctionParameters):
Do not call matchSpecIdentifier() as much as we can. This greatly improves the performance.

(JSC::Parser<LexerType>::parseStatementListItem):
(JSC::Parser<LexerType>::parseStatement):
(JSC::Parser<LexerType>::parseFunctionParameters):
(JSC::Parser<LexerType>::parseFunctionInfo):
Do not touch currentScope()->isGenerator() even if it is unnecessary in parseFunctionInfo.
And accidental syntaxChecker => context changes are fixed.

(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
(JSC::Parser<LexerType>::parseImportClauseItem):
(JSC::Parser<LexerType>::parseExportDeclaration):
(JSC::Parser<LexerType>::parseAssignmentExpression):
Do not use matchSpecIdentifier() in the hot paths.

(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression):
(JSC::Parser<LexerType>::parseUnaryExpression):
(JSC::Parser<LexerType>::printUnexpectedTokenText): Deleted.

  • parser/Parser.h:

(JSC::isIdentifierOrKeyword):
AWAIT shoud be one of the keywords. This AWAIT check is unnecessary.

(JSC::Parser::upperScope):
(JSC::Parser::matchSpecIdentifier):
Touching currentScope() and its member causes significant performance degradation.
We carefully remove the above access in the hot paths.

(JSC::Parser::isDisallowedIdentifierAwait):

  • parser/ParserModes.h:

(JSC::SourceParseModeSet::SourceParseModeSet):
(JSC::SourceParseModeSet::contains):
(JSC::SourceParseModeSet::mergeSourceParseModes):
(JSC::isFunctionParseMode):
(JSC::isAsyncFunctionParseMode):
(JSC::isAsyncArrowFunctionParseMode):
(JSC::isAsyncFunctionWrapperParseMode):
(JSC::isAsyncFunctionBodyParseMode):
(JSC::isModuleParseMode):
(JSC::isProgramParseMode):
(JSC::constructAbilityForParseMode):
The parser frequently checks SourceParseMode. And variety of SourceParseMode becomes many.
So using switch onto SourceParseMode degrades the performance. Instead, we use bit tests to guard against
many SourceParseModes. We expect that this will be efficiently compiled into test & jmp.

  • parser/ParserTokens.h:

Change AWAIT to one of the keywords, as the same to YIELD / LET.

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r201520 r201523  
     12016-05-31  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Recover parser performance regression by async support
     4        https://bugs.webkit.org/show_bug.cgi?id=158228
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch recovers parser performance regression caused in r201481.
     9
     10        Compared to the version that reverts r201481, still ~1% regression remains.
     11        But compared to ToT, this patch significantly improves the code-load performance.
     12
     13        In Linux x64 JSCOnly port, with GCC 5.3.1.
     14
     15        reverted v.s. patched.
     16                                 reverted                  patched
     17
     18        closure              0.61805+-0.00376    ?     0.62280+-0.00525       ?
     19        jquery               8.03778+-0.02114          8.03453+-0.04646
     20
     21        <geometric>          2.22883+-0.00836    ?     2.23688+-0.00995       ? might be 1.0036x slower
     22
     23        ToT v.s. patched.
     24                                 baseline                  patched
     25
     26        closure              0.65490+-0.00351    ^     0.62473+-0.00363       ^ definitely 1.0483x faster
     27        jquery               8.25373+-0.06256    ^     8.04701+-0.03455       ^ definitely 1.0257x faster
     28
     29        <geometric>          2.32488+-0.00921    ^     2.24210+-0.00592       ^ definitely 1.0369x faster
     30
     31        * bytecode/UnlinkedFunctionExecutable.cpp:
     32        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     33        * bytecode/UnlinkedFunctionExecutable.h:
     34        Extend SourceParseMode.
     35
     36        * parser/Parser.cpp:
     37        (JSC::Parser<LexerType>::parseInner):
     38        (JSC::Parser<LexerType>::isArrowFunctionParameters):
     39        Do not call `matchSpecIdentifier()` as much as we can. This greatly improves the performance.
     40
     41        (JSC::Parser<LexerType>::parseStatementListItem):
     42        (JSC::Parser<LexerType>::parseStatement):
     43        (JSC::Parser<LexerType>::parseFunctionParameters):
     44        (JSC::Parser<LexerType>::parseFunctionInfo):
     45        Do not touch `currentScope()->isGenerator()` even if it is unnecessary in parseFunctionInfo.
     46        And accidental `syntaxChecker => context` changes are fixed.
     47
     48        (JSC::Parser<LexerType>::parseClass):
     49        (JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
     50        (JSC::Parser<LexerType>::parseImportClauseItem):
     51        (JSC::Parser<LexerType>::parseExportDeclaration):
     52        (JSC::Parser<LexerType>::parseAssignmentExpression):
     53        Do not use matchSpecIdentifier() in the hot paths.
     54
     55        (JSC::Parser<LexerType>::parseProperty):
     56        (JSC::Parser<LexerType>::parsePrimaryExpression):
     57        (JSC::Parser<LexerType>::parseMemberExpression):
     58        (JSC::Parser<LexerType>::parseUnaryExpression):
     59        (JSC::Parser<LexerType>::printUnexpectedTokenText): Deleted.
     60        * parser/Parser.h:
     61        (JSC::isIdentifierOrKeyword):
     62        AWAIT shoud be one of the keywords. This AWAIT check is unnecessary.
     63
     64        (JSC::Parser::upperScope):
     65        (JSC::Parser::matchSpecIdentifier):
     66        Touching currentScope() and its member causes significant performance degradation.
     67        We carefully remove the above access in the hot paths.
     68
     69        (JSC::Parser::isDisallowedIdentifierAwait):
     70        * parser/ParserModes.h:
     71        (JSC::SourceParseModeSet::SourceParseModeSet):
     72        (JSC::SourceParseModeSet::contains):
     73        (JSC::SourceParseModeSet::mergeSourceParseModes):
     74        (JSC::isFunctionParseMode):
     75        (JSC::isAsyncFunctionParseMode):
     76        (JSC::isAsyncArrowFunctionParseMode):
     77        (JSC::isAsyncFunctionWrapperParseMode):
     78        (JSC::isAsyncFunctionBodyParseMode):
     79        (JSC::isModuleParseMode):
     80        (JSC::isProgramParseMode):
     81        (JSC::constructAbilityForParseMode):
     82        The parser frequently checks SourceParseMode. And variety of SourceParseMode becomes many.
     83        So using switch onto SourceParseMode degrades the performance. Instead, we use bit tests to guard against
     84        many SourceParseModes. We expect that this will be efficiently compiled into test & jmp.
     85
     86        * parser/ParserTokens.h:
     87        Change AWAIT to one of the keywords, as the same to YIELD / LET.
     88
    1892016-05-31  Saam Barati  <sbarati@apple.com>
    290
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r201481 r201523  
    9292    , m_parameterCount(node->parameterCount())
    9393    , m_features(0)
     94    , m_sourceParseMode(node->parseMode())
    9495    , m_isInStrictContext(node->isInStrictContext())
    9596    , m_hasCapturedVariables(false)
     
    100101    , m_superBinding(static_cast<unsigned>(node->superBinding()))
    101102    , m_derivedContextType(static_cast<unsigned>(derivedContextType))
    102     , m_sourceParseMode(static_cast<unsigned>(node->parseMode()))
    103103    , m_name(node->ident())
    104104    , m_ecmaName(node->ecmaName())
     
    113113    ASSERT(m_superBinding == static_cast<unsigned>(node->superBinding()));
    114114    ASSERT(m_derivedContextType == static_cast<unsigned>(derivedContextType));
    115     ASSERT(m_sourceParseMode == static_cast<unsigned>(node->parseMode()));
    116115
    117116    m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r201481 r201523  
    159159    unsigned m_parameterCount;
    160160    CodeFeatures m_features;
     161    SourceParseMode m_sourceParseMode;
    161162    unsigned m_isInStrictContext : 1;
    162163    unsigned m_hasCapturedVariables : 1;
     
    167168    unsigned m_superBinding : 1;
    168169    unsigned m_derivedContextType: 2;
    169     unsigned m_sourceParseMode : 4; // SourceParseMode
    170170
    171171    WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r201488 r201523  
    8181    if (m_token.m_type & KeywordTokenFlag) \
    8282        semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
    83     if (isDisallowedIdentifierAwait(m_token)) \
    84         semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \
    8583} while (0)
    8684
     
    259257    if (m_lexer->isReparsingFunction()) {
    260258        ParserFunctionInfo<ASTBuilder> functionInfo;
    261         if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode))
     259        if (SourceParseModeSet(SourceParseMode::GeneratorBodyMode).contains(parseMode) || isAsyncFunctionBodyParseMode(parseMode))
    262260            m_parameters = createGeneratorParameters(context);
    263261        else
    264262            m_parameters = parseFunctionParameters(context, parseMode, functionInfo);
    265263
    266         if ((parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !hasError()) {
     264        if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && !hasError()) {
    267265            // The only way we could have an error wile reparsing is if we run out of stack space.
    268266            RELEASE_ASSERT(match(ARROWFUNCTION));
     
    310308        varDeclarations.markVariableAsCaptured(entry);
    311309
    312     if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) {
     310    if (SourceParseModeSet(SourceParseMode::GeneratorWrapperFunctionMode).contains(parseMode) || isAsyncFunctionWrapperParseMode(parseMode)) {
    313311        if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
    314312            context.propagateArgumentsUse();
     
    355353bool Parser<LexerType>::isArrowFunctionParameters()
    356354{
    357     bool isOpenParen = match(OPENPAREN);
    358     bool isIdent = matchSpecIdentifier();
    359    
    360     if (!isOpenParen && !isIdent)
    361         return false;
    362 
    363     bool isArrowFunction = false;
    364     SavePoint saveArrowFunctionPoint = createSavePoint();
    365        
    366     if (isIdent) {
    367         next();
    368         isArrowFunction = match(ARROWFUNCTION);
    369     } else {
    370         RELEASE_ASSERT(isOpenParen);
    371         next();
     355    if (match(OPENPAREN)) {
     356        SavePoint saveArrowFunctionPoint = createSavePoint();
     357        next();
     358        bool isArrowFunction = false;
    372359        if (match(CLOSEPAREN)) {
    373360            next();
     
    381368            unsigned parametersCount = 0;
    382369            isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
    383                
     370
    384371            popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
    385372        }
    386     }
    387        
    388     restoreSavePoint(saveArrowFunctionPoint);
    389        
    390     return isArrowFunction;
     373        restoreSavePoint(saveArrowFunctionPoint);
     374        return isArrowFunction;
     375    }
     376
     377    if (matchSpecIdentifier()) {
     378        SavePoint saveArrowFunctionPoint = createSavePoint();
     379        next();
     380        bool isArrowFunction = match(ARROWFUNCTION);
     381        restoreSavePoint(saveArrowFunctionPoint);
     382        return isArrowFunction;
     383    }
     384
     385    return false;
    391386}
    392387
     
    601596            // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration
    602597            // to raise consistent errors between "var", "const" and "let".
    603             if (!(match(IDENT) || match(AWAIT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))
     598            if (!(match(IDENT) || match(LET) || match(YIELD) || match(AWAIT)) && !match(OPENBRACE) && !match(OPENBRACKET))
    604599                shouldParseVariableDeclaration = false;
    605600            restoreSavePoint(savePoint);
     
    620615        result = parseFunctionDeclaration(context);
    621616        break;
    622 
    623617    case IDENT:
    624         if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
    625             // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case,
    626             // but could be mistakenly parsed as an AsyncFunctionExpression.
    627             SavePoint savePoint = createSavePoint();
    628             next();
    629             if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) {
    630                 result = parseAsyncFunctionDeclaration(context);
    631                 break;
     618        // FIXME: This branch contributes to a 1% octane code-load regression.
     619        // https://bugs.webkit.org/show_bug.cgi?id=158211
     620        if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async)) {
     621            if (m_runtimeFlags.isAsyncAwaitEnabled()) {
     622                // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case,
     623                // but could be mistakenly parsed as an AsyncFunctionExpression.
     624                SavePoint savePoint = createSavePoint();
     625                next();
     626                if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) {
     627                    result = parseAsyncFunctionDeclaration(context);
     628                    break;
     629                }
     630                restoreSavePoint(savePoint);
    632631            }
    633             restoreSavePoint(savePoint);
    634632        }
    635633        FALLTHROUGH;
     
    17361734        // These tokens imply the end of a set of source elements
    17371735        return 0;
    1738 
    17391736    case IDENT:
    1740         if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
    1741             SavePoint savePoint = createSavePoint();
    1742             next();
    1743             if (match(FUNCTION) && !m_lexer->prevTerminator()) {
    1744                 const bool isAsync = true;
    1745                 result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
    1746                 break;
     1737        // FIXME: This branch contributes to a 1% octane code-load regression.
     1738        // https://bugs.webkit.org/show_bug.cgi?id=158211
     1739        if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async)) {
     1740            if (m_runtimeFlags.isAsyncAwaitEnabled()) {
     1741                SavePoint savePoint = createSavePoint();
     1742                next();
     1743                if (match(FUNCTION) && !m_lexer->prevTerminator()) {
     1744                    const bool isAsync = true;
     1745                    result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
     1746                    break;
     1747                }
     1748                restoreSavePoint(savePoint);
    17471749            }
    1748             restoreSavePoint(savePoint);
    17491750        }
    17501751        FALLTHROUGH;
     
    19301931template <typename LexerType> template <class TreeBuilder, class FunctionInfoType> typename TreeBuilder::FormalParameterList Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, SourceParseMode mode, FunctionInfoType& functionInfo)
    19311932{
    1932     RELEASE_ASSERT(mode != SourceParseMode::ProgramMode && mode != SourceParseMode::ModuleAnalyzeMode && mode != SourceParseMode::ModuleEvaluateMode);
     1933    ASSERT(!(SourceParseModeSet(SourceParseMode::ProgramMode, SourceParseMode::ModuleAnalyzeMode, SourceParseMode::ModuleEvaluateMode).contains(mode)));
    19331934    TreeFormalParameterList parameterList = context.createFormalParameterList();
    19341935    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
    19351936   
    1936     if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
     1937    if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)) {
    19371938        if (!matchSpecIdentifier() && !match(OPENPAREN)) {
    19381939            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
     
    20262027    RELEASE_ASSERT(isFunctionParseMode(mode));
    20272028
    2028     bool upperScopeIsGenerator = currentScope()->isGenerator();
    20292029    bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token);
    20302030    const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr;
     2031
    20312032    AutoPopScopeRef functionScope(this, pushScope());
    20322033    functionScope->setSourceParseMode(mode);
     
    20672068           
    20682069            FunctionBodyType functionBodyType;
    2069             if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode)
     2070            if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode))
    20702071                functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
    20712072            else
     
    21102111    SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
    21112112
    2112     if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
     2113    if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)) {
    21132114        startLocation = tokenLocation();
    21142115        functionInfo.startLine = tokenLine();
     
    21222123        {
    21232124            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
    2124             parseFunctionParameters(context, mode, functionInfo);
     2125            parseFunctionParameters(syntaxChecker, mode, functionInfo);
    21252126        }
    21262127
     
    21552156        //
    21562157        // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator.
    2157         if (functionDefinitionType == FunctionDefinitionType::Expression && (mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::AsyncFunctionMode))
    2158             upperScopeIsGenerator = false;
     2158        bool upperScopeIsGenerator = false;
     2159        if (!(functionDefinitionType == FunctionDefinitionType::Expression && SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::AsyncFunctionMode).contains(mode)))
     2160            upperScopeIsGenerator = upperScope(1)->isGenerator();
    21592161
    21602162        if (matchSpecIdentifier(upperScopeIsGenerator)) {
     
    21712173                failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
    21722174        } else if (requirements == FunctionNeedsName) {
    2173             semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
    2174             semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
     2175            if (match(OPENPAREN)) {
     2176                semanticFailIfTrue(mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
     2177                semanticFailIfTrue(mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
     2178            }
    21752179            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
    21762180            failDueToUnexpectedToken();
     
    21902194        {
    21912195            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
    2192             parseFunctionParameters(context, mode, functionInfo);
     2196            parseFunctionParameters(syntaxChecker, mode, functionInfo);
    21932197            propagateError();
    21942198        }
     
    22362240    };
    22372241
    2238     if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) {
     2242    if (UNLIKELY((SourceParseModeSet(SourceParseMode::GeneratorWrapperFunctionMode).contains(mode)) || isAsyncFunctionWrapperParseMode(mode))) {
    22392243        AutoPopScopeRef generatorBodyScope(this, pushScope());
    22402244        SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
     
    22622266    context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
    22632267    if (functionScope->strictMode() && functionInfo.name) {
    2264         RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode));
     2268        RELEASE_ASSERT((SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode)) || isAsyncFunctionWrapperParseMode(mode));
    22652269        semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
    22662270        semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
     
    24762480        bool isGenerator = false;
    24772481        bool isAsyncMethod = false;
    2478 
    24792482        if (consume(TIMES))
    24802483            isGenerator = true;
     
    24882491            next();
    24892492            break;
     2493        case IDENT:
    24902494        case AWAIT:
    2491         case IDENT:
    24922495            ident = m_token.m_data.ident;
    24932496            ASSERT(ident);
     
    24962499                isGetter = *ident == propertyNames.get;
    24972500                isSetter = *ident == propertyNames.set;
    2498                 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && !isAsyncMethod && *ident == propertyNames.async && !m_lexer->prevTerminator())) {
    2499                     isAsyncMethod = true;
    2500                     goto parseMethod;
     2501                if (UNLIKELY(!isAsyncMethod && *ident == propertyNames.async && !m_lexer->prevTerminator())) {
     2502                    if (m_runtimeFlags.isAsyncAwaitEnabled()) {
     2503                        isAsyncMethod = true;
     2504                        goto parseMethod;
     2505                    }
    25012506                }
    25022507            }
     
    26192624            return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
    26202625        }
     2626        // FIXME: This branch contributes to a 1% octane code-load regression.
     2627        // https://bugs.webkit.org/show_bug.cgi?id=158211
     2628        if (UNLIKELY(match(AWAIT)))
     2629            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
    26212630        const Identifier* ident = m_token.m_data.ident;
    2622         const bool isDisallowedLabelAwait = isDisallowedIdentifierAwait(m_token);
    26232631        JSTextPosition end = tokenEndPosition();
    26242632        next();
    26252633        consumeOrFail(COLON, "Labels must be followed by a ':'");
    2626         semanticFailIfTrue(isDisallowedLabelAwait, "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
    26272634        if (!m_syntaxAlreadyValidated) {
    26282635            // This is O(N^2) over the current list of consecutive labels, but I
     
    28592866    }
    28602867
     2868    semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name");
    28612869    semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
    2862     semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name");
    28632870    DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported);
    28642871    if (declarationResult != DeclarationResult::Valid) {
     
    30033010        SavePoint savePoint = createSavePoint();
    30043011
    3005         if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
    3006             next();
    3007             if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator()))
    3008                 isAsyncFunctionExport = true;
    3009             else
    3010                 restoreSavePoint(savePoint);
     3012        if (UNLIKELY(matchContextualKeyword(m_vm->propertyNames->async))) {
     3013            if (m_runtimeFlags.isAsyncAwaitEnabled()) {
     3014                next();
     3015                if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator()))
     3016                    isAsyncFunctionExport = true;
     3017                else
     3018                    restoreSavePoint(savePoint);
     3019            }
    30113020        }
    30123021
     
    31543163
    31553164        default:
    3156             if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
    3157                 next();
    3158                 semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator");
    3159                 result = parseAsyncFunctionDeclaration(context, ExportType::Exported);
    3160                 break;
     3165            if (UNLIKELY(matchContextualKeyword(m_vm->propertyNames->async))) {
     3166                if (m_runtimeFlags.isAsyncAwaitEnabled()) {
     3167                    next();
     3168                    semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator");
     3169                    result = parseAsyncFunctionDeclaration(context, ExportType::Exported);
     3170                    break;
     3171                }
    31613172            }
     3173
    31623174            failWithMessage("Expected either a declaration or a variable statement");
    31633175            break;
     
    32243236   
    32253237    failIfStackOverflow();
     3238
     3239    if (match(YIELD) && !isYIELDMaskedAsIDENT(currentScope()->isGenerator()))
     3240        return parseYieldExpression(context);
     3241
    32263242    JSTextPosition start = tokenStartPosition();
    32273243    JSTokenLocation location(tokenLocation());
     
    32303246    bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
    32313247    bool wasOpenParen = match(OPENPAREN);
    3232     bool isValidArrowFunctionStart = match(OPENPAREN) || matchSpecIdentifier();
     3248    // Do not use matchSpecIdentifier() here since it is slower than isIdentifierOrKeyword.
     3249    // Whether spec identifier is will be validated by isArrowFunctionParameters().
     3250    bool wasIdentifierOrKeyword = isIdentifierOrKeyword(m_token);
     3251    bool maybeValidArrowFunctionStart = wasOpenParen || wasIdentifierOrKeyword;
    32333252    SavePoint savePoint = createSavePoint();
    32343253    size_t usedVariablesSize = 0;
    3235     if (wasOpenParen || UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
     3254
     3255    // FIXME: This branch contributes to a 1% octane code-load regression.
     3256    // https://bugs.webkit.org/show_bug.cgi?id=158211
     3257    if (wasOpenParen || (wasIdentifierOrKeyword && m_runtimeFlags.isAsyncAwaitEnabled() && UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async))) {
    32363258        usedVariablesSize = currentScope()->currentUsedVariablesSize();
    32373259        currentScope()->pushUsedVariableSet();
    32383260    }
    32393261
    3240     if (match(YIELD) && !isYIELDMaskedAsIDENT(currentScope()->isGenerator()))
    3241         return parseYieldExpression(context);
    3242 
    32433262    TreeExpression lhs = parseConditionalExpression(context);
    32443263
    3245     if (isValidArrowFunctionStart && !match(EOFTOK)) {
     3264    if (maybeValidArrowFunctionStart && !match(EOFTOK)) {
    32463265        bool isArrowFunctionToken = match(ARROWFUNCTION);
    32473266        if (!lhs || isArrowFunctionToken) {
     
    34843503    bool isClassProperty = false;
    34853504    bool isAsyncMethod = false;
    3486 
    34873505    if (consume(TIMES))
    34883506        isGenerator = true;
     
    34913509    switch (m_token.m_type) {
    34923510    namedProperty:
     3511    case IDENT:
    34933512    case AWAIT:
    3494     case IDENT:
    34953513        wasIdent = true;
    34963514        FALLTHROUGH;
     
    35433561            failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");
    35443562            goto parseProperty;
    3545         }
    3546         else
     3563        } else
    35473564            failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
    35483565        return parseGetterSetter(context, complete, type, getterOrSetterStartOffset, ConstructorKind::None, isClassProperty);
     
    39663983        JSTokenLocation location(tokenLocation());
    39673984        next();
    3968         if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(FUNCTION) && !m_lexer->prevTerminator() && *ident == m_vm->propertyNames->async))
    3969             return parseAsyncFunctionExpression(context);
     3985        // FIXME: This branch contributes to a 1% octane code-load regression.
     3986        // https://bugs.webkit.org/show_bug.cgi?id=158211
     3987        if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator() && *ident == m_vm->propertyNames->async)) {
     3988            if (m_runtimeFlags.isAsyncAwaitEnabled())
     3989                return parseAsyncFunctionExpression(context);
     3990        }
    39703991        currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
    39713992        m_parserState.lastIdentifier = ident;
     
    41624183        }
    41634184    } else if (!baseIsNewTarget) {
    4164         currentFunctionScope()->setNeedsSuperBinding();
     4185        // FIXME: This branch contributes to a 1% octane code-load regression.
     4186        // https://bugs.webkit.org/show_bug.cgi?id=158211
    41654187        const bool isAsync = matchContextualKeyword(m_vm->propertyNames->async);
    41664188        base = parsePrimaryExpression(context);
     
    42574279            break;
    42584280        }
    4259 
    42604281        default:
    42614282            goto endMemberExpression;
     
    43264347    unsigned lastOperator = 0;
    43274348
    4328     if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(AWAIT) && currentFunctionScope()->isAsyncFunction()))
    4329         return parseAwaitExpression(context);
     4349    // FIXME: This branch contributes to a 1% octane code-load regression.
     4350    // https://bugs.webkit.org/show_bug.cgi?id=158211
     4351    if (UNLIKELY(match(AWAIT))) {
     4352        if (m_runtimeFlags.isAsyncAwaitEnabled() && currentFunctionScope()->isAsyncFunction())
     4353            return parseAwaitExpression(context);
     4354    }
    43304355
    43314356    while (isUnaryOp(m_token.m_type)) {
     
    45104535        return;
    45114536
    4512     case AWAIT:
    45134537    case IDENT:
    45144538        out.print("Unexpected identifier '", getToken(), "'");
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r201481 r201523  
    127127ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
    128128{
    129     return token.m_type == IDENT || token.m_type == AWAIT || token.m_type & KeywordTokenFlag;
     129    return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
    130130}
    131131
     
    10731073    ALWAYS_INLINE bool isEvalOrArguments(const Identifier* ident) { return isEvalOrArgumentsIdentifier(m_vm, ident); }
    10741074
     1075    ScopeRef upperScope(unsigned n)
     1076    {
     1077        ASSERT(m_scopeStack.size() >= (1 + n));
     1078        return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1 - n);
     1079    }
     1080
    10751081    ScopeRef currentScope()
    10761082    {
     
    14461452    ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
    14471453    {
    1448         return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || match(AWAIT);
    1449     }
    1450 
     1454        return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator);
     1455    }
     1456
     1457    // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
    14511458    ALWAYS_INLINE bool matchSpecIdentifier()
    14521459    {
    1453         return matchSpecIdentifier(currentScope()->isGenerator());
     1460        return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator());
    14541461    }
    14551462
     
    15681575    bool isDisallowedIdentifierAwait(const JSToken& token)
    15691576    {
    1570         return token.m_type == AWAIT && (currentScope()->isAsyncFunctionBoundary() || currentScope()->isModule() || !m_parserState.allowAwait);
     1577        return token.m_type == AWAIT && (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary() || currentScope()->isModule());
    15711578    }
    15721579
  • trunk/Source/JavaScriptCore/parser/ParserModes.h

    r201481 r201523  
    4444enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
    4545
    46 enum class SourceParseMode : uint8_t {
    47     NormalFunctionMode,
    48     GeneratorBodyMode,
    49     GeneratorWrapperFunctionMode,
    50     GetterMode,
    51     SetterMode,
    52     MethodMode,
    53     ArrowFunctionMode,
    54     AsyncFunctionBodyMode,
    55     AsyncArrowFunctionBodyMode,
    56     AsyncFunctionMode,
    57     AsyncMethodMode,
    58     AsyncArrowFunctionMode,
    59     ProgramMode,
    60     ModuleAnalyzeMode,
    61     ModuleEvaluateMode
     46// When you add a new source parse mode, do not forget to ensure that the predicates defined in this
     47// file work with the newly added mode.
     48enum class SourceParseMode : uint16_t {
     49    NormalFunctionMode            = 0b0000000000000001,
     50    GeneratorBodyMode             = 0b0000000000000010,
     51    GeneratorWrapperFunctionMode  = 0b0000000000000100,
     52    GetterMode                    = 0b0000000000001000,
     53    SetterMode                    = 0b0000000000010000,
     54    MethodMode                    = 0b0000000000100000,
     55    ArrowFunctionMode             = 0b0000000001000000,
     56    AsyncFunctionBodyMode         = 0b0000000010000000,
     57    AsyncArrowFunctionBodyMode    = 0b0000000100000000,
     58    AsyncFunctionMode             = 0b0000001000000000,
     59    AsyncMethodMode               = 0b0000010000000000,
     60    AsyncArrowFunctionMode        = 0b0000100000000000,
     61    ProgramMode                   = 0b0001000000000000,
     62    ModuleAnalyzeMode             = 0b0010000000000000,
     63    ModuleEvaluateMode            = 0b0100000000000000,
    6264};
    6365
    64 inline bool isFunctionParseMode(SourceParseMode parseMode)
    65 {
    66     switch (parseMode) {
    67     case SourceParseMode::NormalFunctionMode:
    68     case SourceParseMode::GeneratorBodyMode:
    69     case SourceParseMode::GeneratorWrapperFunctionMode:
    70     case SourceParseMode::GetterMode:
    71     case SourceParseMode::SetterMode:
    72     case SourceParseMode::MethodMode:
    73     case SourceParseMode::ArrowFunctionMode:
    74     case SourceParseMode::AsyncFunctionBodyMode:
    75     case SourceParseMode::AsyncFunctionMode:
    76     case SourceParseMode::AsyncMethodMode:
    77     case SourceParseMode::AsyncArrowFunctionMode:
    78     case SourceParseMode::AsyncArrowFunctionBodyMode:
    79         return true;
    80 
    81     case SourceParseMode::ProgramMode:
    82     case SourceParseMode::ModuleAnalyzeMode:
    83     case SourceParseMode::ModuleEvaluateMode:
    84         return false;
    85     }
    86     RELEASE_ASSERT_NOT_REACHED();
    87     return false;
    88 }
    89 
    90 inline bool isAsyncFunctionParseMode(SourceParseMode parseMode)
    91 {
    92     switch (parseMode) {
    93     case SourceParseMode::AsyncFunctionBodyMode:
    94     case SourceParseMode::AsyncArrowFunctionBodyMode:
    95     case SourceParseMode::AsyncFunctionMode:
    96     case SourceParseMode::AsyncMethodMode:
    97     case SourceParseMode::AsyncArrowFunctionMode:
    98         return true;
    99 
    100     case SourceParseMode::NormalFunctionMode:
    101     case SourceParseMode::GeneratorBodyMode:
    102     case SourceParseMode::GeneratorWrapperFunctionMode:
    103     case SourceParseMode::GetterMode:
    104     case SourceParseMode::SetterMode:
    105     case SourceParseMode::MethodMode:
    106     case SourceParseMode::ArrowFunctionMode:
    107     case SourceParseMode::ModuleAnalyzeMode:
    108     case SourceParseMode::ModuleEvaluateMode:
    109     case SourceParseMode::ProgramMode:
    110         return false;
    111     }
    112     RELEASE_ASSERT_NOT_REACHED();
    113     return false;
    114 }
    115 
    116 inline bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
    117 {
    118     switch (parseMode) {
    119     case SourceParseMode::AsyncArrowFunctionMode:
    120     case SourceParseMode::AsyncArrowFunctionBodyMode:
    121         return true;
    122 
    123     case SourceParseMode::NormalFunctionMode:
    124     case SourceParseMode::GeneratorBodyMode:
    125     case SourceParseMode::GeneratorWrapperFunctionMode:
    126     case SourceParseMode::GetterMode:
    127     case SourceParseMode::SetterMode:
    128     case SourceParseMode::MethodMode:
    129     case SourceParseMode::ArrowFunctionMode:
    130     case SourceParseMode::ModuleAnalyzeMode:
    131     case SourceParseMode::ModuleEvaluateMode:
    132     case SourceParseMode::AsyncFunctionBodyMode:
    133     case SourceParseMode::AsyncMethodMode:
    134     case SourceParseMode::AsyncFunctionMode:
    135     case SourceParseMode::ProgramMode:
    136         return false;
    137     }
    138 
    139     RELEASE_ASSERT_NOT_REACHED();
    140     return false;
    141 }
    142 
    143 inline bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
    144 {
    145     switch (parseMode) {
    146     case SourceParseMode::AsyncFunctionMode:
    147     case SourceParseMode::AsyncMethodMode:
    148     case SourceParseMode::AsyncArrowFunctionMode:
    149         return true;
    150 
    151     case SourceParseMode::AsyncFunctionBodyMode:
    152     case SourceParseMode::AsyncArrowFunctionBodyMode:
    153     case SourceParseMode::NormalFunctionMode:
    154     case SourceParseMode::GeneratorBodyMode:
    155     case SourceParseMode::GeneratorWrapperFunctionMode:
    156     case SourceParseMode::GetterMode:
    157     case SourceParseMode::SetterMode:
    158     case SourceParseMode::MethodMode:
    159     case SourceParseMode::ArrowFunctionMode:
    160     case SourceParseMode::ModuleAnalyzeMode:
    161     case SourceParseMode::ModuleEvaluateMode:
    162     case SourceParseMode::ProgramMode:
    163         return false;
    164     }
    165     RELEASE_ASSERT_NOT_REACHED();
    166     return false;
    167 }
    168 
    169 inline bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
    170 {
    171     switch (parseMode) {
    172     case SourceParseMode::AsyncFunctionBodyMode:
    173     case SourceParseMode::AsyncArrowFunctionBodyMode:
    174         return true;
    175 
    176     case SourceParseMode::NormalFunctionMode:
    177     case SourceParseMode::GeneratorBodyMode:
    178     case SourceParseMode::GeneratorWrapperFunctionMode:
    179     case SourceParseMode::GetterMode:
    180     case SourceParseMode::SetterMode:
    181     case SourceParseMode::MethodMode:
    182     case SourceParseMode::ArrowFunctionMode:
    183     case SourceParseMode::AsyncFunctionMode:
    184     case SourceParseMode::AsyncMethodMode:
    185     case SourceParseMode::AsyncArrowFunctionMode:
    186     case SourceParseMode::ModuleAnalyzeMode:
    187     case SourceParseMode::ModuleEvaluateMode:
    188     case SourceParseMode::ProgramMode:
    189         return false;
    190     }
    191     RELEASE_ASSERT_NOT_REACHED();
    192     return false;
    193 }
    194 
    195 inline bool isModuleParseMode(SourceParseMode parseMode)
    196 {
    197     switch (parseMode) {
    198     case SourceParseMode::ModuleAnalyzeMode:
    199     case SourceParseMode::ModuleEvaluateMode:
    200         return true;
    201 
    202     case SourceParseMode::NormalFunctionMode:
    203     case SourceParseMode::GeneratorBodyMode:
    204     case SourceParseMode::GeneratorWrapperFunctionMode:
    205     case SourceParseMode::GetterMode:
    206     case SourceParseMode::SetterMode:
    207     case SourceParseMode::MethodMode:
    208     case SourceParseMode::ArrowFunctionMode:
    209     case SourceParseMode::AsyncFunctionBodyMode:
    210     case SourceParseMode::AsyncFunctionMode:
    211     case SourceParseMode::AsyncMethodMode:
    212     case SourceParseMode::AsyncArrowFunctionMode:
    213     case SourceParseMode::AsyncArrowFunctionBodyMode:
    214     case SourceParseMode::ProgramMode:
    215         return false;
    216     }
    217     RELEASE_ASSERT_NOT_REACHED();
    218     return false;
    219 }
    220 
    221 inline bool isProgramParseMode(SourceParseMode parseMode)
    222 {
    223     switch (parseMode) {
    224     case SourceParseMode::ProgramMode:
    225         return true;
    226 
    227     case SourceParseMode::NormalFunctionMode:
    228     case SourceParseMode::GeneratorBodyMode:
    229     case SourceParseMode::GeneratorWrapperFunctionMode:
    230     case SourceParseMode::GetterMode:
    231     case SourceParseMode::SetterMode:
    232     case SourceParseMode::MethodMode:
    233     case SourceParseMode::ArrowFunctionMode:
    234     case SourceParseMode::AsyncFunctionBodyMode:
    235     case SourceParseMode::AsyncFunctionMode:
    236     case SourceParseMode::AsyncMethodMode:
    237     case SourceParseMode::AsyncArrowFunctionMode:
    238     case SourceParseMode::AsyncArrowFunctionBodyMode:
    239     case SourceParseMode::ModuleAnalyzeMode:
    240     case SourceParseMode::ModuleEvaluateMode:
    241         return false;
    242     }
    243     RELEASE_ASSERT_NOT_REACHED();
    244     return false;
    245 }
    246 
    247 inline ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
    248 {
    249     switch (parseMode) {
    250     case SourceParseMode::NormalFunctionMode:
     66class SourceParseModeSet {
     67public:
     68    template<typename... Modes>
     69    SourceParseModeSet(Modes... args)
     70        : m_mask(mergeSourceParseModes(args...))
     71    {
     72    }
     73
     74    ALWAYS_INLINE bool contains(SourceParseMode mode)
     75    {
     76        return static_cast<unsigned>(mode) & m_mask;
     77    }
     78
     79private:
     80    ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode)
     81    {
     82        return static_cast<unsigned>(mode);
     83    }
     84
     85    template<typename... Rest>
     86    ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode, Rest... rest)
     87    {
     88        return static_cast<unsigned>(mode) | mergeSourceParseModes(rest...);
     89    }
     90
     91    const unsigned m_mask;
     92};
     93
     94ALWAYS_INLINE bool isFunctionParseMode(SourceParseMode parseMode)
     95{
     96    return SourceParseModeSet(
     97        SourceParseMode::NormalFunctionMode,
     98        SourceParseMode::GeneratorBodyMode,
     99        SourceParseMode::GeneratorWrapperFunctionMode,
     100        SourceParseMode::GetterMode,
     101        SourceParseMode::SetterMode,
     102        SourceParseMode::MethodMode,
     103        SourceParseMode::ArrowFunctionMode,
     104        SourceParseMode::AsyncFunctionBodyMode,
     105        SourceParseMode::AsyncFunctionMode,
     106        SourceParseMode::AsyncMethodMode,
     107        SourceParseMode::AsyncArrowFunctionMode,
     108        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
     109}
     110
     111ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode)
     112{
     113    return SourceParseModeSet(
     114        SourceParseMode::AsyncFunctionBodyMode,
     115        SourceParseMode::AsyncFunctionMode,
     116        SourceParseMode::AsyncMethodMode,
     117        SourceParseMode::AsyncArrowFunctionMode,
     118        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
     119}
     120
     121ALWAYS_INLINE bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
     122{
     123    return SourceParseModeSet(
     124        SourceParseMode::AsyncArrowFunctionMode,
     125        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
     126}
     127
     128ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
     129{
     130    return SourceParseModeSet(
     131        SourceParseMode::AsyncArrowFunctionMode,
     132        SourceParseMode::AsyncFunctionMode,
     133        SourceParseMode::AsyncMethodMode).contains(parseMode);
     134}
     135
     136ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
     137{
     138    return SourceParseModeSet(
     139        SourceParseMode::AsyncFunctionBodyMode,
     140        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
     141}
     142
     143ALWAYS_INLINE bool isModuleParseMode(SourceParseMode parseMode)
     144{
     145    return SourceParseModeSet(
     146        SourceParseMode::ModuleAnalyzeMode,
     147        SourceParseMode::ModuleEvaluateMode).contains(parseMode);
     148}
     149
     150ALWAYS_INLINE bool isProgramParseMode(SourceParseMode parseMode)
     151{
     152    return SourceParseModeSet(SourceParseMode::ProgramMode).contains(parseMode);
     153}
     154
     155ALWAYS_INLINE ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
     156{
     157    if (parseMode == SourceParseMode::NormalFunctionMode)
    251158        return ConstructAbility::CanConstruct;
    252 
    253     case SourceParseMode::GeneratorBodyMode:
    254     case SourceParseMode::GeneratorWrapperFunctionMode:
    255     case SourceParseMode::GetterMode:
    256     case SourceParseMode::SetterMode:
    257     case SourceParseMode::MethodMode:
    258     case SourceParseMode::ArrowFunctionMode:
    259     case SourceParseMode::AsyncFunctionBodyMode:
    260     case SourceParseMode::AsyncArrowFunctionBodyMode:
    261     case SourceParseMode::AsyncFunctionMode:
    262     case SourceParseMode::AsyncMethodMode:
    263     case SourceParseMode::AsyncArrowFunctionMode:
    264         return ConstructAbility::CannotConstruct;
    265 
    266     case SourceParseMode::ProgramMode:
    267     case SourceParseMode::ModuleAnalyzeMode:
    268     case SourceParseMode::ModuleEvaluateMode:
    269         break;
    270     }
    271     RELEASE_ASSERT_NOT_REACHED();
    272     return ConstructAbility::CanConstruct;
     159    return ConstructAbility::CannotConstruct;
    273160}
    274161
  • trunk/Source/JavaScriptCore/parser/ParserTokens.h

    r201481 r201523  
    8383    EXTENDS,
    8484    SUPER,
     85    AWAIT,
    8586    OPENBRACE = 0,
    8687    CLOSEBRACE,
     
    114115    DOTDOTDOT,
    115116    ARROWFUNCTION,
    116     // Untagged conditional keywords
    117     AWAIT,
    118117    LastUntaggedToken,
    119118
Note: See TracChangeset for help on using the changeset viewer.