diff options
Diffstat (limited to 'JavaScriptCore/parser')
-rw-r--r-- | JavaScriptCore/parser/JSParser.cpp | 27 | ||||
-rw-r--r-- | JavaScriptCore/parser/Nodes.h | 3 |
2 files changed, 25 insertions, 5 deletions
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp index 540dc3b..0e526ac 100644 --- a/JavaScriptCore/parser/JSParser.cpp +++ b/JavaScriptCore/parser/JSParser.cpp @@ -204,6 +204,7 @@ private: Scope() : m_usesEval(false) , m_needsFullActivation(false) + , m_allowsNewDecls(true) { } @@ -212,6 +213,9 @@ private: m_declaredVariables.add(ident->ustring().impl()); } + void preventNewDecls() { m_allowsNewDecls = false; } + bool allowsNewDecls() const { return m_allowsNewDecls; } + void useVariable(const Identifier* ident, bool isEval) { m_usesEval |= isEval; @@ -249,6 +253,7 @@ private: private: bool m_usesEval; bool m_needsFullActivation; + bool m_allowsNewDecls; IdentifierSet m_declaredVariables; IdentifierSet m_usedVariables; IdentifierSet m_closedVariables; @@ -287,6 +292,17 @@ private: m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables); m_scopeStack.removeLast(); } + + void declareVariable(const Identifier* ident) + { + unsigned i = m_scopeStack.size() - 1; + ASSERT(i < m_scopeStack.size()); + while (!m_scopeStack[i].allowsNewDecls()) { + i--; + ASSERT(i < m_scopeStack.size()); + } + m_scopeStack[i].declareVariable(ident); + } ScopeStack m_scopeStack; }; @@ -425,7 +441,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr lastIdent = name; next(); bool hasInitializer = match(EQUAL); - currentScope()->declareVariable(name); + declareVariable(name); context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); if (hasInitializer) { int varDivot = tokenStart() + 1; @@ -457,7 +473,7 @@ template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationLi const Identifier* name = m_token.m_data.ident; next(); bool hasInitializer = match(EQUAL); - currentScope()->declareVariable(name); + declareVariable(name); context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0)); TreeExpression initializer = 0; if (hasInitializer) { @@ -759,6 +775,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild next(); ScopeRef catchScope = pushScope(); catchScope->declareVariable(ident); + catchScope->preventNewDecls(); consumeOrFail(CLOSEPAREN); matchOrFail(OPENBRACE); int initialEvalCount = context.evalCount(); @@ -862,7 +879,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame { matchOrFail(IDENT); usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident; - currentScope()->declareVariable(m_token.m_data.ident); + declareVariable(m_token.m_data.ident); TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident); TreeFormalParameterList tail = list; next(); @@ -870,7 +887,7 @@ template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParame next(); matchOrFail(IDENT); const Identifier* ident = m_token.m_data.ident; - currentScope()->declareVariable(ident); + declareVariable(ident); next(); usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident; tail = context.createFormalParameterList(tail, *ident); @@ -933,7 +950,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseFunctionDeclaration(Tr int bodyStartLine = 0; failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); failIfFalse(name); - currentScope()->declareVariable(name); + declareVariable(name); return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); } diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h index 2d8448c..fa61cdc 100644 --- a/JavaScriptCore/parser/Nodes.h +++ b/JavaScriptCore/parser/Nodes.h @@ -1412,8 +1412,11 @@ namespace JSC { bool usesArguments() const { return m_features & ArgumentsFeature; } void setUsesArguments() { m_features |= ArgumentsFeature; } bool usesThis() const { return m_features & ThisFeature; } + bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); } bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); } bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); } + size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); } + bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); } VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; } |