Changeset 223124 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Oct 9, 2017, 10:53:12 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r223062 r223124 658 658 result = parseFunctionDeclaration(context); 659 659 break; 660 case ASYNC: { 661 // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case, 662 // but could be mistakenly parsed as an AsyncFunctionExpression. 663 SavePoint savePoint = createSavePoint(); 664 next(); 665 if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) { 666 result = parseAsyncFunctionDeclaration(context); 667 break; 668 } 669 restoreSavePoint(savePoint); 660 case IDENT: 661 if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped)) { 662 // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case, 663 // but could be mistakenly parsed as an AsyncFunctionExpression. 664 SavePoint savePoint = createSavePoint(); 665 next(); 666 if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) { 667 result = parseAsyncFunctionDeclaration(context); 668 break; 669 } 670 restoreSavePoint(savePoint); 671 } 670 672 FALLTHROUGH; 671 }672 case IDENT:673 673 case AWAIT: 674 674 case YIELD: { … … 1350 1350 bool isOfEnumeration = false; 1351 1351 if (!match(INTOKEN)) { 1352 failIfFalse(match (IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");1352 failIfFalse(matchContextualKeyword(m_vm->propertyNames->of), "Expected either 'in' or 'of' in enumeration syntax"); 1353 1353 isOfEnumeration = true; 1354 1354 next(); … … 1400 1400 pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::DeclarationStatement); 1401 1401 declsEnd = lastTokenEndPosition(); 1402 if (pattern && (match(INTOKEN) || (match(IDENT) && *m_token.m_data.ident ==m_vm->propertyNames->of)))1402 if (pattern && (match(INTOKEN) || matchContextualKeyword(m_vm->propertyNames->of))) 1403 1403 goto enumerationLoop; 1404 1404 pattern = TreeDestructuringPattern(0); … … 1455 1455 bool isOfEnumeration = false; 1456 1456 if (!match(INTOKEN)) { 1457 failIfFalse(match (IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");1457 failIfFalse(matchContextualKeyword(m_vm->propertyNames->of), "Expected either 'in' or 'of' in enumeration syntax"); 1458 1458 isOfEnumeration = true; 1459 1459 next(); … … 1900 1900 goto defaultCase; 1901 1901 } 1902 case ASYNC: 1903 if (maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement)) 1904 break; 1902 case IDENT: 1903 if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped)) { 1904 if (maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement)) 1905 break; 1906 } 1905 1907 FALLTHROUGH; 1906 case IDENT:1907 1908 case AWAIT: 1908 1909 case YIELD: { … … 1989 1990 template <class TreeBuilder> bool Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement) 1990 1991 { 1991 ASSERT(match (ASYNC));1992 ASSERT(matchContextualKeyword(m_vm->propertyNames->async)); 1992 1993 SavePoint savePoint = createSavePoint(); 1993 1994 next(); … … 2836 2837 next(); 2837 2838 break; 2838 case ASYNC: 2839 if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode)) { 2840 ident = m_token.m_data.ident; 2841 next(); 2842 if (match(OPENPAREN) || match(COLON) || match(EQUAL) || m_lexer->prevTerminator()) 2843 break; 2844 if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES))) 2845 parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode; 2846 else 2847 parseMode = SourceParseMode::AsyncMethodMode; 2848 goto parseMethod; 2839 case IDENT: 2840 if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped)) { 2841 if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode)) { 2842 ident = m_token.m_data.ident; 2843 next(); 2844 if (match(OPENPAREN) || match(COLON) || match(EQUAL) || m_lexer->prevTerminator()) 2845 break; 2846 if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES))) 2847 parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode; 2848 else 2849 parseMode = SourceParseMode::AsyncMethodMode; 2850 goto parseMethod; 2851 } 2849 2852 } 2850 2853 FALLTHROUGH; 2851 case IDENT:2852 2854 case AWAIT: 2853 2855 ident = m_token.m_data.ident; … … 3370 3372 localName = m_token.m_data.ident; 3371 3373 restoreSavePoint(savePoint); 3372 } else if (match (ASYNC)) {3374 } else if (matchContextualKeyword(m_vm->propertyNames->async)) { 3373 3375 SavePoint savePoint = createSavePoint(); 3374 3376 next(); … … 3394 3396 result = parseClassDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault); 3395 3397 } else { 3396 ASSERT(match (ASYNC));3398 ASSERT(matchContextualKeyword(m_vm->propertyNames->async)); 3397 3399 next(); 3398 3400 DepthManager statementDepth(&m_statementDepth); … … 3515 3517 break; 3516 3518 3517 case ASYNC: { 3518 next(); 3519 semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator"); 3520 DepthManager statementDepth(&m_statementDepth); 3521 m_statementDepth = 1; 3522 result = parseAsyncFunctionDeclaration(context, ExportType::Exported); 3523 break; 3524 } 3525 3519 case IDENT: 3520 if (*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped) { 3521 next(); 3522 semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator"); 3523 DepthManager statementDepth(&m_statementDepth); 3524 m_statementDepth = 1; 3525 result = parseAsyncFunctionDeclaration(context, ExportType::Exported); 3526 break; 3527 } 3528 FALLTHROUGH; 3526 3529 default: 3527 3530 failWithMessage("Expected either a declaration or a variable statement"); … … 3621 3624 bool isAsyncArrow = false; 3622 3625 if (UNLIKELY(classifier.indicatesPossibleAsyncArrowFunction())) { 3623 ASSERT(match (ASYNC));3626 ASSERT(matchContextualKeyword(m_vm->propertyNames->async)); 3624 3627 next(); 3625 3628 isAsyncArrow = !m_lexer->prevTerminator(); … … 3889 3892 parseProperty: 3890 3893 switch (m_token.m_type) { 3891 case ASYNC: 3892 if (parseMode == SourceParseMode::MethodMode) { 3893 SavePoint savePoint = createSavePoint(); 3894 next(); 3895 3896 if (match(COLON) || match(OPENPAREN) || match(COMMA) || match(CLOSEBRACE)) { 3897 restoreSavePoint(savePoint); 3898 wasIdent = true; 3899 goto namedProperty; 3894 case IDENT: 3895 if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped)) { 3896 if (parseMode == SourceParseMode::MethodMode) { 3897 SavePoint savePoint = createSavePoint(); 3898 next(); 3899 3900 if (match(COLON) || match(OPENPAREN) || match(COMMA) || match(CLOSEBRACE)) { 3901 restoreSavePoint(savePoint); 3902 wasIdent = true; 3903 goto namedProperty; 3904 } 3905 3906 failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'"); 3907 if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES))) 3908 parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode; 3909 else 3910 parseMode = SourceParseMode::AsyncMethodMode; 3911 goto parseProperty; 3900 3912 } 3901 3902 failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");3903 if (Options::useAsyncIterator() && UNLIKELY(consume(TIMES)))3904 parseMode = SourceParseMode::AsyncGeneratorWrapperMethodMode;3905 else3906 parseMode = SourceParseMode::AsyncMethodMode;3907 goto parseProperty;3908 3913 } 3909 3914 FALLTHROUGH; 3910 case IDENT:3911 3915 case YIELD: 3912 3916 case AWAIT: … … 4449 4453 4450 4454 goto identifierExpression; 4451 case ASYNC: {4452 JSTextPosition start = tokenStartPosition();4453 const Identifier* ident = m_token.m_data.ident;4454 JSTokenLocation location(tokenLocation());4455 next();4456 if (match(FUNCTION) && !m_lexer->prevTerminator())4457 return parseAsyncFunctionExpression(context);4458 4459 // Avoid using variable if it is an arrow function parameter4460 if (UNLIKELY(match(ARROWFUNCTION)))4461 return 0;4462 4463 const bool isEval = false;4464 return createResolveAndUseVariable(context, ident, isEval, start, location);4465 }4466 4455 case IDENT: { 4456 if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && !m_token.m_data.escaped)) { 4457 JSTextPosition start = tokenStartPosition(); 4458 const Identifier* ident = m_token.m_data.ident; 4459 JSTokenLocation location(tokenLocation()); 4460 next(); 4461 if (match(FUNCTION) && !m_lexer->prevTerminator()) 4462 return parseAsyncFunctionExpression(context); 4463 4464 // Avoid using variable if it is an arrow function parameter 4465 if (UNLIKELY(match(ARROWFUNCTION))) 4466 return 0; 4467 4468 const bool isEval = false; 4469 return createResolveAndUseVariable(context, ident, isEval, start, location); 4470 } 4467 4471 identifierExpression: 4468 4472 JSTextPosition start = tokenStartPosition(); … … 4650 4654 if (newCount && match(DOT)) { 4651 4655 next(); 4652 if (match(IDENT)) { 4653 const Identifier* ident = m_token.m_data.ident; 4654 if (m_vm->propertyNames->target == *ident) { 4655 ScopeRef closestOrdinaryFunctionScope = closestParentOrdinaryFunctionNonLexicalScope(); 4656 semanticFailIfFalse(currentScope()->isFunction() || closestOrdinaryFunctionScope->evalContextType() == EvalContextType::FunctionEvalContext, "new.target is only valid inside functions"); 4657 baseIsNewTarget = true; 4658 if (currentScope()->isArrowFunction()) { 4659 semanticFailIfFalse(!closestOrdinaryFunctionScope->isGlobalCodeScope() || closestOrdinaryFunctionScope->evalContextType() == EvalContextType::FunctionEvalContext, "new.target is not valid inside arrow functions in global code"); 4660 currentScope()->setInnerArrowFunctionUsesNewTarget(); 4661 } 4662 base = context.createNewTargetExpr(location); 4663 newCount--; 4664 next(); 4665 } else 4666 failWithMessage("\"new.\" can only followed with target"); 4667 } else 4656 if (matchContextualKeyword(m_vm->propertyNames->target)) { 4657 ScopeRef closestOrdinaryFunctionScope = closestParentOrdinaryFunctionNonLexicalScope(); 4658 semanticFailIfFalse(currentScope()->isFunction() || closestOrdinaryFunctionScope->evalContextType() == EvalContextType::FunctionEvalContext, "new.target is only valid inside functions"); 4659 baseIsNewTarget = true; 4660 if (currentScope()->isArrowFunction()) { 4661 semanticFailIfFalse(!closestOrdinaryFunctionScope->isGlobalCodeScope() || closestOrdinaryFunctionScope->evalContextType() == EvalContextType::FunctionEvalContext, "new.target is not valid inside arrow functions in global code"); 4662 currentScope()->setInnerArrowFunctionUsesNewTarget(); 4663 } 4664 base = context.createNewTargetExpr(location); 4665 newCount--; 4666 next(); 4667 } else { 4668 failIfTrue(match(IDENT), "\"new.\" can only followed with target"); 4668 4669 failDueToUnexpectedToken(); 4670 } 4669 4671 } 4670 4672 … … 4692 4694 JSTextPosition expressionEnd = lastTokenEndPosition(); 4693 4695 if (consume(DOT)) { 4694 if (!match(IDENT)) 4696 if (matchContextualKeyword(m_vm->propertyNames->builtinNames().metaPublicName())) { 4697 semanticFailIfFalse(m_scriptMode == JSParserScriptMode::Module, "import.meta is only valid inside modules"); 4698 4699 JSTokenLocation location(tokenLocation()); 4700 base = createResolveAndUseVariable(context, &m_vm->propertyNames->builtinNames().metaPrivateName(), false, expressionStart, location); 4701 next(); 4702 } else { 4703 failIfTrue(match(IDENT), "\"import.\" can only followed with meta"); 4695 4704 failDueToUnexpectedToken(); 4696 const Identifier* ident = m_token.m_data.ident; 4697 if (m_vm->propertyNames->builtinNames().metaPublicName() != *ident) 4698 failWithMessage("\"import.\" can only followed with meta"); 4699 4700 semanticFailIfFalse(m_scriptMode == JSParserScriptMode::Module, "import.meta is only valid inside modules"); 4701 4702 JSTokenLocation location(tokenLocation()); 4703 base = createResolveAndUseVariable(context, &m_vm->propertyNames->builtinNames().metaPrivateName(), false, expressionStart, location); 4704 next(); 4705 } 4705 4706 } else { 4706 4707 consumeOrFail(OPENPAREN, "import call expects exactly one argument"); … … 4711 4712 } 4712 4713 } else if (!baseIsNewTarget) { 4713 const bool isAsync = match (ASYNC);4714 const bool isAsync = matchContextualKeyword(m_vm->propertyNames->async); 4714 4715 4715 4716 base = parsePrimaryExpression(context); … … 5068 5069 return; 5069 5070 5070 case ASYNC:5071 5071 case AWAIT: 5072 5072 case IDENT:
Note:
See TracChangeset
for help on using the changeset viewer.