summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-11 09:43:24 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-11 09:43:24 +0200
commit1b914638db989aaa98631a1c1e02c7b2d44805d8 (patch)
tree87f4fd2c7b38db320079a5de8877890d2ca3c485 /Source/JavaScriptCore/parser
parent2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (diff)
downloadqtwebkit-1b914638db989aaa98631a1c1e02c7b2d44805d8.tar.gz
Imported WebKit commit 9a52e27980f47e8b0d8f8b7cc0fd7b5741bceb92 (http://svn.webkit.org/repository/webkit/trunk@116736)
New snapshot to include QDeclarative* -> QQml* build fixes
Diffstat (limited to 'Source/JavaScriptCore/parser')
-rw-r--r--Source/JavaScriptCore/parser/ASTBuilder.h44
-rw-r--r--Source/JavaScriptCore/parser/NodeInfo.h4
-rw-r--r--Source/JavaScriptCore/parser/Nodes.cpp40
-rw-r--r--Source/JavaScriptCore/parser/Nodes.h88
-rw-r--r--Source/JavaScriptCore/parser/Parser.cpp54
-rw-r--r--Source/JavaScriptCore/parser/Parser.h118
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCacheItem.h4
-rw-r--r--Source/JavaScriptCore/parser/SyntaxChecker.h1
8 files changed, 200 insertions, 153 deletions
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index a173cc10f..0eb60cf89 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -77,6 +77,7 @@ public:
: m_globalData(globalData)
, m_sourceCode(sourceCode)
, m_scope(globalData)
+ , m_evalCount(0)
{
}
@@ -118,6 +119,7 @@ public:
ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
+ int features() const { return m_scope.m_features; }
int numConstants() const { return m_scope.m_numConstants; }
void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
@@ -150,8 +152,17 @@ public:
incConstants();
return new (m_globalData) VoidNode(lineNumber, expr);
}
- ExpressionNode* thisExpr(int lineNumber) { return new (m_globalData) ThisNode(lineNumber); }
- ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start) { return new (m_globalData) ResolveNode(lineNumber, *ident, start); }
+ ExpressionNode* thisExpr(int lineNumber)
+ {
+ usesThis();
+ return new (m_globalData) ThisNode(lineNumber);
+ }
+ ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start)
+ {
+ if (m_globalData->propertyNames->arguments == *ident)
+ usesArguments();
+ return new (m_globalData) ResolveNode(lineNumber, *ident, start);
+ }
ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); }
ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); }
@@ -252,9 +263,9 @@ public:
return result;
}
- FunctionBodyNode* createFunctionBody(int lineNumber, ScopeFlags scopeFlags)
+ FunctionBodyNode* createFunctionBody(int lineNumber, bool inStrictContext)
{
- return FunctionBodyNode::create(m_globalData, lineNumber, scopeFlags);
+ return FunctionBodyNode::create(m_globalData, lineNumber, inStrictContext);
}
template <bool> PropertyNode* createGetterOrSetterProperty(int lineNumber, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
@@ -301,6 +312,8 @@ public:
StatementNode* createFuncDeclStatement(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
FuncDeclNode* decl = new (m_globalData) FuncDeclNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
+ if (*name == m_globalData->propertyNames->arguments)
+ usesArguments();
m_scope.m_funcDeclarations->data.append(decl->body());
body->setLoc(bodyStartLine, bodyEndLine);
return decl;
@@ -413,6 +426,8 @@ public:
StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
{
TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
+ if (catchBlock)
+ usesCatch();
result->setLoc(startLine, endLine);
return result;
}
@@ -448,6 +463,7 @@ public:
StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
{
+ usesWith();
WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start);
result->setLoc(startLine, endLine);
return result;
@@ -490,6 +506,8 @@ public:
void addVar(const Identifier* ident, int attrs)
{
+ if (m_globalData->propertyNames->arguments == *ident)
+ usesArguments();
m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
}
@@ -504,6 +522,8 @@ public:
return new (m_globalData) CommaNode(lineNumber, list, init);
}
+ int evalCount() const { return m_evalCount; }
+
void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
{
operandStackDepth++;
@@ -590,11 +610,13 @@ private:
Scope(JSGlobalData* globalData)
: m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
, m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
+ , m_features(0)
, m_numConstants(0)
{
}
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
+ int m_features;
int m_numConstants;
};
@@ -604,6 +626,15 @@ private:
}
void incConstants() { m_scope.m_numConstants++; }
+ void usesThis() { m_scope.m_features |= ThisFeature; }
+ void usesCatch() { m_scope.m_features |= CatchFeature; }
+ void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
+ void usesWith() { m_scope.m_features |= WithFeature; }
+ void usesEval()
+ {
+ m_evalCount++;
+ m_scope.m_features |= EvalFeature;
+ }
ExpressionNode* createNumber(int lineNumber, double d)
{
return new (m_globalData) NumberNode(lineNumber, d);
@@ -616,6 +647,7 @@ private:
Vector<AssignmentInfo, 10> m_assignmentInfoStack;
Vector<pair<int, int>, 10> m_binaryOperatorStack;
Vector<pair<int, int>, 10> m_unaryTokenStack;
+ int m_evalCount;
};
ExpressionNode* ASTBuilder::makeTypeOfNode(int lineNumber, ExpressionNode* expr)
@@ -765,8 +797,10 @@ ExpressionNode* ASTBuilder::makeFunctionCallNode(int lineNumber, ExpressionNode*
if (func->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(func);
const Identifier& identifier = resolve->identifier();
- if (identifier == m_globalData->propertyNames->eval)
+ if (identifier == m_globalData->propertyNames->eval) {
+ usesEval();
return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot);
+ }
return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot);
}
if (func->isBracketAccessorNode()) {
diff --git a/Source/JavaScriptCore/parser/NodeInfo.h b/Source/JavaScriptCore/parser/NodeInfo.h
index e0d4ffec4..4853aec42 100644
--- a/Source/JavaScriptCore/parser/NodeInfo.h
+++ b/Source/JavaScriptCore/parser/NodeInfo.h
@@ -26,7 +26,7 @@ namespace JSC {
template <typename T> struct NodeInfo {
T m_node;
- ScopeFlags m_scopeFlags;
+ CodeFeatures m_features;
int m_numConstants;
};
@@ -44,7 +44,7 @@ namespace JSC {
T m_node;
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
- ScopeFlags m_scopeFlags;
+ CodeFeatures m_features;
int m_numConstants;
};
diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index 75c848bce..c32e4c73a 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -75,19 +75,19 @@ StatementNode* SourceElements::singleStatement() const
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
+ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
- , m_scopeFlags(scopeFlags)
+ , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
, m_numConstants(0)
, m_statements(0)
{
}
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, ScopeFlags scopeFlags, int numConstants)
+ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
- , m_scopeFlags(scopeFlags)
+ , m_features(features)
, m_source(source)
, m_numConstants(numConstants)
, m_statements(children)
@@ -107,14 +107,14 @@ StatementNode* ScopeNode::singleStatement() const
// ------------------------------ ProgramNode -----------------------------
-inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
+inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, scopeFlags, numConstants);
+ RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -125,14 +125,14 @@ PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNu
// ------------------------------ EvalNode -----------------------------
-inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
+inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, scopeFlags, numConstants);
+ RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -149,13 +149,13 @@ FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
append(parameter->ident());
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
- : ScopeNode(globalData, lineNumber, scopeFlags)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
+ : ScopeNode(globalData, lineNumber, inStrictContext)
{
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
- : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
@@ -172,14 +172,14 @@ void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters,
m_ident = ident;
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
{
- return new FunctionBodyNode(globalData, lineNumber, scopeFlags);
+ return new FunctionBodyNode(globalData, lineNumber, inStrictContext);
}
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
{
- RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, scopeFlags, numConstants);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index f752b91e9..26c829da6 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -47,31 +47,19 @@ namespace JSC {
class ScopeChainNode;
class ScopeNode;
- typedef unsigned short ScopeFlags;
-
- const ScopeFlags NoScopeFlags = 0;
-
- // Some scope flags propagate down the parse tree from parent scopes, like
- // strict mode. They are modal to an entire set of nested scopes.
- const ScopeFlags StrictModeFlag = 1 << 0;
- const ScopeFlags FunctionModeFlag = 1 << 1;
- const ScopeFlags AllScopeModeFlags = StrictModeFlag | FunctionModeFlag;
-
- // Some scope flags refer only to a specific scope, and don't propagate down
- // or up.
- const ScopeFlags BlockScopeFlag = 1 << 4;
- const ScopeFlags AllScopeKindFlags = BlockScopeFlag;
-
- // Other flags reflect uses within nested scopes, and so propagate up
- // from the leaves.
- const ScopeFlags UsesEvalFlag = 1 << 8;
- const ScopeFlags UsesArgumentsFlag = 1 << 9;
- const ScopeFlags UsesWithFlag = 1 << 10;
- const ScopeFlags UsesCatchFlag = 1 << 11;
- const ScopeFlags UsesThisFlag = 1 << 12;
- const ScopeFlags ShadowsArgumentsFlag = 1 << 13;
- const ScopeFlags AllScopeUsesFlags = UsesEvalFlag | UsesArgumentsFlag | UsesWithFlag | UsesCatchFlag | UsesThisFlag | ShadowsArgumentsFlag;
+ typedef unsigned CodeFeatures;
+
+ const CodeFeatures NoFeatures = 0;
+ const CodeFeatures EvalFeature = 1 << 0;
+ const CodeFeatures ArgumentsFeature = 1 << 1;
+ const CodeFeatures WithFeature = 1 << 2;
+ const CodeFeatures CatchFeature = 1 << 3;
+ const CodeFeatures ThisFeature = 1 << 4;
+ const CodeFeatures StrictModeFeature = 1 << 5;
+ const CodeFeatures ShadowsArgumentsFeature = 1 << 6;
+ const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
+
enum Operator {
OpEqual,
OpPlusEq,
@@ -1395,8 +1383,8 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*, int, ScopeFlags);
- ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, ScopeFlags, int numConstants);
+ ScopeNode(JSGlobalData*, int, bool inStrictContext);
+ ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
@@ -1409,26 +1397,24 @@ namespace JSC {
m_capturedVariables.clear();
}
- bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
- size_t capturedVariableCount() const { return m_capturedVariables.size(); }
- bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
-
- void addScopeFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
- ScopeFlags scopeFlags() const { return m_scopeFlags; }
-
- bool isStrictMode() const { return m_scopeFlags & StrictModeFlag; }
- bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
- bool usesArguments() const { return (m_scopeFlags & UsesArgumentsFlag) && !(m_scopeFlags & ShadowsArgumentsFlag); }
- void setUsesArguments() { m_scopeFlags |= UsesArgumentsFlag; }
- bool usesThis() const { return m_scopeFlags & UsesThisFlag; }
-
- bool needsActivationForMoreThanVariables() const { return m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); }
- bool needsActivation() const { return hasCapturedVariables() || needsActivationForMoreThanVariables(); }
-
const SourceCode& source() const { return m_source; }
const UString& sourceURL() const { return m_source.provider()->url(); }
intptr_t sourceID() const { return m_source.provider()->asID(); }
+ void setFeatures(CodeFeatures features) { m_features = features; }
+ CodeFeatures features() { return m_features; }
+
+ bool usesEval() const { return m_features & EvalFeature; }
+ bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
+ void setUsesArguments() { m_features |= ArgumentsFeature; }
+ bool usesThis() const { return m_features & ThisFeature; }
+ bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+ bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+
VarStack& varStack() { return m_varStack; }
FunctionStack& functionStack() { return m_functionStack; }
@@ -1448,7 +1434,7 @@ namespace JSC {
ParserArena m_arena;
private:
- ScopeFlags m_scopeFlags;
+ CodeFeatures m_features;
SourceCode m_source;
VarStack m_varStack;
FunctionStack m_functionStack;
@@ -1460,12 +1446,12 @@ namespace JSC {
class ProgramNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1473,12 +1459,12 @@ namespace JSC {
class EvalNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1495,8 +1481,8 @@ namespace JSC {
class FunctionBodyNode : public ScopeNode {
public:
static const bool isFunctionNode = true;
- static FunctionBodyNode* create(JSGlobalData*, int, ScopeFlags);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ static FunctionBodyNode* create(JSGlobalData*, int, bool isStrictMode);
+ static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
@@ -1513,8 +1499,8 @@ namespace JSC {
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*, int, ScopeFlags);
- FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
+ FunctionBodyNode(JSGlobalData*, int, bool inStrictContext);
+ FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
Identifier m_inferredName;
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index a03af24df..d88a9a8b7 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -62,12 +62,11 @@ Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, Fu
m_lexer->setCode(source, m_arena);
m_functionCache = source.provider()->cache();
- ScopeFlags scopeFlags = NoScopeFlags;
- if (strictness == JSParseStrict)
- scopeFlags |= StrictModeFlag;
+ ScopeRef scope = pushScope();
if (parserMode == JSParseFunctionCode)
- scopeFlags |= FunctionModeFlag;
- ScopeRef scope = pushScope(scopeFlags);
+ scope->setIsFunction();
+ if (strictness == JSParseStrict)
+ scope->setStrictMode();
if (parameters) {
for (unsigned i = 0; i < parameters->size(); i++)
scope->declareParameter(&parameters->at(i));
@@ -97,12 +96,16 @@ UString Parser<LexerType>::parseInner()
IdentifierSet capturedVariables;
scope->getCapturedVariables(capturedVariables);
- ScopeFlags scopeFlags = scope->modeFlags() | scope->usesFlags();
+ CodeFeatures features = context.features();
+ if (scope->strictMode())
+ features |= StrictModeFeature;
+ if (scope->shadowsArguments())
+ features |= ShadowsArgumentsFeature;
unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
if (functionCacheSize != oldFunctionCacheSize)
m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize);
- didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), scopeFlags,
+ didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
m_lastLine, context.numConstants(), capturedVariables);
return parseError;
@@ -110,13 +113,13 @@ UString Parser<LexerType>::parseInner()
template <typename LexerType>
void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
- ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, ScopeFlags scopeFlags, int lastLine, int numConstants, IdentifierSet& capturedVars)
+ ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
{
m_sourceElements = sourceElements;
m_varDeclarations = varStack;
m_funcDeclarations = funcStack;
m_capturedVariables.swap(capturedVars);
- m_scopeFlags = scopeFlags;
+ m_features = features;
m_lastLine = lastLine;
m_numConstants = numConstants;
}
@@ -144,7 +147,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) {
- currentScope()->setFlags(StrictModeFlag);
+ setStrictMode();
hasSetStrict = true;
failIfFalse(isValidStrictMode());
m_lexer->setOffset(startOffset);
@@ -252,8 +255,6 @@ 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;
@@ -288,8 +289,6 @@ 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) {
@@ -512,7 +511,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement
{
ASSERT(match(WITH));
failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode");
- currentScope()->setFlags(UsesWithFlag);
+ currentScope()->setNeedsFullActivation();
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -527,7 +526,6 @@ 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);
}
@@ -616,15 +614,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(
int lastLine = m_lastLine;
if (match(CATCH)) {
- currentScope()->setFlags(UsesCatchFlag);
+ currentScope()->setNeedsFullActivation();
next();
consumeOrFail(OPENPAREN);
matchOrFail(IDENT);
ident = m_token.m_data.ident;
next();
- AutoPopScopeRef catchScope(this, pushScope(currentScope()->modeFlags()));
+ AutoPopScopeRef catchScope(this, pushScope());
failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode");
- currentScope()->setFlags(BlockScopeFlag | UsesCatchFlag);
+ catchScope->preventNewDecls();
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
catchBlock = parseBlockStatement(context);
@@ -761,7 +759,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
{
if (match(CLOSEBRACE))
- return context.createFunctionBody(m_lexer->lastLineNumber(), currentScope()->modeFlags());
+ return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
DepthManager statementDepth(&m_statementDepth);
m_statementDepth = 0;
typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
@@ -772,7 +770,8 @@ 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(currentScope()->modeFlags() | FunctionModeFlag));
+ AutoPopScopeRef functionScope(this, pushScope());
+ functionScope->setIsFunction();
if (match(IDENT)) {
name = m_token.m_data.ident;
next();
@@ -794,8 +793,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->scopeFlags & StrictModeFlag));
- body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->scopeFlags);
+ ASSERT(!strictMode() || cachedInfo->strictMode);
+ body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
functionScope->restoreFunctionInfo(cachedInfo);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
@@ -855,8 +854,6 @@ 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);
}
@@ -1416,18 +1413,13 @@ 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();
- if (m_globalData->propertyNames->eval == *ident)
- currentScope()->setFlags(UsesEvalFlag);
- else if (m_globalData->propertyNames->arguments == *ident)
- currentScope()->setFlags(UsesArgumentsFlag);
- currentScope()->useVariable(ident);
+ currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
m_lastIdentifier = ident;
return context.createResolve(m_lexer->lastLineNumber(), ident, start);
}
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index c0b13c53a..c2a11d665 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -130,19 +130,30 @@ struct ScopeLabelInfo {
};
struct Scope {
- Scope(const JSGlobalData* globalData, ScopeFlags scopeFlags)
+ Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode)
: m_globalData(globalData)
- , m_scopeFlags(scopeFlags)
+ , m_shadowsArguments(false)
+ , m_usesEval(false)
+ , m_needsFullActivation(false)
+ , m_allowsNewDecls(true)
+ , m_strictMode(strictMode)
+ , m_isFunction(isFunction)
+ , m_isFunctionBoundary(false)
, m_isValidStrictMode(true)
, m_loopDepth(0)
, m_switchDepth(0)
{
- ASSERT(!(scopeFlags & ~AllScopeModeFlags));
}
Scope(const Scope& rhs)
: m_globalData(rhs.m_globalData)
- , m_scopeFlags(rhs.m_scopeFlags)
+ , m_shadowsArguments(rhs.m_shadowsArguments)
+ , m_usesEval(rhs.m_usesEval)
+ , m_needsFullActivation(rhs.m_needsFullActivation)
+ , m_allowsNewDecls(rhs.m_allowsNewDecls)
+ , m_strictMode(rhs.m_strictMode)
+ , m_isFunction(rhs.m_isFunction)
+ , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
, m_isValidStrictMode(rhs.m_isValidStrictMode)
, m_loopDepth(rhs.m_loopDepth)
, m_switchDepth(rhs.m_switchDepth)
@@ -157,22 +168,6 @@ struct Scope {
}
}
- ALWAYS_INLINE ScopeFlags scopeFlags() const { return m_scopeFlags; }
- ALWAYS_INLINE ScopeFlags modeFlags() const { return m_scopeFlags & AllScopeModeFlags; }
- ALWAYS_INLINE ScopeFlags usesFlags() const { return m_scopeFlags & AllScopeUsesFlags; }
- ALWAYS_INLINE void setFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
-
- ALWAYS_INLINE bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
- ALWAYS_INLINE bool strictMode() const { return m_scopeFlags & StrictModeFlag; }
- ALWAYS_INLINE bool shadowsArguments() const { return m_scopeFlags & ShadowsArgumentsFlag; }
- ALWAYS_INLINE bool isFunction() const { return m_scopeFlags & FunctionModeFlag; }
- ALWAYS_INLINE bool isBlockScope() const { return m_scopeFlags & BlockScopeFlag; }
- ALWAYS_INLINE bool isFunctionBoundary() const { return isFunction() && !isBlockScope(); }
-
- ALWAYS_INLINE bool allowsNewDecls() const { return !isBlockScope(); }
-
- ALWAYS_INLINE bool isValidStrictMode() const { return m_isValidStrictMode; }
-
void startSwitch() { m_switchDepth++; }
void endSwitch() { m_switchDepth--; }
void startLoop() { m_loopDepth++; }
@@ -206,6 +201,14 @@ struct Scope {
return 0;
}
+ void setIsFunction()
+ {
+ m_isFunction = true;
+ m_isFunctionBoundary = true;
+ }
+ bool isFunction() { return m_isFunction; }
+ bool isFunctionBoundary() { return m_isFunctionBoundary; }
+
bool declareVariable(const Identifier* ident)
{
bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
@@ -216,28 +219,35 @@ struct Scope {
void declareWrite(const Identifier* ident)
{
- ASSERT(strictMode());
+ ASSERT(m_strictMode);
m_writtenVariables.add(ident->impl());
}
+ void preventNewDecls() { m_allowsNewDecls = false; }
+ bool allowsNewDecls() const { return m_allowsNewDecls; }
+
bool declareParameter(const Identifier* ident)
{
bool isArguments = m_globalData->propertyNames->arguments == *ident;
bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).isNewEntry && m_globalData->propertyNames->eval != *ident && !isArguments;
m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
if (isArguments)
- setFlags(ShadowsArgumentsFlag);
+ m_shadowsArguments = true;
return isValidStrictMode;
}
- void useVariable(const Identifier* ident)
+ void useVariable(const Identifier* ident, bool isEval)
{
+ m_usesEval |= isEval;
m_usedVariables.add(ident->ustring().impl());
}
+ void setNeedsFullActivation() { m_needsFullActivation = true; }
+
bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
{
- setFlags(nestedScope->usesFlags());
+ if (nestedScope->m_usesEval)
+ m_usesEval = true;
IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
if (nestedScope->m_declaredVariables.contains(*ptr))
@@ -269,7 +279,7 @@ struct Scope {
void getCapturedVariables(IdentifierSet& capturedVariables)
{
- if (usesEval()) {
+ if (m_needsFullActivation || m_usesEval) {
capturedVariables.swap(m_declaredVariables);
return;
}
@@ -279,6 +289,11 @@ struct Scope {
capturedVariables.add(*ptr);
}
}
+ void setStrictMode() { m_strictMode = true; }
+ bool strictMode() const { return m_strictMode; }
+ bool isValidStrictMode() const { return m_isValidStrictMode; }
+ bool shadowsArguments() const { return m_shadowsArguments; }
+
void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector)
{
IdentifierSet::iterator end = capturedVariables.end();
@@ -292,16 +307,20 @@ struct Scope {
void saveFunctionInfo(SourceProviderCacheItem* info)
{
- ASSERT(isFunction());
- info->scopeFlags = m_scopeFlags;
+ ASSERT(m_isFunction);
+ info->usesEval = m_usesEval;
+ info->strictMode = m_strictMode;
+ info->needsFullActivation = m_needsFullActivation;
copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
}
void restoreFunctionInfo(const SourceProviderCacheItem* info)
{
- ASSERT(isFunction());
- m_scopeFlags |= info->scopeFlags;
+ ASSERT(m_isFunction);
+ m_usesEval = info->usesEval;
+ m_strictMode = info->strictMode;
+ m_needsFullActivation = info->needsFullActivation;
unsigned size = info->usedVariables.size();
for (unsigned i = 0; i < size; ++i)
m_usedVariables.add(info->usedVariables[i]);
@@ -312,7 +331,13 @@ struct Scope {
private:
const JSGlobalData* m_globalData;
- ScopeFlags m_scopeFlags;
+ bool m_shadowsArguments : 1;
+ bool m_usesEval : 1;
+ bool m_needsFullActivation : 1;
+ bool m_allowsNewDecls : 1;
+ bool m_strictMode : 1;
+ bool m_isFunction : 1;
+ bool m_isFunctionBoundary : 1;
bool m_isValidStrictMode : 1;
int m_loopDepth;
int m_switchDepth;
@@ -402,14 +427,20 @@ private:
Parser* m_parser;
};
- ALWAYS_INLINE ScopeRef currentScope()
+ ScopeRef currentScope()
{
return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
}
- ScopeRef pushScope(ScopeFlags scopeFlags)
+ ScopeRef pushScope()
{
- m_scopeStack.append(Scope(m_globalData, scopeFlags));
+ bool isFunction = false;
+ bool isStrict = false;
+ if (!m_scopeStack.isEmpty()) {
+ isStrict = m_scopeStack.last().strictMode();
+ isFunction = m_scopeStack.last().isFunction();
+ }
+ m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
return currentScope();
}
@@ -461,7 +492,7 @@ private:
UString parseInner();
void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
- ParserArenaData<DeclarationStacks::FunctionStack>*, ScopeFlags,
+ ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures,
int, int, IdentifierSet&);
// Used to determine type of error to report.
@@ -792,13 +823,14 @@ private:
m_errorMessage = UString(msg);
}
- ALWAYS_INLINE void startLoop() { currentScope()->startLoop(); }
- ALWAYS_INLINE void endLoop() { currentScope()->endLoop(); }
- ALWAYS_INLINE void startSwitch() { currentScope()->startSwitch(); }
- ALWAYS_INLINE void endSwitch() { currentScope()->endSwitch(); }
- ALWAYS_INLINE bool strictMode() { return currentScope()->strictMode(); }
- ALWAYS_INLINE bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
- ALWAYS_INLINE bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
+ void startLoop() { currentScope()->startLoop(); }
+ void endLoop() { currentScope()->endLoop(); }
+ void startSwitch() { currentScope()->startSwitch(); }
+ void endSwitch() { currentScope()->endSwitch(); }
+ void setStrictMode() { currentScope()->setStrictMode(); }
+ bool strictMode() { return currentScope()->strictMode(); }
+ bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
+ bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
bool breakIsValid()
{
ScopeRef current = currentScope();
@@ -917,7 +949,7 @@ private:
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
IdentifierSet m_capturedVariables;
- ScopeFlags m_scopeFlags;
+ CodeFeatures m_features;
int m_numConstants;
struct DepthManager {
@@ -978,7 +1010,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
m_funcDeclarations ? &m_funcDeclarations->data : 0,
m_capturedVariables,
*m_source,
- m_scopeFlags,
+ m_features,
m_numConstants);
result->setLoc(m_source->firstLine(), m_lastLine);
} else if (lexicalGlobalObject) {
diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
index ad7a759ce..3662367a0 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
@@ -61,7 +61,9 @@ public:
int closeBraceLine;
int closeBracePos;
- unsigned short scopeFlags;
+ bool usesEval;
+ bool strictMode;
+ bool needsFullActivation;
Vector<RefPtr<StringImpl> > usedVariables;
Vector<RefPtr<StringImpl> > writtenVariables;
};
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index 2acb5097d..c2c93756d 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -220,6 +220,7 @@ public:
void appendStatement(int, int) { }
void addVar(const Identifier*, bool) { }
int combineCommaNodes(int, int, int) { return 1; }
+ int evalCount() const { return 0; }
void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
{
if (!m_topBinaryExpr)