summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/parser
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/parser')
-rw-r--r--JavaScriptCore/parser/JSParser.cpp27
-rw-r--r--JavaScriptCore/parser/Nodes.h3
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; }