diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/parser/Parser.cpp | |
parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) | |
download | qtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore/parser/Parser.cpp')
-rw-r--r-- | Source/JavaScriptCore/parser/Parser.cpp | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp index 939d2696c..f58847fd2 100644 --- a/Source/JavaScriptCore/parser/Parser.cpp +++ b/Source/JavaScriptCore/parser/Parser.cpp @@ -62,11 +62,12 @@ Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, Fu m_lexer->setCode(source, m_arena); m_functionCache = source.provider()->cache(); - ScopeRef scope = pushScope(); - if (parserMode == JSParseFunctionCode) - scope->setIsFunction(); + ScopeFlags scopeFlags = NoScopeFlags; if (strictness == JSParseStrict) - scope->setStrictMode(); + scopeFlags |= StrictModeFlag; + if (parserMode == JSParseFunctionCode) + scopeFlags |= FunctionModeFlag; + ScopeRef scope = pushScope(scopeFlags); if (parameters) { for (unsigned i = 0; i < parameters->size(); i++) scope->declareParameter(¶meters->at(i)); @@ -96,16 +97,12 @@ UString Parser<LexerType>::parseInner() IdentifierSet capturedVariables; scope->getCapturedVariables(capturedVariables); - CodeFeatures features = context.features(); - if (scope->strictMode()) - features |= StrictModeFeature; - if (scope->shadowsArguments()) - features |= ShadowsArgumentsFeature; + ScopeFlags scopeFlags = scope->modeFlags() | scope->usesFlags(); unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0; if (functionCacheSize != oldFunctionCacheSize) m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize); - didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features, + didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), scopeFlags, m_lastLine, context.numConstants(), capturedVariables); return parseError; @@ -113,13 +110,13 @@ UString Parser<LexerType>::parseInner() template <typename LexerType> void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, - ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars) + ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, ScopeFlags scopeFlags, int lastLine, int numConstants, IdentifierSet& capturedVars) { m_sourceElements = sourceElements; m_varDeclarations = varStack; m_funcDeclarations = funcStack; m_capturedVariables.swap(capturedVars); - m_features = features; + m_scopeFlags = scopeFlags; m_lastLine = lastLine; m_numConstants = numConstants; } @@ -147,7 +144,7 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser< if (directive) { // "use strict" must be the exact literal without escape sequences or line continuation. if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) { - setStrictMode(); + currentScope()->setFlags(StrictModeFlag); hasSetStrict = true; failIfFalse(isValidStrictMode()); m_lexer->setOffset(startOffset); @@ -255,6 +252,8 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati next(); bool hasInitializer = match(EQUAL); failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode."); + if (m_globalData->propertyNames->arguments == *name) + currentScope()->setFlags(UsesArgumentsFlag); context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); if (hasInitializer) { int varDivot = tokenStart() + 1; @@ -289,6 +288,8 @@ template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDecl next(); bool hasInitializer = match(EQUAL); declareVariable(name); + if (m_globalData->propertyNames->arguments == *name) + currentScope()->setFlags(UsesArgumentsFlag); context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0)); TreeExpression initializer = 0; if (hasInitializer) { @@ -511,7 +512,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement { ASSERT(match(WITH)); failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode"); - currentScope()->setNeedsFullActivation(); + currentScope()->setFlags(UsesWithFlag); int startLine = tokenLine(); next(); consumeOrFail(OPENPAREN); @@ -526,6 +527,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement TreeStatement statement = parseStatement(context, unused); failIfFalse(statement); + currentScope()->setFlags(UsesWithFlag); return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine); } @@ -614,15 +616,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement( int lastLine = m_lastLine; if (match(CATCH)) { - currentScope()->setNeedsFullActivation(); + currentScope()->setFlags(UsesCatchFlag); next(); consumeOrFail(OPENPAREN); matchOrFail(IDENT); ident = m_token.m_data.ident; next(); - AutoPopScopeRef catchScope(this, pushScope()); + AutoPopScopeRef catchScope(this, pushScope(currentScope()->modeFlags())); failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode"); - catchScope->preventNewDecls(); + currentScope()->setFlags(BlockScopeFlag | UsesCatchFlag); consumeOrFail(CLOSEPAREN); matchOrFail(OPENBRACE); catchBlock = parseBlockStatement(context); @@ -759,7 +761,7 @@ template <typename LexerType> template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context) { if (match(CLOSEBRACE)) - return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode()); + return context.createFunctionBody(m_lexer->lastLineNumber(), currentScope()->modeFlags()); DepthManager statementDepth(&m_statementDepth); m_statementDepth = 0; typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get()); @@ -770,8 +772,7 @@ template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBo template <typename LexerType> template <FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine) { - AutoPopScopeRef functionScope(this, pushScope()); - functionScope->setIsFunction(); + AutoPopScopeRef functionScope(this, pushScope(currentScope()->modeFlags() | FunctionModeFlag)); if (match(IDENT)) { name = m_token.m_data.ident; next(); @@ -793,8 +794,8 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class // If we know about this function already, we can use the cached info and skip the parser to the end of the function. if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) { // If we're in a strict context, the cached function info must say it was strict too. - ASSERT(!strictMode() || cachedInfo->strictMode); - body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode); + ASSERT(!strictMode() || (cachedInfo->scopeFlags & StrictModeFlag)); + body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->scopeFlags); functionScope->restoreFunctionInfo(cachedInfo); failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo)); @@ -854,6 +855,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); failIfFalse(name); failIfFalseIfStrict(declareVariable(name)); + if (*name == m_globalData->propertyNames->arguments) + currentScope()->setFlags(UsesArgumentsFlag); return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); } @@ -1204,7 +1207,6 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars return context.template createProperty<complete>(ident, node, PropertyNode::Constant); } failIfFalse(wasIdent); - matchOrFail(IDENT); const Identifier* accessorName = 0; TreeFormalParameterList parameters = 0; TreeFunctionBody body = 0; @@ -1218,8 +1220,19 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars type = PropertyNode::Setter; else fail(); - failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine))); - return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); + const Identifier* stringPropertyName = 0; + double numericPropertyName = 0; + if (m_token.m_type == IDENT || m_token.m_type == STRING) + stringPropertyName = m_token.m_data.ident; + else if (m_token.m_type == NUMBER) + numericPropertyName = m_token.m_data.doubleValue; + else + fail(); + next(); + failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine))); + if (stringPropertyName) + return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, stringPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); + return context.template createGetterOrSetterProperty<complete>(const_cast<JSGlobalData*>(m_globalData), m_lexer->lastLineNumber(), type, numericPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); } case NUMBER: { double propertyName = m_token.m_data.doubleValue; @@ -1391,13 +1404,18 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre } case THISTOKEN: { next(); + currentScope()->setFlags(UsesThisFlag); return context.thisExpr(m_lexer->lastLineNumber()); } case IDENT: { int start = tokenStart(); const Identifier* ident = m_token.m_data.ident; next(); - currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident); + if (m_globalData->propertyNames->eval == *ident) + currentScope()->setFlags(UsesEvalFlag); + else if (m_globalData->propertyNames->arguments == *ident) + currentScope()->setFlags(UsesArgumentsFlag); + currentScope()->useVariable(ident); m_lastIdentifier = ident; return context.createResolve(m_lexer->lastLineNumber(), ident, start); } |