Changeset 220323 in webkit


Ignore:
Timestamp:
Aug 6, 2017 6:04:32 AM (7 years ago)
Author:
gskachkov@gmail.com
Message:

[Next] Async iteration - Implement Async Generator - parser
https://bugs.webkit.org/show_bug.cgi?id=175210

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/async-await-syntax.js:

(testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntax):

  • stress/async-iteration-syntax.js: Added.

(assert):
(checkSyntax):
(checkSyntaxError):
(checkSimpleAsyncGeneratorSloppyMode):
(checkSimpleAsyncGeneratorStrictMode):
(checkNestedAsyncGenerators):
(checkSimpleAsyncGeneratorSyntaxErrorInStrictMode):

  • stress/generator-class-methods-syntax.js:

Source/JavaScriptCore:

Current implementation is draft version of Async Iteration.
Link to spec https://tc39.github.io/proposal-async-iteration/

Current patch implement only parser part of the Async generator
Runtime part will be in next ptches

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createFunctionMetadata):

  • parser/Parser.cpp:

(JSC::getAsynFunctionBodyParseMode):
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
(JSC::Parser<LexerType>::parseAsyncGeneratorFunctionSourceElements):
(JSC::stringArticleForFunctionMode):
(JSC::stringForFunctionMode):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parsePropertyMethod):
(JSC::Parser<LexerType>::parseAsyncFunctionExpression):

  • parser/Parser.h:

(JSC::Scope::setSourceParseMode):

  • parser/ParserModes.h:

