}
Node::Node()
- : m_mayHaveDeclarations(false)
- , m_expectedReturnType(ObjectType)
+ : m_expectedReturnType(ObjectType)
{
m_line = lexer().lineNo();
}
Node::Node(JSType expectedReturn)
- : m_mayHaveDeclarations(false)
- , m_expectedReturnType(expectedReturn)
+ : m_expectedReturnType(expectedReturn)
{
m_line = lexer().lineNo();
}
, ident(id)
, init(in)
{
- m_mayHaveDeclarations = true;
}
void VarDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
nodeStack.append(init.get());
}
-void VarDeclNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (next) {
- ASSERT(next->mayHaveDeclarations());
- stacks.nodeStack.append(next.get());
- }
-
- // The normal check to avoid overwriting pre-existing values with variable
- // declarations doesn't work for the "arguments" property because we
- // instantiate it lazily. So we need to check here instead.
- if (ident == stacks.exec->propertyNames().arguments)
- return;
-
- stacks.varStack.append(this);
-}
-
void VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
{
ScopeChainIterator iter = chain.begin();
return Completion(Normal);
}
-void VarStatementNode::getDeclarations(DeclarationStacks& stacks)
-{
- ASSERT(next->mayHaveDeclarations());
- stacks.nodeStack.append(next.get());
-}
-
// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
static inline void statementListPushFIFO(SourceElements& statements, DeclarationStacks::NodeStack& stack)
}
}
-static inline void statementListGetDeclarations(SourceElements& statements, DeclarationStacks& stacks)
-{
- SourceElements::iterator it = statements.end();
- SourceElements::iterator begin = statements.begin();
- while (it != begin) {
- --it;
- if ((*it)->mayHaveDeclarations())
- stacks.nodeStack.append((*it).get());
- }
-}
-
-static inline Node* statementListInitializeDeclarationStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
-{
- ASSERT(!stack.size()); // Otherwise, the removeLast() call might remove someone else's node.
-
- SourceElements::iterator it = statements.end();
- SourceElements::iterator begin = statements.begin();
-
- while (it != begin) {
- --it;
- if ((*it)->mayHaveDeclarations())
- stack.append((*it).get());
- }
-
- if (!stack.size())
- return 0;
-
- Node* n = stack.last();
- stack.removeLast();
- return n;
-}
-
static inline Node* statementListInitializeVariableAccessStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
{
if (!statements.size())
: m_children(children)
{
ASSERT(m_children);
- m_mayHaveDeclarations = true;
}
void BlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
statementListPushFIFO(*m_children, nodeStack);
}
-void BlockNode::getDeclarations(DeclarationStacks& stacks)
-{
- statementListGetDeclarations(*m_children, stacks);
-}
-
// ECMA 12.1
Completion BlockNode::execute(ExecState *exec)
{
return statement2->execute(exec);
}
-void IfNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement2 && statement2->mayHaveDeclarations())
- stacks.nodeStack.append(statement2.get());
- if (statement1->mayHaveDeclarations())
- stacks.nodeStack.append(statement1.get());
-}
-
// ------------------------------ DoWhileNode ----------------------------------
void DoWhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
return Completion(); // work around gcc 4.0 bug
}
-void DoWhileNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
-}
-
// ------------------------------ WhileNode ------------------------------------
void WhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
return Completion(); // work around gcc 4.0 bug
}
-void WhileNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
-}
-
// ------------------------------ ForNode --------------------------------------
void ForNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
return Completion(); // work around gcc 4.0 bug
}
-void ForNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
- if (expr1 && expr1->mayHaveDeclarations())
- stacks.nodeStack.append(expr1.get());
-}
-
// ------------------------------ ForInNode ------------------------------------
ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode* s)
: init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
{
- m_mayHaveDeclarations = true;
}
ForInNode::ForInNode(const Identifier& i, AssignExprNode* in, ExpressionNode* e, StatementNode* s)
: ident(i), init(in), expr(e), statement(s)
{
- m_mayHaveDeclarations = true;
-
// for( var foo = bar in baz )
varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
lexpr = new ResolveNode(ident);
nodeStack.append(varDecl.get());
}
-void ForInNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
- if (varDecl && varDecl->mayHaveDeclarations())
- stacks.nodeStack.append(varDecl.get());
-}
-
// ECMA 12.6.4
Completion ForInNode::execute(ExecState *exec)
{
// ------------------------------ WithNode -------------------------------------
-void WithNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
-}
-
void WithNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
{
// Can't optimize within statement because "with" introduces a dynamic scope.
statementListPushFIFO(*m_children, nodeStack);
}
-void CaseClauseNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (m_children)
- statementListGetDeclarations(*m_children, stacks);
-}
-
// ECMA 12.11
JSValue *CaseClauseNode::evaluate(ExecState *exec)
{
nodeStack.append(clause.get());
}
-void ClauseListNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (next && next->mayHaveDeclarations())
- stacks.nodeStack.append(next.get());
- if (clause->mayHaveDeclarations())
- stacks.nodeStack.append(clause.get());
-}
-
// ------------------------------ CaseBlockNode --------------------------------
CaseBlockNode::CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2)
, def(d)
, list2(l2)
{
- m_mayHaveDeclarations = true;
}
void CaseBlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
nodeStack.append(list1.get());
}
-void CaseBlockNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (list2 && list2->mayHaveDeclarations())
- stacks.nodeStack.append(list2.get());
- if (def && def->mayHaveDeclarations())
- stacks.nodeStack.append(def.get());
- if (list1 && list1->mayHaveDeclarations())
- stacks.nodeStack.append(list1.get());
-}
-
// ECMA 12.11
Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
{
nodeStack.append(expr.get());
}
-void SwitchNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (block->mayHaveDeclarations())
- stacks.nodeStack.append(block.get());
-}
-
// ECMA 12.11
Completion SwitchNode::execute(ExecState *exec)
{
nodeStack.append(statement.get());
}
-void LabelNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (statement->mayHaveDeclarations())
- stacks.nodeStack.append(statement.get());
-}
-
// ECMA 12.12
Completion LabelNode::execute(ExecState *exec)
{
nodeStack.append(tryBlock.get());
}
-void TryNode::getDeclarations(DeclarationStacks& stacks)
-{
- if (finallyBlock && finallyBlock->mayHaveDeclarations())
- stacks.nodeStack.append(finallyBlock.get());
- if (catchBlock && catchBlock->mayHaveDeclarations())
- stacks.nodeStack.append(catchBlock.get());
- if (tryBlock->mayHaveDeclarations())
- stacks.nodeStack.append(tryBlock.get());
-}
-
// ECMA 12.14
Completion TryNode::execute(ExecState *exec)
{
body->parameters().append(p->ident());
}
-void FuncDeclNode::getDeclarations(DeclarationStacks& stacks)
-{
- stacks.functionStack.append(this);
-}
-
FunctionImp* FuncDeclNode::makeFunction(ExecState* exec)
{
FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->scopeChain());
// Serialization.
virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
virtual Precedence precedence() const = 0;
-
- // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
- bool mayHaveDeclarations() const { return m_mayHaveDeclarations; }
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
// Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
Completion rethrowException(ExecState*) KJS_FAST_CALL;
int m_line : 28;
- bool m_mayHaveDeclarations : 1;
unsigned m_expectedReturnType : 3; // JSType
};
virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
void evaluateSingle(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
PassRefPtr<VarDeclNode> releaseNext() KJS_FAST_CALL { return next.release(); }
class VarStatementNode : public StatementNode {
public:
- VarStatementNode(VarDeclNode* l) KJS_FAST_CALL : next(l) { m_mayHaveDeclarations = true; }
+ VarStatementNode(VarDeclNode* l) KJS_FAST_CALL : next(l) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<VarDeclNode> next;
};
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
virtual Completion execute(ExecState*) KJS_FAST_CALL { ASSERT_NOT_REACHED(); return Completion(); }
virtual void streamTo(SourceStream&) const KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
private:
OwnPtr<SourceElements> m_sourceElements;
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
protected:
OwnPtr<SourceElements> m_children;
};
class IfNode : public StatementNode {
public:
IfNode(ExpressionNode* e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
- : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
+ : expr(e), statement1(s1), statement2(s2) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> expr;
RefPtr<StatementNode> statement1;
class DoWhileNode : public StatementNode {
public:
- DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
+ DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<StatementNode> statement;
RefPtr<ExpressionNode> expr;
class WhileNode : public StatementNode {
public:
- WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
+ WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> expr;
RefPtr<StatementNode> statement;
ForNode(ExpressionNode* e1, ExpressionNode* e2, ExpressionNode* e3, StatementNode* s) KJS_FAST_CALL :
expr1(e1), expr2(e2), expr3(e3), statement(s)
{
- m_mayHaveDeclarations = true;
if (expr1)
expr1->optimizeForUnnecessaryResult();
if (expr3)
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> expr1;
RefPtr<ExpressionNode> expr2;
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
VarDeclNode* getVarDecl() { return varDecl.get(); }
private:
Identifier ident;
class WithNode : public StatementNode {
public:
- WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
+ WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> expr;
RefPtr<StatementNode> statement;
class LabelNode : public StatementNode {
public:
- LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
+ LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
Identifier label;
RefPtr<StatementNode> statement;
class TryNode : public StatementNode {
public:
TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
- : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
+ : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<StatementNode> tryBlock;
Identifier exceptionIdent;
class FuncDeclNode : public StatementNode {
public:
FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
- : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
+ : ident(i), body(b) { addParams(); }
FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
- : ident(i), param(p), body(b) { addParams(); m_mayHaveDeclarations = true; }
+ : ident(i), param(p), body(b) { addParams(); }
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
Identifier ident;
private:
class CaseClauseNode : public Node {
public:
- CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
+ CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
- : expr(e), m_children(children) { m_mayHaveDeclarations = true; }
+ : expr(e), m_children(children) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
JSValue* evaluate(ExecState*) KJS_FAST_CALL;
class ClauseListNode : public Node {
public:
- ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
+ ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { }
ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
- : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
+ : clause(c) { n->next = this; }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
private:
friend class CaseBlockNode;
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
private:
RefPtr<ClauseListNode> list1;
class SwitchNode : public StatementNode {
public:
- SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
+ SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { }
virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual Completion execute(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
- virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> expr;
RefPtr<CaseBlockNode> block;