Changeset 178888 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jan 21, 2015, 10:39:31 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r178692 r178888 1274 1274 1275 1275 template <typename LexerType> 1276 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn)1276 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ParserFunctionInfo<TreeBuilder>& info) 1277 1277 { 1278 1278 AutoPopScopeRef functionScope(this, pushScope()); … … 1282 1282 m_lastFunctionName = nullptr; 1283 1283 if (match(IDENT)) { 1284 name = m_token.m_data.ident;1285 m_lastFunctionName = name;1284 info.name = m_token.m_data.ident; 1285 m_lastFunctionName = info.name; 1286 1286 next(); 1287 1287 if (!nameIsInContainingScope) 1288 failIfFalseIfStrict(functionScope->declareVariable( name), "'",name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");1288 failIfFalseIfStrict(functionScope->declareVariable(info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 1289 1289 } else if (requirements == FunctionNeedsName) { 1290 1290 if (match(OPENPAREN) && mode == FunctionMode) … … 1299 1299 } 1300 1300 if (!match(CLOSEPAREN)) { 1301 parameters = parseFormalParameters(context);1302 failIfFalse( parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));1301 info.parameters = parseFormalParameters(context); 1302 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1303 1303 } 1304 1304 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration"); 1305 1305 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); 1306 1306 1307 openBraceOffset = m_token.m_data.offset;1308 bodyStartLine = tokenLine();1309 bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;1307 info.openBraceOffset = m_token.m_data.offset; 1308 info.bodyStartLine = tokenLine(); 1309 info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset; 1310 1310 JSTokenLocation startLocation(tokenLocation()); 1311 1311 1312 1312 // If we know about this function already, we can use the cached info and skip the parser to the end of the function. 1313 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo( openBraceOffset) : 0) {1313 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(info.openBraceOffset) : 0) { 1314 1314 // If we're in a strict context, the cached function info must say it was strict too. 1315 1315 ASSERT(!strictMode() || cachedInfo->strictMode); … … 1320 1320 endLocation.lineStartOffset = cachedInfo->closeBraceLineStartOffset; 1321 1321 1322 bool endColumnIsOnStartLine = (endLocation.line == bodyStartLine);1322 bool endColumnIsOnStartLine = (endLocation.line == info.bodyStartLine); 1323 1323 ASSERT(endLocation.startOffset >= endLocation.lineStartOffset); 1324 1324 unsigned bodyEndColumn = endColumnIsOnStartLine ? … … 1327 1327 unsigned currentLineStartOffset = m_token.m_location.lineStartOffset; 1328 1328 1329 body = context.createFunctionBody(startLocation, endLocation,bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);1329 info.body = context.createFunctionBody(startLocation, endLocation, info.bodyStartColumn, bodyEndColumn, cachedInfo->strictMode); 1330 1330 1331 1331 functionScope->restoreFromSourceProviderCache(cachedInfo); 1332 1332 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error"); 1333 1333 1334 closeBraceOffset = cachedInfo->closeBraceOffset;1335 1336 context.setFunctionNameStart( body, functionNameStart);1334 info.closeBraceOffset = cachedInfo->closeBraceOffset; 1335 1336 context.setFunctionNameStart(info.body, functionNameStart); 1337 1337 m_token = cachedInfo->closeBraceToken(); 1338 1338 if (endColumnIsOnStartLine) … … 1342 1342 m_lexer->setLineNumber(m_token.m_location.line); 1343 1343 1344 context.setEndOffset( body, m_lexer->currentOffset());1344 context.setEndOffset(info.body, m_lexer->currentOffset()); 1345 1345 1346 1346 next(); 1347 info.bodyEndLine = m_lastTokenEndPosition.line; 1347 1348 return true; 1348 1349 } 1349 1350 m_lastFunctionName = lastFunctionName; 1350 1351 ParserState oldState = saveState(); 1351 body = parseFunctionBody(context);1352 info.body = parseFunctionBody(context); 1352 1353 restoreState(oldState); 1353 failIfFalse( body, "Cannot parse the body of this ", stringForFunctionMode(mode));1354 context.setEndOffset( body, m_lexer->currentOffset());1355 if (functionScope->strictMode() && name) {1354 failIfFalse(info.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); 1355 context.setEndOffset(info.body, m_lexer->currentOffset()); 1356 if (functionScope->strictMode() && info.name) { 1356 1357 RELEASE_ASSERT(mode == FunctionMode); 1357 semanticFailIfTrue(m_vm->propertyNames->arguments == * name, "'",name->impl(), "' is not a valid function name in strict mode");1358 semanticFailIfTrue(m_vm->propertyNames->eval == * name, "'",name->impl(), "' is not a valid function name in strict mode");1359 } 1360 closeBraceOffset = m_token.m_data.offset;1358 semanticFailIfTrue(m_vm->propertyNames->arguments == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode"); 1359 semanticFailIfTrue(m_vm->propertyNames->eval == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode"); 1360 } 1361 info.closeBraceOffset = m_token.m_data.offset; 1361 1362 unsigned closeBraceLine = m_token.m_data.line; 1362 1363 unsigned closeBraceLineStartOffset = m_token.m_data.lineStartOffset; … … 1366 1367 static const int minimumFunctionLengthToCache = 16; 1367 1368 std::unique_ptr<SourceProviderCacheItem> newInfo; 1368 int functionLength = closeBraceOffset -openBraceOffset;1369 int functionLength = info.closeBraceOffset - info.openBraceOffset; 1369 1370 if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) { 1370 1371 SourceProviderCacheItemCreationParameters parameters; 1371 1372 parameters.functionNameStart = functionNameStart; 1372 1373 parameters.closeBraceLine = closeBraceLine; 1373 parameters.closeBraceOffset = closeBraceOffset;1374 parameters.closeBraceOffset = info.closeBraceOffset; 1374 1375 parameters.closeBraceLineStartOffset = closeBraceLineStartOffset; 1375 1376 functionScope->fillParametersForSourceProviderCache(parameters); … … 1377 1378 1378 1379 } 1379 context.setFunctionNameStart( body, functionNameStart);1380 context.setFunctionNameStart(info.body, functionNameStart); 1380 1381 1381 1382 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error"); … … 1383 1384 1384 1385 if (newInfo) 1385 m_functionCache->add( openBraceOffset, WTF::move(newInfo));1386 m_functionCache->add(info.openBraceOffset, WTF::move(newInfo)); 1386 1387 1387 1388 next(); 1389 info.bodyEndLine = m_lastTokenEndPosition.line; 1388 1390 return true; 1389 1391 } … … 1396 1398 unsigned functionKeywordStart = tokenStart(); 1397 1399 next(); 1398 const Identifier* name = 0; 1399 TreeFormalParameterList parameters = 0; 1400 TreeFunctionBody body = 0; 1401 unsigned openBraceOffset = 0; 1402 unsigned closeBraceOffset = 0; 1403 int bodyStartLine = 0; 1404 unsigned bodyStartColumn = 0; 1405 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse this function"); 1406 failIfFalse(name, "Function statements must have a name"); 1407 failIfFalseIfStrict(declareVariable(name), "Cannot declare a function named '", name->impl(), "' in strict mode"); 1408 return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, functionKeywordStart); 1400 ParserFunctionInfo<TreeBuilder> info; 1401 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, info)), "Cannot parse this function"); 1402 failIfFalse(info.name, "Function statements must have a name"); 1403 failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode"); 1404 return context.createFuncDeclStatement(location, info, functionKeywordStart); 1409 1405 } 1410 1406 … … 1800 1796 } 1801 1797 failIfFalse(wasIdent, "Expected an identifier as property name"); 1802 const Identifier* accessorName = 0;1803 TreeFormalParameterList parameters = 0;1804 TreeFunctionBody body = 0;1805 unsigned openBraceOffset = 0;1806 unsigned closeBraceOffset = 0;1807 int bodyStartLine = 0;1808 unsigned bodyStartColumn = 0;1809 1798 PropertyNode::Type type; 1810 1799 if (*ident == m_vm->propertyNames->get) … … 1824 1813 JSTokenLocation location(tokenLocation()); 1825 1814 next(); 1815 ParserFunctionInfo<TreeBuilder> info; 1826 1816 if (type == PropertyNode::Getter) { 1827 1817 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 1828 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse getter definition");1818 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, info)), "Cannot parse getter definition"); 1829 1819 } else { 1830 1820 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 1831 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse setter definition");1821 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, info)), "Cannot parse setter definition"); 1832 1822 } 1833 1823 if (stringPropertyName) 1834 return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, getterOrSetterStartOffset);1835 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, complete, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, getterOrSetterStartOffset);1824 return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, info, getterOrSetterStartOffset); 1825 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, complete, numericPropertyName, info, getterOrSetterStartOffset); 1836 1826 } 1837 1827 case NUMBER: { … … 2173 2163 newCount++; 2174 2164 } 2175 2165 2176 2166 if (match(FUNCTION)) { 2177 const Identifier* name = &m_vm->propertyNames->nullIdentifier;2178 TreeFormalParameterList parameters = 0;2179 TreeFunctionBody body = 0;2180 unsigned openBraceOffset = 0;2181 unsigned closeBraceOffset = 0;2182 int bodyStartLine = 0;2183 unsigned bodyStartColumn = 0;2184 2167 unsigned functionKeywordStart = tokenStart(); 2185 2168 location = tokenLocation(); 2186 2169 next(); 2187 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse function expression"); 2188 base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, functionKeywordStart); 2170 ParserFunctionInfo<TreeBuilder> info; 2171 info.name = &m_vm->propertyNames->nullIdentifier; 2172 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, info)), "Cannot parse function expression"); 2173 base = context.createFunctionExpr(location, info, functionKeywordStart); 2189 2174 } else 2190 2175 base = parsePrimaryExpression(context);
Note:
See TracChangeset
for help on using the changeset viewer.