(JSC::isFunctionParseMode):
(JSC::isAsyncFunctionParseMode):
(JSC::isAsyncArrowFunctionParseMode):
(JSC::isAsyncGeneratorFunctionParseMode):
(JSC::isAsyncFunctionOrAsyncGeneratorWrapperParseMode):
(JSC::isAsyncFunctionWrapperParseMode):
(JSC::isAsyncFunctionBodyParseMode):
(JSC::isGeneratorMethodParseMode):
(JSC::isAsyncMethodParseMode):
(JSC::isAsyncGeneratorMethodParseMode):
(JSC::isMethodParseMode):
(JSC::isGeneratorOrAsyncFunctionBodyParseMode):
(JSC::isGeneratorOrAsyncFunctionWrapperParseMode):

Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r220265 r220323  
     12017-08-06  Oleksandr Skachkov  <gskachkov@gmail.com>
     2
     3        [ESNext] Async iteration - Implement Async Generator - parser
     4        https://bugs.webkit.org/show_bug.cgi?id=175210
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * stress/async-await-syntax.js:
     9        (testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntax):
     10        * stress/async-iteration-syntax.js: Added.
     11        (assert):
     12        (checkSyntax):
     13        (checkSyntaxError):
     14        (checkSimpleAsyncGeneratorSloppyMode):
     15        (checkSimpleAsyncGeneratorStrictMode):
     16        (checkNestedAsyncGenerators):
     17        (checkSimpleAsyncGeneratorSyntaxErrorInStrictMode):
     18        * stress/generator-class-methods-syntax.js:
     19
    1202017-08-03  Carlos Alberto Lopez Perez  <clopez@igalia.com>
    221
  • trunk/JSTests/stress/async-await-syntax.js

    r217629 r220323  
    3333
    3434(function testTopLevelAsyncAwaitSyntaxSloppyMode() {
     35    testSyntax(`({async: 1})`);
    3536    testSyntax(`var asyncFn = async function() { await 1; };`);
    3637    testSyntax(`var asyncFn = async function withName() { await 1; };`);
    3738    testSyntax(`var asyncFn = async () => await 'test';`);
    3839    testSyntax(`var asyncFn = async x => await x + 'test';`);
     40    testSyntax(`function foo(fn) { fn({ async: true }); }`);
    3941    testSyntax(`async function asyncFn() { await 1; }`);
    4042    testSyntax(`var O = { async method() { await 1; } };`);
     
    6668
    6769(function testTopLevelAsyncAwaitSyntaxStrictMode() {
     70    testSyntax(`"use strict"; ({async: 1})`);
    6871    testSyntax(`"use strict"; var asyncFn = async function() { await 1; };`);
    6972    testSyntax(`"use strict"; var asyncFn = async function withName() { await 1; };`);
    7073    testSyntax(`"use strict"; var asyncFn = async () => await 'test';`);
    7174    testSyntax(`"use strict"; var asyncFn = async x => await x + 'test';`);
     75    testSyntax(`"use strict"; function foo(fn) { fn({ async: true }); }`);
    7276    testSyntax(`"use strict"; async function asyncFn() { await 1; }`);
    7377    testSyntax(`"use strict"; var O = { async method() { await 1; } };`);
     
    156160
    157161(function testTopLevelAsyncAwaitSyntaxSloppyMode() {
     162    testSyntaxError(`({ async
     163        foo() {} })`);
     164    testSyntaxError(`({async =  1})`);
    158165    testSyntaxError(`var asyncFn = async function await() {}`);
    159166    testSyntaxError(`var asyncFn = async () => var await = 'test';`);
     
    187194    testSyntaxError(`var asyncArrowFn = async() => await;`);
    188195
    189     testSyntaxError(`var asyncFn = async function*() {}`);
    190     testSyntaxError(`async function* asyncGenerator() {}`);
     196    testSyntax(`var asyncFn = async function*() {}`);
     197    testSyntax(`async function* asyncGenerator() {}`);
    191198    testSyntaxError(`var O = { *async asyncGeneratorMethod() {} };`);
    192     testSyntaxError(`var O = { async *asyncGeneratorMethod() {} };`);
     199    testSyntax(`var O = { async *asyncGeneratorMethod() {} };`);
    193200    testSyntaxError(`var O = { async asyncGeneratorMethod*() {} };`);
    194201
     
    242249
    243250(function testTopLevelAsyncAwaitSyntaxStrictMode() {
     251    testSyntaxError(`"use strict"; ({ async
     252        foo() {} })`);
     253    testSyntaxError(`"use strict"; ({async =  1})`);
    244254    testSyntaxError(`"use strict"; var asyncFn = async function await() {}`);
    245255    testSyntaxError(`"use strict"; var asyncFn = async () => var await = 'test';`);
     
    258268    testSyntaxError(`"use strict"; var asyncArrowFn = async() => await;`);
    259269
    260     testSyntaxError(`"use strict"; var asyncFn = async function*() {}`);
    261     testSyntaxError(`"use strict"; async function* asyncGenerator() {}`);
    262270    testSyntaxError(`"use strict"; var O = { *async asyncGeneratorMethod() {} };`);
    263     testSyntaxError(`"use strict"; var O = { async *asyncGeneratorMethod() {} };`);
    264271    testSyntaxError(`"use strict"; var O = { async asyncGeneratorMethod*() {} };`);
    265272
  • trunk/JSTests/stress/generator-class-methods-syntax.js

    r192937 r220323  
    2828    }
    2929}
    30 `, `SyntaxError: Cannot declare a generator named 'constructor'.`);
     30`, `SyntaxError: Cannot declare a generator function named 'constructor'.`);
    3131
    3232testSyntax(`
  • trunk/Source/JavaScriptCore/ChangeLog

    r220322 r220323  
     12017-08-06  Oleksandr Skachkov  <gskachkov@gmail.com>
     2
     3        [ESNext] Async iteration - Implement Async Generator - parser
     4        https://bugs.webkit.org/show_bug.cgi?id=175210
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Current implementation is draft version of Async Iteration.
     9        Link to spec https://tc39.github.io/proposal-async-iteration/
     10
     11        Current patch implement only parser part of the Async generator
     12        Runtime part will be in next ptches
     13
     14        * parser/ASTBuilder.h:
     15        (JSC::ASTBuilder::createFunctionMetadata):
     16        * parser/Parser.cpp:
     17        (JSC::getAsynFunctionBodyParseMode):
     18        (JSC::Parser<LexerType>::parseInner):
     19        (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
     20        (JSC::Parser<LexerType>::parseAsyncGeneratorFunctionSourceElements):
     21        (JSC::stringArticleForFunctionMode):
     22        (JSC::stringForFunctionMode):
     23        (JSC::Parser<LexerType>::parseFunctionInfo):
     24        (JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
     25        (JSC::Parser<LexerType>::parseClass):
     26        (JSC::Parser<LexerType>::parseProperty):
     27        (JSC::Parser<LexerType>::parsePropertyMethod):
     28        (JSC::Parser<LexerType>::parseAsyncFunctionExpression):
     29        * parser/Parser.h:
     30        (JSC::Scope::setSourceParseMode):
     31        * parser/ParserModes.h:
     32        (JSC::isFunctionParseMode):
     33        (JSC::isAsyncFunctionParseMode):
     34        (JSC::isAsyncArrowFunctionParseMode):
     35        (JSC::isAsyncGeneratorFunctionParseMode):
     36        (JSC::isAsyncFunctionOrAsyncGeneratorWrapperParseMode):
     37        (JSC::isAsyncFunctionWrapperParseMode):
     38        (JSC::isAsyncFunctionBodyParseMode):
     39        (JSC::isGeneratorMethodParseMode):
     40        (JSC::isAsyncMethodParseMode):
     41        (JSC::isAsyncGeneratorMethodParseMode):
     42        (JSC::isMethodParseMode):
     43        (JSC::isGeneratorOrAsyncFunctionBodyParseMode):
     44        (JSC::isGeneratorOrAsyncFunctionWrapperParseMode):
     45
    1462017-08-05  Filip Pizlo  <fpizlo@apple.com>
    247
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r219702 r220323  
    438438        SourceParseMode mode, bool isArrowFunctionBodyExpression)
    439439    {
     440        SourceParseMode bodySourceParseMode = mode;
     441        if (mode == SourceParseMode::AsyncGeneratorBodyMode) {
     442            ASSERT(Options::useAsyncIterator());
     443            bodySourceParseMode = SourceParseMode::AsyncFunctionBodyMode;
     444        } else if (mode == SourceParseMode::AsyncGeneratorWrapperFunctionMode) {
     445            ASSERT(Options::useAsyncIterator());
     446            bodySourceParseMode = SourceParseMode::ArrowFunctionMode;
     447        } else if (mode == SourceParseMode::AsyncGeneratorWrapperMethodMode) {
     448            ASSERT(Options::useAsyncIterator());
     449            bodySourceParseMode = SourceParseMode::AsyncMethodMode;
     450        }
     451
    440452        return new (m_parserArena) FunctionMetadataNode(
    441453            m_parserArena, startLocation, endLocation, startColumn, endColumn,
    442454            functionKeywordStart, functionNameStart, parametersStart,
    443455            inStrictContext, constructorKind, superBinding,
    444             parameterCount, mode, isArrowFunctionBodyExpression);
     456            parameterCount, bodySourceParseMode, isArrowFunctionBodyExpression);
    445457    }
    446458
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r220068 r220323  
    9191namespace JSC {
    9292
     93ALWAYS_INLINE static SourceParseMode getAsynFunctionBodyParseMode(SourceParseMode parseMode)
     94{
     95    if (isAsyncGeneratorFunctionParseMode(parseMode))
     96        return SourceParseMode::AsyncGeneratorBodyMode;
     97
     98    if (parseMode == SourceParseMode::AsyncArrowFunctionMode)
     99        return SourceParseMode::AsyncArrowFunctionBodyMode;
     100
     101    return SourceParseMode::AsyncFunctionBodyMode;
     102}
     103
    93104template <typename LexerType>
    94105void Parser<LexerType>::logError(bool)
     
    229240        else if (isGeneratorWrapperParseMode(parseMode))
    230241            sourceElements = parseGeneratorFunctionSourceElements(context, calleeName, CheckForStrictMode);
     242        else if (isAsyncGeneratorFunctionParseMode(parseMode))
     243            sourceElements = parseAsyncGeneratorFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode);
    231244        else
    232245            sourceElements = parseSourceElements(context, CheckForStrictMode);
     
    250263        varDeclarations.markVariableAsCaptured(entry);
    251264
    252     if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunctionWrapperParseMode(parseMode)) {
     265    if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(parseMode)) {
    253266        if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
    254267            context.propagateArgumentsUse();
     
    503516template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode)
    504517{
    505     ASSERT(isAsyncFunctionWrapperParseMode(parseMode));
     518    ASSERT(isAsyncFunctionOrAsyncGeneratorWrapperParseMode(parseMode));
    506519    auto sourceElements = context.createSourceElements();
    507520
     
    518531    info.startOffset = parametersStart;
    519532    info.startLine = tokenLine();
    520     SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode
    521         ? SourceParseMode::AsyncArrowFunctionBodyMode
    522         : SourceParseMode::AsyncFunctionBodyMode;
     533
     534    SourceParseMode innerParseMode = getAsynFunctionBodyParseMode(parseMode);
     535
    523536    {
    524537        AutoPopScopeRef asyncFunctionBodyScope(this, pushScope());
     
    551564}
    552565
     566template <typename LexerType>
     567template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncGeneratorFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode)
     568{
     569    ASSERT_UNUSED(parseMode, isAsyncGeneratorFunctionParseMode(parseMode));
     570    auto sourceElements = context.createSourceElements();
     571       
     572    unsigned functionKeywordStart = tokenStart();
     573    JSTokenLocation startLocation(tokenLocation());
     574    JSTextPosition start = tokenStartPosition();
     575    unsigned startColumn = tokenColumn();
     576    int functionNameStart = m_token.m_location.startOffset;
     577    int parametersStart = m_token.m_location.startOffset;
     578   
     579    ParserFunctionInfo<TreeBuilder> info;
     580    info.name = &m_vm->propertyNames->nullIdentifier;
     581    createGeneratorParameters(context, info.parameterCount);
     582    info.startOffset = parametersStart;
     583    info.startLine = tokenLine();
     584    SourceParseMode innerParseMode = SourceParseMode::AsyncGeneratorBodyMode;
     585    {
     586        AutoPopScopeRef asyncFunctionBodyScope(this, pushScope());
     587        asyncFunctionBodyScope->setSourceParseMode(innerParseMode);
     588        SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
     589        if (isArrowFunctionBodyExpression) {
     590            if (m_debuggerParseData)
     591                failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(context), "Cannot parse the body of async arrow function");
     592            else
     593                failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(syntaxChecker), "Cannot parse the body of async arrow function");
     594        } else {
     595            if (m_debuggerParseData)
     596                failIfFalse(parseSourceElements(context, mode), "Cannot parse the body of async function");
     597            else
     598                failIfFalse(parseSourceElements(syntaxChecker, mode), "Cannot parse the body of async function");
     599        }
     600        popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo);
     601    }
     602    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression);
     603
     604    info.endLine = tokenLine();
     605    info.endOffset = isArrowFunctionBodyExpression ? tokenLocation().endOffset : m_token.m_data.offset;
     606    info.parametersStartColumn = startColumn;
     607
     608    auto functionExpr = context.createAsyncFunctionBody(startLocation, info, innerParseMode);
     609    auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
     610    context.appendStatement(sourceElements, statement);
     611       
     612    return sourceElements;
     613}
     614   
    553615template <typename LexerType>
    554616template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
     
    20072069}
    20082070
     2071static const char* stringArticleForFunctionMode(SourceParseMode mode)
     2072{
     2073    switch (mode) {
     2074    case SourceParseMode::GetterMode:
     2075    case SourceParseMode::SetterMode:
     2076    case SourceParseMode::NormalFunctionMode:
     2077    case SourceParseMode::MethodMode:
     2078    case SourceParseMode::GeneratorBodyMode:
     2079    case SourceParseMode::GeneratorWrapperFunctionMode:
     2080    case SourceParseMode::GeneratorWrapperMethodMode:
     2081        return "a ";
     2082    case SourceParseMode::ArrowFunctionMode:
     2083    case SourceParseMode::AsyncFunctionMode:
     2084    case SourceParseMode::AsyncFunctionBodyMode:
     2085    case SourceParseMode::AsyncMethodMode:
     2086    case SourceParseMode::AsyncArrowFunctionBodyMode:
     2087    case SourceParseMode::AsyncArrowFunctionMode:
     2088    case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
     2089    case SourceParseMode::AsyncGeneratorBodyMode:
     2090    case SourceParseMode::AsyncGeneratorWrapperMethodMode:
     2091        return "an ";
     2092    case SourceParseMode::ProgramMode:
     2093    case SourceParseMode::ModuleAnalyzeMode:
     2094    case SourceParseMode::ModuleEvaluateMode:
     2095        RELEASE_ASSERT_NOT_REACHED();
     2096        return "";
     2097    }
     2098    RELEASE_ASSERT_NOT_REACHED();
     2099    return nullptr;
     2100}
     2101   
    20092102static const char* stringForFunctionMode(SourceParseMode mode)
    20102103{
     
    20332126    case SourceParseMode::AsyncArrowFunctionMode:
    20342127        return "async arrow function";
     2128    case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
     2129    case SourceParseMode::AsyncGeneratorBodyMode:
     2130        return "async generator function";
     2131    case SourceParseMode::AsyncGeneratorWrapperMethodMode:
     2132        return "async generator method";
    20352133    case SourceParseMode::ProgramMode:
    20362134    case SourceParseMode::ModuleAnalyzeMode:
     
    23042402                m_parserState.lastFunctionName = functionInfo.name;
    23052403                if (UNLIKELY(isDisallowedAwaitFunctionName))
    2306                     semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
    2307                 else if (isAsyncFunctionWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
    2308                     semanticFail("Cannot declare async function named 'await'");
     2404                    semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
     2405                else if (isAsyncFunctionOrAsyncGeneratorWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
     2406                    semanticFail("Cannot declare ", stringForFunctionMode(mode), " named 'await'");
    23092407                else if (isGeneratorWrapperParseMode(mode) && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression)
    23102408                    semanticFail("Cannot declare generator function named 'yield'");
     
    23882486        AutoPopScopeRef generatorBodyScope(this, pushScope());
    23892487        SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
    2390         if (isAsyncFunctionWrapperParseMode(mode)) {
    2391             innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode
    2392                 ? SourceParseMode::AsyncArrowFunctionBodyMode
    2393                 : SourceParseMode::AsyncFunctionBodyMode;
    2394         }
     2488        if (isAsyncFunctionOrAsyncGeneratorWrapperParseMode(mode))
     2489            innerParseMode = getAsynFunctionBodyParseMode(mode);
     2490
    23952491        generatorBodyScope->setSourceParseMode(innerParseMode);
    23962492        generatorBodyScope->setConstructorKind(ConstructorKind::None);
     
    24172513    if (functionScope->strictMode() && requirements != FunctionNameRequirements::Unnamed) {
    24182514        ASSERT(functionInfo.name);
    2419         RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunctionWrapperParseMode(mode));
     2515        RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(mode));
    24202516        semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
    24212517        semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
     
    25432639    ParserFunctionInfo<TreeBuilder> functionInfo;
    25442640    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
     2641    if (Options::useAsyncIterator() && consume(TIMES))
     2642        parseMode = SourceParseMode::AsyncGeneratorWrapperFunctionMode;
     2643
    25452644    FunctionNameRequirements requirements = FunctionNameRequirements::Named;
    25462645    if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) {
     
    27042803        bool isGetter = false;
    27052804        bool isSetter = false;
    2706         bool isGenerator = false;
    2707         bool isAsync = false;
    2708         bool isAsyncMethod = false;
     2805        SourceParseMode parseMode = SourceParseMode::MethodMode;
    27092806        if (consume(TIMES))
    2710             isGenerator = true;
     2807            parseMode = SourceParseMode::GeneratorWrapperMethodMode;
    27112808
    27122809parseMethod:
     
    27192816            break;
    27202817        case ASYNC:
    2721             isAsync = !isGenerator && !isAsyncMethod;
     2818            if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode)) {
     2819                ident = m_token.m_data.ident;
     2820                next();
     2821                if (match(OPENPAREN) || match(COLON) || match(EQUAL) || m_lexer->prevTerminator())
     2822                    break;
     2823                if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES)))
     2824                    parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode;
     2825                else
     2826                    parseMode = SourceParseMode::AsyncMethodMode;
     2827                goto parseMethod;
     2828            }
    27222829            FALLTHROUGH;
    27232830        case IDENT:
     
    27262833            ASSERT(ident);
    27272834            next();
    2728             if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
     2835            if (parseMode == SourceParseMode::MethodMode && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
    27292836                isGetter = *ident == propertyNames.get;
    27302837                isSetter = *ident == propertyNames.set;
    2731 
    2732                 if (UNLIKELY(isAsync && !m_lexer->prevTerminator())) {
    2733                     isAsyncMethod = true;
    2734                     goto parseMethod;
    2735                 }
    27362838            }
    27372839            break;
     
    27642866            ParserFunctionInfo<TreeBuilder> methodInfo;
    27652867            bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
    2766             SourceParseMode parseMode = SourceParseMode::MethodMode;
    2767             if (isAsyncMethod) {
     2868            if (isAsyncMethodParseMode(parseMode) || isAsyncGeneratorMethodParseMode(parseMode) || isGeneratorMethodParseMode(parseMode)) {
    27682869                isConstructor = false;
    2769                 parseMode = SourceParseMode::AsyncMethodMode;
    2770                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'");
    2771                 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
    2772             } else if (isGenerator) {
    2773                 isConstructor = false;
    2774                 parseMode = SourceParseMode::GeneratorWrapperMethodMode;
    2775                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");
    2776                 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'");
     2870                semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare ", stringArticleForFunctionMode(parseMode), stringForFunctionMode(parseMode), " named 'prototype'");
     2871                semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare ", stringArticleForFunctionMode(parseMode), stringForFunctionMode(parseMode), " named 'constructor'");
    27772872            }
     2873
    27782874            methodInfo.name = isConstructor ? info.className : ident;
    27792875            failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
     
    37623858template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete)
    37633859{
     3860    SourceParseMode parseMode = SourceParseMode::MethodMode;
    37643861    bool wasIdent = false;
    3765     bool isAsync = false;
    3766     bool isGenerator = false;
    37673862    bool isClassProperty = false;
    37683863    bool isStaticMethod = false;
    3769     bool isAsyncMethod = false;
     3864
    37703865    if (consume(TIMES))
    3771         isGenerator = true;
     3866        parseMode = SourceParseMode::GeneratorWrapperMethodMode;
    37723867
    37733868parseProperty:
    37743869    switch (m_token.m_type) {
    37753870    case ASYNC:
    3776         isAsync = !isGenerator && !isAsyncMethod;
     3871        if (parseMode == SourceParseMode::MethodMode) {
     3872            SavePoint savePoint = createSavePoint();
     3873            next();
     3874
     3875            if (match(COLON) || match(OPENPAREN) || match(COMMA) || match(CLOSEBRACE)) {
     3876                restoreSavePoint(savePoint);
     3877                wasIdent = true;
     3878                goto namedProperty;
     3879            }
     3880
     3881            failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");
     3882            if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES)))
     3883                parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode;
     3884            else
     3885                parseMode = SourceParseMode::AsyncMethodMode;
     3886            goto parseProperty;
     3887        }
    37773888        FALLTHROUGH;
    37783889    case IDENT:
     
    37833894    case STRING: {
    37843895namedProperty:
    3785         JSToken identToken = m_token;
    37863896        const Identifier* ident = m_token.m_data.ident;
    37873897        unsigned getterOrSetterStartOffset = tokenStart();
    3788 
    3789         if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)) || isAsync)
     3898        JSToken identToken = m_token;
     3899
     3900        if (complete || (wasIdent && !isGeneratorMethodParseMode(parseMode)  && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
    37903901            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
    37913902        else
    37923903            nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
    37933904
    3794         if (!isGenerator && !isAsyncMethod && match(COLON)) {
     3905        if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode) && match(COLON)) {
    37953906            next();
    37963907            TreeExpression node = parseAssignmentExpressionOrPropagateErrorClass(context);
     
    38023913
    38033914        if (match(OPENPAREN)) {
    3804             auto method = parsePropertyMethod(context, ident, isGenerator, isAsyncMethod);
     3915            auto method = parsePropertyMethod(context, ident, parseMode);
    38053916            propagateError();
    38063917            return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete, SuperBinding::Needed, InferName::Allowed, isClassProperty);
    38073918        }
    3808         failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
     3919        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
    38093920
    38103921        failIfFalse(wasIdent, "Expected an identifier as property name");
     
    38293940        else if (*ident == m_vm->propertyNames->set)
    38303941            type = PropertyNode::Setter;
    3831         else if (UNLIKELY(isAsync && !isAsyncMethod)) {
    3832             isAsyncMethod = true;
    3833             failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");
    3834             goto parseProperty;
    3835         } else
     3942        else
    38363943            failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
    38373944        return parseGetterSetter(context, complete, type, getterOrSetterStartOffset, ConstructorKind::None, isClassProperty, isStaticMethod);
     
    38443951        if (match(OPENPAREN)) {
    38453952            const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
    3846             auto method = parsePropertyMethod(context, &ident, isGenerator, isAsyncMethod);
     3953            auto method = parsePropertyMethod(context, &ident, parseMode);
    38473954            propagateError();
    38483955            return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete, SuperBinding::Needed, InferName::Allowed, isClassProperty);
    38493956        }
    3850         failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
     3957        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
    38513958
    38523959        consumeOrFail(COLON, "Expected ':' after property name");
     
    38633970
    38643971        if (match(OPENPAREN)) {
    3865             auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, isAsyncMethod);
     3972            auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, parseMode);
    38663973            propagateError();
    38673974            return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty);
    38683975        }
    3869         failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
     3976        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
    38703977
    38713978        consumeOrFail(COLON, "Expected ':' after property name");
     
    38964003
    38974004template <typename LexerType>
    3898 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod)
    3899 {
     4005template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, SourceParseMode parseMode)
     4006{
     4007    ASSERT(isMethodParseMode(parseMode));
    39004008    JSTokenLocation methodLocation(tokenLocation());
    39014009    unsigned methodStart = tokenStart();
    39024010    ParserFunctionInfo<TreeBuilder> methodInfo;
    39034011    methodInfo.name = methodName;
    3904     SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperMethodMode : isAsyncMethod ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
    39054012    failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
    39064013    return context.createMethodDefinition(methodLocation, methodInfo);
     
    42044311    unsigned functionKeywordStart = tokenStart();
    42054312    next();
     4313    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
     4314
     4315    if (Options::useAsyncIterator() && consume(TIMES))
     4316        parseMode = SourceParseMode::AsyncGeneratorWrapperFunctionMode;
     4317
    42064318    ParserFunctionInfo<TreeBuilder> functionInfo;
    42074319    functionInfo.name = &m_vm->propertyNames->nullIdentifier;
    4208     SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
    4209     failIfFalse(parseFunctionInfo(context, FunctionNameRequirements::None, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression");
     4320    failIfFalse(parseFunctionInfo(context, FunctionNameRequirements::None, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), parseMode == SourceParseMode::AsyncFunctionMode ? "Cannot parse async function expression" : "Cannot parse async generator function expression");
    42104321    return context.createFunctionExpr(location, functionInfo);
    42114322}
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r218861 r220323  
    226226    {
    227227        switch (mode) {
     228        case SourceParseMode::AsyncGeneratorBodyMode:
     229            setIsAsyncFunctionBody();
     230            setIsGenerator();
     231            break;
    228232        case SourceParseMode::AsyncArrowFunctionBodyMode:
    229233            setIsAsyncArrowFunctionBody();
     
    243247            break;
    244248
     249        case SourceParseMode::AsyncGeneratorWrapperMethodMode:
     250        case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
     251            setIsAsyncFunction();
     252            setIsGeneratorFunction();
     253            break;
     254   
    245255        case SourceParseMode::NormalFunctionMode:
    246256        case SourceParseMode::GetterMode:
     
    14961506    template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, const Identifier& name, SourceElementsMode);
    14971507    template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
     1508    template <class TreeBuilder> TreeSourceElements parseAsyncGeneratorFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
    14981509    template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
    14991510    template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
     
    15421553    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
    15431554    template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
    1544     template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
     1555    template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, SourceParseMode);
    15451556    template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty, bool isStaticMethod);
    15461557    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
  • trunk/Source/JavaScriptCore/parser/ParserModes.h

    r215723 r220323  
    4343enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
    4444
    45 enum class SourceParseMode : uint16_t {
    46     NormalFunctionMode            = 0b0000000000000001,
    47     GeneratorBodyMode             = 0b0000000000000010,
    48     GeneratorWrapperFunctionMode  = 0b0000000000000100,
    49     GeneratorWrapperMethodMode    = 0b0000000000001000,
    50     GetterMode                    = 0b0000000000010000,
    51     SetterMode                    = 0b0000000000100000,
    52     MethodMode                    = 0b0000000001000000,
    53     ArrowFunctionMode             = 0b0000000010000000,
    54     AsyncFunctionBodyMode         = 0b0000000100000000,
    55     AsyncArrowFunctionBodyMode    = 0b0000001000000000,
    56     AsyncFunctionMode             = 0b0000010000000000,
    57     AsyncMethodMode               = 0b0000100000000000,
    58     AsyncArrowFunctionMode        = 0b0001000000000000,
    59     ProgramMode                   = 0b0010000000000000,
    60     ModuleAnalyzeMode             = 0b0100000000000000,
    61     ModuleEvaluateMode            = 0b1000000000000000,
     45enum class SourceParseMode : uint32_t {
     46    NormalFunctionMode                = 0b00000000000000000000000000000001,
     47    GeneratorBodyMode                 = 0b00000000000000000000000000000010,
     48    GeneratorWrapperFunctionMode      = 0b00000000000000000000000000000100,
     49    GetterMode                        = 0b00000000000000000000000000001000,
     50    SetterMode                        = 0b00000000000000000000000000010000,
     51    MethodMode                        = 0b00000000000000000000000000100000,
     52    ArrowFunctionMode                 = 0b00000000000000000000000001000000,
     53    AsyncFunctionBodyMode             = 0b00000000000000000000000010000000,
     54    AsyncArrowFunctionBodyMode        = 0b00000000000000000000000100000000,
     55    AsyncFunctionMode                 = 0b00000000000000000000001000000000,
     56    AsyncMethodMode                   = 0b00000000000000000000010000000000,
     57    AsyncArrowFunctionMode            = 0b00000000000000000000100000000000,
     58    ProgramMode                       = 0b00000000000000000001000000000000,
     59    ModuleAnalyzeMode                 = 0b00000000000000000010000000000000,
     60    ModuleEvaluateMode                = 0b00000000000000000100000000000000,
     61    AsyncGeneratorBodyMode            = 0b00000000000000001000000000000000,
     62    AsyncGeneratorWrapperFunctionMode = 0b00000000000000010000000000000000,
     63    AsyncGeneratorWrapperMethodMode   = 0b00000000000000100000000000000000,
     64    GeneratorWrapperMethodMode        = 0b00000000000001000000000000000000,
    6265};
    6366
     
    105108        SourceParseMode::AsyncMethodMode,
    106109        SourceParseMode::AsyncArrowFunctionMode,
    107         SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
     110        SourceParseMode::AsyncArrowFunctionBodyMode,
     111        SourceParseMode::AsyncGeneratorBodyMode,
     112        SourceParseMode::AsyncGeneratorWrapperFunctionMode,
     113        SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
    108114}
    109115
    110116ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode)
    111117{
    112     return SourceParseModeSet(
     118    return SourceParseModeSet(
     119        SourceParseMode::AsyncGeneratorWrapperFunctionMode,
     120        SourceParseMode::AsyncGeneratorBodyMode,
     121        SourceParseMode::AsyncGeneratorWrapperMethodMode,
    113122        SourceParseMode::AsyncFunctionBodyMode,
    114123        SourceParseMode::AsyncFunctionMode,
     
    121130{
    122131    return SourceParseModeSet(
    123         SourceParseMode::AsyncArrowFunctionMode, 
     132        SourceParseMode::AsyncArrowFunctionMode,
    124133        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
    125134}
    126135
     136ALWAYS_INLINE bool isAsyncGeneratorFunctionParseMode(SourceParseMode parseMode)
     137{
     138    return SourceParseModeSet(
     139        SourceParseMode::AsyncGeneratorWrapperFunctionMode,
     140        SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
     141}
     142
     143ALWAYS_INLINE bool isAsyncFunctionOrAsyncGeneratorWrapperParseMode(SourceParseMode parseMode)
     144{
     145    return SourceParseModeSet(
     146        SourceParseMode::AsyncArrowFunctionMode,
     147        SourceParseMode::AsyncFunctionMode,
     148        SourceParseMode::AsyncGeneratorWrapperFunctionMode,
     149        SourceParseMode::AsyncGeneratorWrapperMethodMode,
     150        SourceParseMode::AsyncMethodMode).contains(parseMode);
     151    }
     152   
    127153ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
    128154{
    129155    return SourceParseModeSet(
    130156        SourceParseMode::AsyncArrowFunctionMode,
    131         SourceParseMode::AsyncFunctionMode, 
     157        SourceParseMode::AsyncFunctionMode,
    132158        SourceParseMode::AsyncMethodMode).contains(parseMode);
    133 } 
     159}
    134160
    135161ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
    136162{
    137163    return SourceParseModeSet(
    138         SourceParseMode::AsyncFunctionBodyMode,
     164        SourceParseMode::AsyncFunctionBodyMode,
     165        SourceParseMode::AsyncGeneratorBodyMode,
    139166        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
    140 }
     167}
     168   
     169ALWAYS_INLINE bool isGeneratorMethodParseMode(SourceParseMode parseMode)
     170{
     171    return SourceParseModeSet(
     172        SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
     173}
     174
     175ALWAYS_INLINE bool isAsyncMethodParseMode(SourceParseMode parseMode)
     176{
     177    return SourceParseModeSet(SourceParseMode::AsyncMethodMode).contains(parseMode);
     178}
     179   
     180ALWAYS_INLINE bool isAsyncGeneratorMethodParseMode(SourceParseMode parseMode)
     181{
     182    return SourceParseModeSet(SourceParseMode::AsyncGeneratorWrapperFunctionMode).contains(parseMode);
     183}
    141184
    142185ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode)
     
    147190        SourceParseMode::SetterMode,
    148191        SourceParseMode::MethodMode,
    149         SourceParseMode::AsyncMethodMode).contains(parseMode);
     192        SourceParseMode::AsyncMethodMode,
     193        SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
    150194}
    151195
     
    155199        SourceParseMode::GeneratorBodyMode,
    156200        SourceParseMode::AsyncFunctionBodyMode,
     201        SourceParseMode::AsyncGeneratorBodyMode,
    157202        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
    158203}
     
    165210        SourceParseMode::AsyncFunctionMode,
    166211        SourceParseMode::AsyncArrowFunctionMode,
    167         SourceParseMode::AsyncMethodMode).contains(parseMode);
     212        SourceParseMode::AsyncGeneratorWrapperFunctionMode,
     213        SourceParseMode::AsyncMethodMode,
     214        SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
    168215}
    169216
Note: See TracChangeset for help on using the changeset viewer.