summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser/Parser.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
commitdd91e772430dc294e3bf478c119ef8d43c0a3358 (patch)
tree6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/parser/Parser.cpp
parentad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff)
downloadqtwebkit-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.cpp70
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(&parameters->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);
}