Changeset 220323 in webkit
- Timestamp:
- Aug 6, 2017 6:04:32 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r220265 r220323 1 2017-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 1 20 2017-08-03 Carlos Alberto Lopez Perez <clopez@igalia.com> 2 21 -
trunk/JSTests/stress/async-await-syntax.js
r217629 r220323 33 33 34 34 (function testTopLevelAsyncAwaitSyntaxSloppyMode() { 35 testSyntax(`({async: 1})`); 35 36 testSyntax(`var asyncFn = async function() { await 1; };`); 36 37 testSyntax(`var asyncFn = async function withName() { await 1; };`); 37 38 testSyntax(`var asyncFn = async () => await 'test';`); 38 39 testSyntax(`var asyncFn = async x => await x + 'test';`); 40 testSyntax(`function foo(fn) { fn({ async: true }); }`); 39 41 testSyntax(`async function asyncFn() { await 1; }`); 40 42 testSyntax(`var O = { async method() { await 1; } };`); … … 66 68 67 69 (function testTopLevelAsyncAwaitSyntaxStrictMode() { 70 testSyntax(`"use strict"; ({async: 1})`); 68 71 testSyntax(`"use strict"; var asyncFn = async function() { await 1; };`); 69 72 testSyntax(`"use strict"; var asyncFn = async function withName() { await 1; };`); 70 73 testSyntax(`"use strict"; var asyncFn = async () => await 'test';`); 71 74 testSyntax(`"use strict"; var asyncFn = async x => await x + 'test';`); 75 testSyntax(`"use strict"; function foo(fn) { fn({ async: true }); }`); 72 76 testSyntax(`"use strict"; async function asyncFn() { await 1; }`); 73 77 testSyntax(`"use strict"; var O = { async method() { await 1; } };`); … … 156 160 157 161 (function testTopLevelAsyncAwaitSyntaxSloppyMode() { 162 testSyntaxError(`({ async 163 foo() {} })`); 164 testSyntaxError(`({async = 1})`); 158 165 testSyntaxError(`var asyncFn = async function await() {}`); 159 166 testSyntaxError(`var asyncFn = async () => var await = 'test';`); … … 187 194 testSyntaxError(`var asyncArrowFn = async() => await;`); 188 195 189 testSyntax Error(`var asyncFn = async function*() {}`);190 testSyntax Error(`async function* asyncGenerator() {}`);196 testSyntax(`var asyncFn = async function*() {}`); 197 testSyntax(`async function* asyncGenerator() {}`); 191 198 testSyntaxError(`var O = { *async asyncGeneratorMethod() {} };`); 192 testSyntax Error(`var O = { async *asyncGeneratorMethod() {} };`);199 testSyntax(`var O = { async *asyncGeneratorMethod() {} };`); 193 200 testSyntaxError(`var O = { async asyncGeneratorMethod*() {} };`); 194 201 … … 242 249 243 250 (function testTopLevelAsyncAwaitSyntaxStrictMode() { 251 testSyntaxError(`"use strict"; ({ async 252 foo() {} })`); 253 testSyntaxError(`"use strict"; ({async = 1})`); 244 254 testSyntaxError(`"use strict"; var asyncFn = async function await() {}`); 245 255 testSyntaxError(`"use strict"; var asyncFn = async () => var await = 'test';`); … … 258 268 testSyntaxError(`"use strict"; var asyncArrowFn = async() => await;`); 259 269 260 testSyntaxError(`"use strict"; var asyncFn = async function*() {}`);261 testSyntaxError(`"use strict"; async function* asyncGenerator() {}`);262 270 testSyntaxError(`"use strict"; var O = { *async asyncGeneratorMethod() {} };`); 263 testSyntaxError(`"use strict"; var O = { async *asyncGeneratorMethod() {} };`);264 271 testSyntaxError(`"use strict"; var O = { async asyncGeneratorMethod*() {} };`); 265 272 -
trunk/JSTests/stress/generator-class-methods-syntax.js
r192937 r220323 28 28 } 29 29 } 30 `, `SyntaxError: Cannot declare a generator named 'constructor'.`);30 `, `SyntaxError: Cannot declare a generator function named 'constructor'.`); 31 31 32 32 testSyntax(` -
trunk/Source/JavaScriptCore/ChangeLog
r220322 r220323 1 2017-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 1 46 2017-08-05 Filip Pizlo <fpizlo@apple.com> 2 47 -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r219702 r220323 438 438 SourceParseMode mode, bool isArrowFunctionBodyExpression) 439 439 { 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 440 452 return new (m_parserArena) FunctionMetadataNode( 441 453 m_parserArena, startLocation, endLocation, startColumn, endColumn, 442 454 functionKeywordStart, functionNameStart, parametersStart, 443 455 inStrictContext, constructorKind, superBinding, 444 parameterCount, mode, isArrowFunctionBodyExpression);456 parameterCount, bodySourceParseMode, isArrowFunctionBodyExpression); 445 457 } 446 458 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r220068 r220323 91 91 namespace JSC { 92 92 93 ALWAYS_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 93 104 template <typename LexerType> 94 105 void Parser<LexerType>::logError(bool) … … 229 240 else if (isGeneratorWrapperParseMode(parseMode)) 230 241 sourceElements = parseGeneratorFunctionSourceElements(context, calleeName, CheckForStrictMode); 242 else if (isAsyncGeneratorFunctionParseMode(parseMode)) 243 sourceElements = parseAsyncGeneratorFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode); 231 244 else 232 245 sourceElements = parseSourceElements(context, CheckForStrictMode); … … 250 263 varDeclarations.markVariableAsCaptured(entry); 251 264 252 if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunction WrapperParseMode(parseMode)) {265 if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(parseMode)) { 253 266 if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl())) 254 267 context.propagateArgumentsUse(); … … 503 516 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode) 504 517 { 505 ASSERT(isAsyncFunction WrapperParseMode(parseMode));518 ASSERT(isAsyncFunctionOrAsyncGeneratorWrapperParseMode(parseMode)); 506 519 auto sourceElements = context.createSourceElements(); 507 520 … … 518 531 info.startOffset = parametersStart; 519 532 info.startLine = tokenLine(); 520 SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode 521 ? SourceParseMode::AsyncArrowFunctionBodyMode522 : SourceParseMode::AsyncFunctionBodyMode; 533 534 SourceParseMode innerParseMode = getAsynFunctionBodyParseMode(parseMode); 535 523 536 { 524 537 AutoPopScopeRef asyncFunctionBodyScope(this, pushScope()); … … 551 564 } 552 565 566 template <typename LexerType> 567 template <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 553 615 template <typename LexerType> 554 616 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength) … … 2007 2069 } 2008 2070 2071 static 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 2009 2102 static const char* stringForFunctionMode(SourceParseMode mode) 2010 2103 { … … 2033 2126 case SourceParseMode::AsyncArrowFunctionMode: 2034 2127 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"; 2035 2133 case SourceParseMode::ProgramMode: 2036 2134 case SourceParseMode::ModuleAnalyzeMode: … … 2304 2402 m_parserState.lastFunctionName = functionInfo.name; 2305 2403 if (UNLIKELY(isDisallowedAwaitFunctionName)) 2306 semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunction WrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);2307 else if (isAsyncFunction WrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)2308 semanticFail("Cannot declare async functionnamed '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'"); 2309 2407 else if (isGeneratorWrapperParseMode(mode) && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression) 2310 2408 semanticFail("Cannot declare generator function named 'yield'"); … … 2388 2486 AutoPopScopeRef generatorBodyScope(this, pushScope()); 2389 2487 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 2395 2491 generatorBodyScope->setSourceParseMode(innerParseMode); 2396 2492 generatorBodyScope->setConstructorKind(ConstructorKind::None); … … 2417 2513 if (functionScope->strictMode() && requirements != FunctionNameRequirements::Unnamed) { 2418 2514 ASSERT(functionInfo.name); 2419 RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunction WrapperParseMode(mode));2515 RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(mode)); 2420 2516 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 2421 2517 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); … … 2543 2639 ParserFunctionInfo<TreeBuilder> functionInfo; 2544 2640 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; 2641 if (Options::useAsyncIterator() && consume(TIMES)) 2642 parseMode = SourceParseMode::AsyncGeneratorWrapperFunctionMode; 2643 2545 2644 FunctionNameRequirements requirements = FunctionNameRequirements::Named; 2546 2645 if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) { … … 2704 2803 bool isGetter = false; 2705 2804 bool isSetter = false; 2706 bool isGenerator = false; 2707 bool isAsync = false; 2708 bool isAsyncMethod = false; 2805 SourceParseMode parseMode = SourceParseMode::MethodMode; 2709 2806 if (consume(TIMES)) 2710 isGenerator = true;2807 parseMode = SourceParseMode::GeneratorWrapperMethodMode; 2711 2808 2712 2809 parseMethod: … … 2719 2816 break; 2720 2817 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 } 2722 2829 FALLTHROUGH; 2723 2830 case IDENT: … … 2726 2833 ASSERT(ident); 2727 2834 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))) { 2729 2836 isGetter = *ident == propertyNames.get; 2730 2837 isSetter = *ident == propertyNames.set; 2731 2732 if (UNLIKELY(isAsync && !m_lexer->prevTerminator())) {2733 isAsyncMethod = true;2734 goto parseMethod;2735 }2736 2838 } 2737 2839 break; … … 2764 2866 ParserFunctionInfo<TreeBuilder> methodInfo; 2765 2867 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 2766 SourceParseMode parseMode = SourceParseMode::MethodMode; 2767 if (isAsyncMethod) { 2868 if (isAsyncMethodParseMode(parseMode) || isAsyncGeneratorMethodParseMode(parseMode) || isGeneratorMethodParseMode(parseMode)) { 2768 2869 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'"); 2777 2872 } 2873 2778 2874 methodInfo.name = isConstructor ? info.className : ident; 2779 2875 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); … … 3762 3858 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete) 3763 3859 { 3860 SourceParseMode parseMode = SourceParseMode::MethodMode; 3764 3861 bool wasIdent = false; 3765 bool isAsync = false;3766 bool isGenerator = false;3767 3862 bool isClassProperty = false; 3768 3863 bool isStaticMethod = false; 3769 bool isAsyncMethod = false; 3864 3770 3865 if (consume(TIMES)) 3771 isGenerator = true;3866 parseMode = SourceParseMode::GeneratorWrapperMethodMode; 3772 3867 3773 3868 parseProperty: 3774 3869 switch (m_token.m_type) { 3775 3870 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 } 3777 3888 FALLTHROUGH; 3778 3889 case IDENT: … … 3783 3894 case STRING: { 3784 3895 namedProperty: 3785 JSToken identToken = m_token;3786 3896 const Identifier* ident = m_token.m_data.ident; 3787 3897 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))) 3790 3901 nextExpectIdentifier(LexerFlagsIgnoreReservedWords); 3791 3902 else 3792 3903 nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); 3793 3904 3794 if (!isGenerator && !isAsyncMethod&& match(COLON)) {3905 if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode) && match(COLON)) { 3795 3906 next(); 3796 3907 TreeExpression node = parseAssignmentExpressionOrPropagateErrorClass(context); … … 3802 3913 3803 3914 if (match(OPENPAREN)) { 3804 auto method = parsePropertyMethod(context, ident, isGenerator, isAsyncMethod);3915 auto method = parsePropertyMethod(context, ident, parseMode); 3805 3916 propagateError(); 3806 3917 return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete, SuperBinding::Needed, InferName::Allowed, isClassProperty); 3807 3918 } 3808 failIfTrue( isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");3919 failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list"); 3809 3920 3810 3921 failIfFalse(wasIdent, "Expected an identifier as property name"); … … 3829 3940 else if (*ident == m_vm->propertyNames->set) 3830 3941 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 3836 3943 failWithMessage("Expected a ':' following the property name '", ident->impl(), "'"); 3837 3944 return parseGetterSetter(context, complete, type, getterOrSetterStartOffset, ConstructorKind::None, isClassProperty, isStaticMethod); … … 3844 3951 if (match(OPENPAREN)) { 3845 3952 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); 3847 3954 propagateError(); 3848 3955 return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete, SuperBinding::Needed, InferName::Allowed, isClassProperty); 3849 3956 } 3850 failIfTrue( isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");3957 failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list"); 3851 3958 3852 3959 consumeOrFail(COLON, "Expected ':' after property name"); … … 3863 3970 3864 3971 if (match(OPENPAREN)) { 3865 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, isAsyncMethod);3972 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, parseMode); 3866 3973 propagateError(); 3867 3974 return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty); 3868 3975 } 3869 failIfTrue( isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");3976 failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list"); 3870 3977 3871 3978 consumeOrFail(COLON, "Expected ':' after property name"); … … 3896 4003 3897 4004 template <typename LexerType> 3898 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod) 3899 { 4005 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, SourceParseMode parseMode) 4006 { 4007 ASSERT(isMethodParseMode(parseMode)); 3900 4008 JSTokenLocation methodLocation(tokenLocation()); 3901 4009 unsigned methodStart = tokenStart(); 3902 4010 ParserFunctionInfo<TreeBuilder> methodInfo; 3903 4011 methodInfo.name = methodName; 3904 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperMethodMode : isAsyncMethod ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;3905 4012 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 3906 4013 return context.createMethodDefinition(methodLocation, methodInfo); … … 4204 4311 unsigned functionKeywordStart = tokenStart(); 4205 4312 next(); 4313 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; 4314 4315 if (Options::useAsyncIterator() && consume(TIMES)) 4316 parseMode = SourceParseMode::AsyncGeneratorWrapperFunctionMode; 4317 4206 4318 ParserFunctionInfo<TreeBuilder> functionInfo; 4207 4319 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"); 4210 4321 return context.createFunctionExpr(location, functionInfo); 4211 4322 } -
trunk/Source/JavaScriptCore/parser/Parser.h
r218861 r220323 226 226 { 227 227 switch (mode) { 228 case SourceParseMode::AsyncGeneratorBodyMode: 229 setIsAsyncFunctionBody(); 230 setIsGenerator(); 231 break; 228 232 case SourceParseMode::AsyncArrowFunctionBodyMode: 229 233 setIsAsyncArrowFunctionBody(); … … 243 247 break; 244 248 249 case SourceParseMode::AsyncGeneratorWrapperMethodMode: 250 case SourceParseMode::AsyncGeneratorWrapperFunctionMode: 251 setIsAsyncFunction(); 252 setIsGeneratorFunction(); 253 break; 254 245 255 case SourceParseMode::NormalFunctionMode: 246 256 case SourceParseMode::GetterMode: … … 1496 1506 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, const Identifier& name, SourceElementsMode); 1497 1507 template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode); 1508 template <class TreeBuilder> TreeSourceElements parseAsyncGeneratorFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode); 1498 1509 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength); 1499 1510 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0); … … 1542 1553 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&); 1543 1554 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); 1545 1556 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty, bool isStaticMethod); 1546 1557 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 43 43 enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition }; 44 44 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, 45 enum 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, 62 65 }; 63 66 … … 105 108 SourceParseMode::AsyncMethodMode, 106 109 SourceParseMode::AsyncArrowFunctionMode, 107 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 110 SourceParseMode::AsyncArrowFunctionBodyMode, 111 SourceParseMode::AsyncGeneratorBodyMode, 112 SourceParseMode::AsyncGeneratorWrapperFunctionMode, 113 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode); 108 114 } 109 115 110 116 ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode) 111 117 { 112 return SourceParseModeSet( 118 return SourceParseModeSet( 119 SourceParseMode::AsyncGeneratorWrapperFunctionMode, 120 SourceParseMode::AsyncGeneratorBodyMode, 121 SourceParseMode::AsyncGeneratorWrapperMethodMode, 113 122 SourceParseMode::AsyncFunctionBodyMode, 114 123 SourceParseMode::AsyncFunctionMode, … … 121 130 { 122 131 return SourceParseModeSet( 123 SourceParseMode::AsyncArrowFunctionMode, 132 SourceParseMode::AsyncArrowFunctionMode, 124 133 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 125 134 } 126 135 136 ALWAYS_INLINE bool isAsyncGeneratorFunctionParseMode(SourceParseMode parseMode) 137 { 138 return SourceParseModeSet( 139 SourceParseMode::AsyncGeneratorWrapperFunctionMode, 140 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode); 141 } 142 143 ALWAYS_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 127 153 ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode) 128 154 { 129 155 return SourceParseModeSet( 130 156 SourceParseMode::AsyncArrowFunctionMode, 131 SourceParseMode::AsyncFunctionMode, 157 SourceParseMode::AsyncFunctionMode, 132 158 SourceParseMode::AsyncMethodMode).contains(parseMode); 133 } 159 } 134 160 135 161 ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode) 136 162 { 137 163 return SourceParseModeSet( 138 SourceParseMode::AsyncFunctionBodyMode, 164 SourceParseMode::AsyncFunctionBodyMode, 165 SourceParseMode::AsyncGeneratorBodyMode, 139 166 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 140 } 167 } 168 169 ALWAYS_INLINE bool isGeneratorMethodParseMode(SourceParseMode parseMode) 170 { 171 return SourceParseModeSet( 172 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode); 173 } 174 175 ALWAYS_INLINE bool isAsyncMethodParseMode(SourceParseMode parseMode) 176 { 177 return SourceParseModeSet(SourceParseMode::AsyncMethodMode).contains(parseMode); 178 } 179 180 ALWAYS_INLINE bool isAsyncGeneratorMethodParseMode(SourceParseMode parseMode) 181 { 182 return SourceParseModeSet(SourceParseMode::AsyncGeneratorWrapperFunctionMode).contains(parseMode); 183 } 141 184 142 185 ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode) … … 147 190 SourceParseMode::SetterMode, 148 191 SourceParseMode::MethodMode, 149 SourceParseMode::AsyncMethodMode).contains(parseMode); 192 SourceParseMode::AsyncMethodMode, 193 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode); 150 194 } 151 195 … … 155 199 SourceParseMode::GeneratorBodyMode, 156 200 SourceParseMode::AsyncFunctionBodyMode, 201 SourceParseMode::AsyncGeneratorBodyMode, 157 202 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 158 203 } … … 165 210 SourceParseMode::AsyncFunctionMode, 166 211 SourceParseMode::AsyncArrowFunctionMode, 167 SourceParseMode::AsyncMethodMode).contains(parseMode); 212 SourceParseMode::AsyncGeneratorWrapperFunctionMode, 213 SourceParseMode::AsyncMethodMode, 214 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode); 168 215 } 169 216
Note: See TracChangeset
for help on using the changeset viewer.