Changeset 186959 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jul 17, 2015, 11:48:30 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r186860 r186959 192 192 template <typename LexerType> 193 193 Parser<LexerType>::Parser( 194 VM* vm, const SourceCode& source, FunctionParameters* parameters, 195 const Identifier& name, JSParserBuiltinMode builtinMode, 194 VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, 196 195 JSParserStrictMode strictMode, JSParserCodeType codeType, 197 196 ConstructorKind defaultConstructorKind, ThisTDZMode thisTDZMode) … … 224 223 if (strictMode == JSParserStrictMode::Strict) 225 224 scope->setStrictMode(); 226 if (parameters) { 227 bool hadBindingParameters = false; 228 for (unsigned i = 0; i < parameters->size(); i++) { 229 auto parameter = parameters->at(i); 230 if (!parameter->isBindingNode()) { 231 hadBindingParameters = true; 232 continue; 233 } 234 scope->declareParameter(&static_cast<BindingNode*>(parameter)->boundProperty()); 235 } 236 if (hadBindingParameters) { 237 Vector<Identifier> boundParameterNames; 238 for (unsigned i = 0; i < parameters->size(); i++) { 239 auto parameter = parameters->at(i); 240 if (parameter->isBindingNode()) 241 continue; 242 parameter->collectBoundIdentifiers(boundParameterNames); 243 } 244 for (auto& boundParameterName : boundParameterNames) 245 scope->declareVariable(&boundParameterName); 246 } 247 } 248 if (!name.isNull()) 249 scope->declareCallee(&name); 225 250 226 next(); 251 227 } … … 257 233 258 234 template <typename LexerType> 259 String Parser<LexerType>::parseInner( )235 String Parser<LexerType>::parseInner(const Identifier& calleeName, FunctionParseMode parseMode) 260 236 { 261 237 String parseError = String(); 262 238 263 239 ASTBuilder context(const_cast<VM*>(m_vm), m_parserArena, const_cast<SourceCode*>(m_source)); 264 if (m_lexer->isReparsing())265 m_statementDepth--;266 240 ScopeRef scope = currentScope(); 267 241 scope->setIsLexicalScope(); 268 242 269 SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode, StandardFunctionParseType); 270 if (!sourceElements || !consume(EOFTOK)) { 243 bool isArrowFunctionBodyExpression = false; 244 if (m_lexer->isReparsingFunction()) { 245 ParserFunctionInfo<ASTBuilder> functionInfo; 246 parseFunctionParameters(context, parseMode, functionInfo); 247 m_parameters = functionInfo.parameters; 248 249 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 250 if (parseMode == ArrowFunctionMode && !hasError()) { 251 // The only way we could have an error wile reparsing is if we run out of stack space. 252 RELEASE_ASSERT(match(ARROWFUNCTION)); 253 next(); 254 isArrowFunctionBodyExpression = !match(OPENBRACE); 255 } 256 #endif 257 } 258 259 if (!calleeName.isNull()) 260 scope->declareCallee(&calleeName); 261 262 if (m_lexer->isReparsingFunction()) 263 m_statementDepth--; 264 265 SourceElements* sourceElements = nullptr; 266 // The only way we can error this early is if we reparse a function and we run out of stack space. 267 if (!hasError()) { 268 if (isArrowFunctionBodyExpression) 269 sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context); 270 else 271 sourceElements = parseSourceElements(context, CheckForStrictMode); 272 } 273 274 bool validEnding; 275 if (isArrowFunctionBodyExpression) { 276 ASSERT(m_lexer->isReparsingFunction()); 277 // When we reparse and stack overflow, we're not guaranteed a valid ending. If we don't run out of stack space, 278 // then of course this will always be valid because we already parsed for syntax errors. But we must 279 // be cautious in case we run out of stack space. 280 validEnding = isEndOfArrowFunction(); 281 } else 282 validEnding = consume(EOFTOK); 283 284 if (!sourceElements || !validEnding) { 271 285 if (hasError()) 272 286 parseError = m_errorMessage; … … 347 361 348 362 template <typename LexerType> 349 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode , FunctionParseType functionParseType)363 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode) 350 364 { 351 365 const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length … … 356 370 auto savePoint = createSavePoint(); 357 371 bool hasSetStrict = false; 358 359 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)360 if (match(ARROWFUNCTION)) {361 TreeStatement arrowfunctionStatement = parseArrowFunctionSingleExpressionBody(context, functionParseType);362 363 if (arrowfunctionStatement) {364 context.setEndOffset(arrowfunctionStatement, m_lastTokenEndPosition.offset);365 context.appendStatement(sourceElements, arrowfunctionStatement);366 }367 368 propagateError();369 return sourceElements;370 }371 #else372 UNUSED_PARAM(functionParseType);373 #endif374 372 375 373 while (TreeStatement statement = parseStatementListItem(context, directive, &directiveLiteralLength)) { … … 663 661 } 664 662 665 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 666 template <typename LexerType> 667 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseArrowFunctionSingleExpressionBody(TreeBuilder& context, FunctionParseType parseType) 668 { 669 ASSERT(match(ARROWFUNCTION)); 670 671 // When reparsing phase, parseType becomes StandardFunctionParseType even if the function is arrow function. 672 // This condition considers the following situations. 673 // (1): If we are in the reparsing phase, this arrow function is already parsed once, so there is no syntax error. 674 // (2): But if we are not in the reparsing phase, we should check this function is called in the context of the arrow function. 675 if (!m_lexer->isReparsing() && parseType != ArrowFunctionParseType) 676 failDueToUnexpectedToken(); 677 663 template <typename LexerType> 664 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder& context) 665 { 666 ASSERT(!match(OPENBRACE)); 667 678 668 JSTokenLocation location(tokenLocation()); 679 669 JSTextPosition start = tokenStartPosition(); 680 JSTextPosition end = tokenEndPosition();681 682 next();683 670 684 671 failIfStackOverflow(); … … 690 677 failIfFalse(isEndOfArrowFunction(), "Expected a ';', ']', '}', ')', ',', line terminator or EOF following a arrow function statement"); 691 678 692 end = tokenEndPosition();679 JSTextPosition end = tokenEndPosition(); 693 680 694 681 if (!m_lexer->prevTerminator()) 695 682 setEndOfStatement(); 696 683 697 return context.createReturnStatement(location, expr, start, end); 698 } 699 #endif 684 TreeSourceElements sourceElements = context.createSourceElements(); 685 TreeStatement body = context.createReturnStatement(location, expr, start, end); 686 context.setEndOffset(body, m_lastTokenEndPosition.offset); 687 context.appendStatement(sourceElements, body); 688 689 return sourceElements; 690 } 700 691 701 692 template <typename LexerType> … … 1230 1221 failIfFalse(condition, "Cannot parse switch clause"); 1231 1222 consumeOrFail(COLON, "Expected a ':' after switch clause expression"); 1232 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode , StandardFunctionParseType);1223 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode); 1233 1224 failIfFalse(statements, "Cannot parse the body of a switch clause"); 1234 1225 TreeClause clause = context.createClause(condition, statements); … … 1243 1234 failIfFalse(condition, "Cannot parse switch case expression"); 1244 1235 consumeOrFail(COLON, "Expected a ':' after switch clause expression"); 1245 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode , StandardFunctionParseType);1236 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode); 1246 1237 failIfFalse(statements, "Cannot parse the body of a switch clause"); 1247 1238 clause = context.createClause(condition, statements); … … 1260 1251 next(); 1261 1252 consumeOrFail(COLON, "Expected a ':' after switch default clause"); 1262 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode , StandardFunctionParseType);1253 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode); 1263 1254 failIfFalse(statements, "Cannot parse the body of a switch default clause"); 1264 1255 TreeClause result = context.createClause(0, statements); … … 1359 1350 return result; 1360 1351 } 1361 TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode , StandardFunctionParseType);1352 TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode); 1362 1353 failIfFalse(subtree, "Cannot parse the body of the block statement"); 1363 1354 matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement"); … … 1467 1458 1468 1459 template <typename LexerType> 1469 template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFormalParameters(TreeBuilder& context)1460 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount) 1470 1461 { 1471 1462 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1472 1463 failIfFalse(parameter, "Cannot parse parameter pattern"); 1473 TreeFormalParameterList list = context.createFormalParameterList(parameter);1474 TreeFormalParameterList tail = list;1464 context.appendParameter(list, parameter); 1465 parameterCount++; 1475 1466 while (consume(COMMA)) { 1476 1467 parameter = parseDestructuringPattern(context, DestructureToParameters); 1477 1468 failIfFalse(parameter, "Cannot parse parameter pattern"); 1478 tail = context.createFormalParameterList(tail, parameter); 1479 } 1480 return list; 1469 context.appendParameter(list, parameter); 1470 parameterCount++; 1471 } 1472 return true; 1481 1473 } 1482 1474 1483 1475 template <typename LexerType> 1484 1476 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody( 1485 TreeBuilder& context, int functionKeywordStart, int functionNameStart, 1486 int parametersStart, ConstructorKind constructorKind, FunctionParseType parseType) 1487 { 1488 JSTokenLocation startLocation(tokenLocation()); 1489 unsigned startColumn = tokenColumn(); 1490 1491 if (parseType == StandardFunctionParseType) { 1477 TreeBuilder& context, const JSTokenLocation& startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart, 1478 ConstructorKind constructorKind, FunctionBodyType bodyType, unsigned parameterCount, FunctionParseMode parseMode) 1479 { 1480 if (bodyType == StandardFunctionBodyBlock || bodyType == ArrowFunctionBodyBlock) { 1492 1481 next(); 1493 1482 if (match(CLOSEBRACE)) { 1494 1483 unsigned endColumn = tokenColumn(); 1495 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind );1484 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, parameterCount, parseMode); 1496 1485 } 1497 1486 } … … 1499 1488 DepthManager statementDepth(&m_statementDepth); 1500 1489 m_statementDepth = 0; 1501 typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<VM*>(m_vm), m_lexer.get()); 1502 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1503 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, parseType), parseType == StandardFunctionParseType ? "Cannot parse body of this function" : "Cannot parse body of this arrow function"); 1504 #else 1505 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, StandardFunctionParseType), "Cannot parse body of this function"); 1506 #endif 1490 SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get()); 1491 if (bodyType == ArrowFunctionBodyExpression) 1492 failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(syntaxChecker), "Cannot parse body of this arrow function"); 1493 else 1494 failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function"); 1507 1495 unsigned endColumn = tokenColumn(); 1508 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind );1496 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, parameterCount, parseMode); 1509 1497 } 1510 1498 … … 1516 1504 case SetterMode: 1517 1505 return "setter"; 1518 case FunctionMode:1506 case NormalFunctionMode: 1519 1507 return "function"; 1520 1508 case MethodMode: 1521 1509 return "method"; 1522 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)1523 1510 case ArrowFunctionMode: 1524 1511 return "arrow function"; 1525 #endif 1512 case NotAFunctionMode: 1513 RELEASE_ASSERT_NOT_REACHED(); 1514 return ""; 1526 1515 } 1527 1516 RELEASE_ASSERT_NOT_REACHED(); … … 1529 1518 } 1530 1519 1531 template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, FunctionParseMode mode, ParserFunctionInfo<TreeBuilder>& info) 1532 { 1520 template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, FunctionParseMode mode, ParserFunctionInfo<TreeBuilder>& functionInfo) 1521 { 1522 RELEASE_ASSERT(mode != NotAFunctionMode); 1533 1523 int parametersStart = m_token.m_location.startOffset; 1534 1535 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1524 TreeFormalParameterList parameterList = context.createFormalParameterList(); 1525 functionInfo.parameters = parameterList; 1526 functionInfo.startOffset = parametersStart; 1527 1536 1528 if (mode == ArrowFunctionMode) { 1537 1529 if (!match(IDENT) && !match(OPENPAREN)) { … … 1542 1534 next(); 1543 1535 1544 if ( !match(CLOSEPAREN)) {1545 info.parameters = parseFormalParameters(context);1546 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));1547 }1536 if (match(CLOSEPAREN)) 1537 functionInfo.parameterCount = 0; 1538 else 1539 failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1548 1540 1549 1541 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration"); 1550 1542 } else { 1543 functionInfo.parameterCount = 1; 1551 1544 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1552 1545 failIfFalse(parameter, "Cannot parse parameter pattern"); 1553 info.parameters = context.createFormalParameterList(parameter); 1554 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1546 context.appendParameter(parameterList, parameter); 1555 1547 } 1556 1548 } 1557 1549 1558 1550 return parametersStart; 1559 1551 } 1560 #endif 1561 1552 1562 1553 if (!consume(OPENPAREN)) { 1563 1554 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); … … 1565 1556 } 1566 1557 1567 if (mode == GetterMode) 1558 if (mode == GetterMode) { 1568 1559 consumeOrFail(CLOSEPAREN, "getter functions must have no parameters"); 1569 else if (mode == SetterMode) { 1560 functionInfo.parameterCount = 0; 1561 } else if (mode == SetterMode) { 1570 1562 failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter"); 1571 1563 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1572 1564 failIfFalse(parameter, "setter functions must have one parameter"); 1573 info.parameters = context.createFormalParameterList(parameter); 1565 context.appendParameter(parameterList, parameter); 1566 functionInfo.parameterCount = 1; 1574 1567 failIfTrue(match(COMMA), "setter functions must have one parameter"); 1575 1568 consumeOrFail(CLOSEPAREN, "Expected a ')' after a parameter declaration"); 1576 1569 } else { 1577 if ( !match(CLOSEPAREN)) {1578 info.parameters = parseFormalParameters(context);1579 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));1580 }1570 if (match(CLOSEPAREN)) 1571 functionInfo.parameterCount = 0; 1572 else 1573 failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1581 1574 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration"); 1582 1575 } 1583 1576 1584 1577 return parametersStart; 1585 1578 } 1586 1579 1587 1580 template <typename LexerType> 1588 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& info, FunctionParseType parseType) 1589 { 1581 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, FunctionParseType parseType) 1582 { 1583 RELEASE_ASSERT(mode != NotAFunctionMode); 1584 1590 1585 AutoPopScopeRef functionScope(this, pushScope()); 1591 1586 functionScope->setIsFunction(); … … 1594 1589 m_lastFunctionName = nullptr; 1595 1590 int parametersStart; 1591 JSTokenLocation startLocation; 1592 int startColumn; 1593 FunctionBodyType functionBodyType; 1596 1594 1597 1595 switch (parseType) { 1598 1596 case StandardFunctionParseType: { 1597 RELEASE_ASSERT(mode != ArrowFunctionMode); 1599 1598 if (match(IDENT) || isLETMaskedAsIDENT()) { 1600 info.name = m_token.m_data.ident;1601 m_lastFunctionName = info.name;1599 functionInfo.name = m_token.m_data.ident; 1600 m_lastFunctionName = functionInfo.name; 1602 1601 next(); 1603 1602 if (!nameIsInContainingScope) 1604 failIfFalseIfStrict(functionScope->declareVariable( info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");1603 failIfFalseIfStrict(functionScope->declareVariable(functionInfo.name), "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 1605 1604 } else if (requirements == FunctionNeedsName) { 1606 if (match(OPENPAREN) && mode == FunctionMode)1605 if (match(OPENPAREN) && mode == NormalFunctionMode) 1607 1606 semanticFail("Function statements must have a name"); 1608 1607 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); … … 1610 1609 return false; 1611 1610 } 1612 1613 parametersStart = parseFunctionParameters(context, mode, info); 1611 1612 startLocation = tokenLocation(); 1613 functionInfo.startLine = tokenLine(); 1614 startColumn = tokenColumn(); 1615 1616 parametersStart = parseFunctionParameters(context, mode, functionInfo); 1614 1617 propagateError(); 1615 1618 … … 1623 1626 expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded; 1624 1627 } 1625 1626 info.startFunctionOffset = m_token.m_data.offset;1628 1629 functionBodyType = StandardFunctionBodyBlock; 1627 1630 1628 1631 break; … … 1630 1633 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1631 1634 case ArrowFunctionParseType: { 1632 parametersStart = parseFunctionParameters(context, ArrowFunctionMode, info); 1635 RELEASE_ASSERT(mode == ArrowFunctionMode); 1636 1637 startLocation = tokenLocation(); 1638 functionInfo.startLine = tokenLine(); 1639 startColumn = tokenColumn(); 1640 1641 parametersStart = parseFunctionParameters(context, mode, functionInfo); 1633 1642 propagateError(); 1634 1643 … … 1640 1649 ASSERT(constructorKind == ConstructorKind::None); 1641 1650 1642 info.arrowFunctionOffset = m_token.m_data.offset;1643 1651 // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function 1644 1652 // and we need use common approach to parse function body 1645 SavePoint savePoint = createSavePoint(); 1653 next(); 1654 functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression; 1646 1655 1647 next(); 1648 info.functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression; 1649 info.startFunctionOffset = (info.functionBodyType == ArrowFunctionBodyBlock) ? m_token.m_data.offset : info.arrowFunctionOffset; 1650 1651 restoreSavePoint(savePoint); 1652 1653 break; 1654 } 1656 break; 1657 } 1658 #else 1659 default: 1660 RELEASE_ASSERT_NOT_REACHED(); 1655 1661 #endif 1656 1662 } … … 1658 1664 bool isClassConstructor = constructorKind != ConstructorKind::None; 1659 1665 1660 info.bodyStartLine = tokenLine(); 1661 info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset; 1662 JSTokenLocation startLocation(tokenLocation()); 1666 functionInfo.bodyStartColumn = startColumn; 1663 1667 1664 1668 // If we know about this function already, we can use the cached info and skip the parser to the end of the function. 1665 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo( info.startFunctionOffset) : 0) {1669 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(functionInfo.startOffset) : 0) { 1666 1670 // If we're in a strict context, the cached function info must say it was strict too. 1667 1671 ASSERT(!strictMode() || cachedInfo->strictMode); … … 1672 1676 endLocation.lineStartOffset = cachedInfo->lastTockenLineStartOffset; 1673 1677 1674 bool endColumnIsOnStartLine = (endLocation.line == info.bodyStartLine);1678 bool endColumnIsOnStartLine = (endLocation.line == functionInfo.startLine); 1675 1679 ASSERT(endLocation.startOffset >= endLocation.lineStartOffset); 1676 1680 unsigned bodyEndColumn = endColumnIsOnStartLine ? … … 1679 1683 unsigned currentLineStartOffset = m_token.m_location.lineStartOffset; 1680 1684 1681 info.body = context.createFunctionBody(1682 startLocation, endLocation, info.bodyStartColumn, bodyEndColumn,1685 functionInfo.body = context.createFunctionBody( 1686 startLocation, endLocation, functionInfo.bodyStartColumn, bodyEndColumn, 1683 1687 functionKeywordStart, functionNameStart, parametersStart, 1684 cachedInfo->strictMode, constructorKind );1688 cachedInfo->strictMode, constructorKind, cachedInfo->parameterCount, mode); 1685 1689 1686 1690 functionScope->restoreFromSourceProviderCache(cachedInfo); … … 1694 1698 m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset); 1695 1699 m_lexer->setLineNumber(m_token.m_location.line); 1696 info.endFunctionOffset = cachedInfo->endFunctionOffset;1697 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1700 functionInfo.endOffset = cachedInfo->endFunctionOffset; 1701 1698 1702 if (parseType == ArrowFunctionParseType) 1699 info.functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;1703 functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock; 1700 1704 else 1701 info.functionBodyType = StandardFunctionBodyBlock;1705 functionBodyType = StandardFunctionBodyBlock; 1702 1706 1703 switch ( info.functionBodyType) {1707 switch (functionBodyType) { 1704 1708 case ArrowFunctionBodyExpression: 1705 1709 next(); 1706 context.setEndOffset( info.body, m_lexer->currentOffset());1710 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 1707 1711 break; 1708 1712 case ArrowFunctionBodyBlock: 1709 1713 case StandardFunctionBodyBlock: 1710 context.setEndOffset( info.body, m_lexer->currentOffset());1714 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 1711 1715 next(); 1712 1716 break; 1713 1717 } 1714 #else 1715 context.setEndOffset(info.body, m_lexer->currentOffset()); 1716 next(); 1717 #endif 1718 info.bodyEndLine = m_lastTokenEndPosition.line; 1718 functionInfo.endLine = m_lastTokenEndPosition.line; 1719 1719 return true; 1720 1720 } … … 1723 1723 ParserState oldState = saveState(); 1724 1724 1725 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1726 switch (info.functionBodyType) { 1727 case ArrowFunctionBodyBlock: { 1728 // Consume => in case of arrow function block e.g. x => { return x; } 1729 next(); 1730 1731 info.bodyStartLine = tokenLine(); 1732 info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset; 1733 1734 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType); 1735 break; 1736 } 1737 case StandardFunctionBodyBlock: 1738 case ArrowFunctionBodyExpression : { 1739 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, parseType); 1740 break; 1741 } 1742 } 1743 #else 1744 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType); 1745 #endif 1725 functionInfo.body = parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, functionBodyType, functionInfo.parameterCount, mode); 1746 1726 1747 1727 restoreState(oldState); 1748 failIfFalse( info.body, "Cannot parse the body of this ", stringForFunctionMode(mode));1749 context.setEndOffset( info.body, m_lexer->currentOffset());1750 if (functionScope->strictMode() && info.name) {1751 RELEASE_ASSERT(mode == FunctionMode || mode == MethodMode);1752 semanticFailIfTrue(m_vm->propertyNames->arguments == * info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");1753 semanticFailIfTrue(m_vm->propertyNames->eval == * info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");1728 failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); 1729 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 1730 if (functionScope->strictMode() && functionInfo.name) { 1731 RELEASE_ASSERT(mode == NormalFunctionMode || mode == MethodMode); 1732 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 1733 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 1754 1734 } 1755 1735 if (functionScope->hasDirectSuper()) { … … 1761 1741 1762 1742 JSTokenLocation location = JSTokenLocation(m_token.m_location); 1763 info.endFunctionOffset = m_token.m_data.offset; 1764 1765 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1766 if (info.functionBodyType == ArrowFunctionBodyExpression) { 1743 functionInfo.endOffset = m_token.m_data.offset; 1744 1745 if (functionBodyType == ArrowFunctionBodyExpression) { 1767 1746 location = locationBeforeLastToken(); 1768 info.endFunctionOffset = location.endOffset; 1769 } 1770 #endif 1747 functionInfo.endOffset = location.endOffset; 1748 } 1771 1749 1772 1750 // Cache the tokenizer state and the function scope the first time the function is parsed. … … 1774 1752 static const int minimumFunctionLengthToCache = 16; 1775 1753 std::unique_ptr<SourceProviderCacheItem> newInfo; 1776 int functionLength = info.endFunctionOffset - info.startFunctionOffset;1754 int functionLength = functionInfo.endOffset - functionInfo.startOffset; 1777 1755 if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) { 1778 1756 SourceProviderCacheItemCreationParameters parameters; 1779 parameters.endFunctionOffset = info.endFunctionOffset;1757 parameters.endFunctionOffset = functionInfo.endOffset; 1780 1758 parameters.functionNameStart = functionNameStart; 1781 1759 parameters.lastTockenLine = location.line; … … 1783 1761 parameters.lastTockenEndOffset = location.endOffset; 1784 1762 parameters.lastTockenLineStartOffset = location.lineStartOffset; 1785 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1786 if ( info.functionBodyType == ArrowFunctionBodyExpression) {1763 parameters.parameterCount = functionInfo.parameterCount; 1764 if (functionBodyType == ArrowFunctionBodyExpression) { 1787 1765 parameters.isBodyArrowExpression = true; 1788 1766 parameters.tokenType = m_token.m_type; 1789 1767 } 1790 #endif1791 1768 functionScope->fillParametersForSourceProviderCache(parameters); 1792 1769 newInfo = SourceProviderCacheItem::create(parameters); … … 1795 1772 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 1796 1773 1797 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1798 if (info.functionBodyType == ArrowFunctionBodyExpression) 1774 if (functionBodyType == ArrowFunctionBodyExpression) 1799 1775 failIfFalse(isEndOfArrowFunction(), "Expected the closing ';' ',' ']' ')' '}', line terminator or EOF after arrow function"); 1800 1776 else { … … 1802 1778 next(); 1803 1779 } 1804 #else1805 matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");1806 next();1807 #endif1808 1780 1809 1781 if (newInfo) 1810 m_functionCache->add( info.startFunctionOffset, WTF::move(newInfo));1811 1812 info.bodyEndLine = m_lastTokenEndPosition.line;1782 m_functionCache->add(functionInfo.startOffset, WTF::move(newInfo)); 1783 1784 functionInfo.endLine = m_lastTokenEndPosition.line; 1813 1785 return true; 1814 1786 } … … 1821 1793 unsigned functionKeywordStart = tokenStart(); 1822 1794 next(); 1823 ParserFunctionInfo<TreeBuilder> info;1824 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded,1825 functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse this function");1826 failIfFalse( info.name, "Function statements must have a name");1827 failIfFalseIfStrict(declareVariable( info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode");1828 return context.createFuncDeclStatement(location, info);1795 ParserFunctionInfo<TreeBuilder> functionInfo; 1796 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, NormalFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, 1797 functionKeywordStart, functionInfo, StandardFunctionParseType)), "Cannot parse this function"); 1798 failIfFalse(functionInfo.name, "Function statements must have a name"); 1799 failIfFalseIfStrict(declareVariable(functionInfo.name), "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode"); 1800 return context.createFuncDeclStatement(location, functionInfo); 1829 1801 } 1830 1802 … … 1940 1912 ParserFunctionInfo<TreeBuilder> methodInfo; 1941 1913 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 1942 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? FunctionMode : MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method");1914 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? NormalFunctionMode : MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 1943 1915 failIfFalse(ident && declareVariable(ident), "Cannot declare a method named '", methodInfo.name->impl(), "'"); 1944 1916 methodInfo.name = isConstructor ? className : ident; … … 2758 2730 ParserFunctionInfo<TreeBuilder> info; 2759 2731 info.name = &m_vm->propertyNames->nullIdentifier; 2760 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse function expression");2732 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, NormalFunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse function expression"); 2761 2733 return context.createFunctionExpr(location, info); 2762 2734 } … … 3003 2975 } 3004 2976 3005 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)3006 2977 template <typename LexerType> 3007 2978 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context) … … 3013 2984 ParserFunctionInfo<TreeBuilder> info; 3014 2985 info.name = &m_vm->propertyNames->nullIdentifier; 3015 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, ArrowFunctionParseType)), "Cannot parse arrow function expression");2986 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, ArrowFunctionParseType)), "Cannot parse arrow function expression"); 3016 2987 3017 2988 return context.createArrowFunctionExpr(location, info); 3018 2989 } 3019 #endif3020 2990 3021 2991 static const char* operatorString(bool prefix, unsigned tok)
Note:
See TracChangeset
for help on using the changeset viewer.