Split the AST LoopStatement type into separate types for do/while,

while, and for loops.

Previously they were distinguished by a type field, which required
runtime asserts to avoid invalid nodes (since not all loop types have
the same internal structure).  Now they C++ type system is used to
require well-formed loop ASTs.

Because they do not share compilation code, we had very large
functions in the code generators that merely did a runtime dispatch to
a specific implementation based on the type.
Review URL: http://codereview.chromium.org/269049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3048 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c6729115
This diff is collapsed.
...@@ -365,6 +365,14 @@ class CodeGenerator: public AstVisitor { ...@@ -365,6 +365,14 @@ class CodeGenerator: public AstVisitor {
inline void GenerateMathSin(ZoneList<Expression*>* args); inline void GenerateMathSin(ZoneList<Expression*>* args);
inline void GenerateMathCos(ZoneList<Expression*>* args); inline void GenerateMathCos(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
ALWAYS_FALSE,
DONT_KNOW
};
ConditionAnalysis AnalyzeCondition(Expression* cond);
// Methods used to indicate which source code is generated for. Source // Methods used to indicate which source code is generated for. Source
// positions are collected by the assembler and emitted with the relocation // positions are collected by the assembler and emitted with the relocation
// information. // information.
......
...@@ -91,20 +91,6 @@ void VariableProxy::BindTo(Variable* var) { ...@@ -91,20 +91,6 @@ void VariableProxy::BindTo(Variable* var) {
} }
#ifdef DEBUG
const char* LoopStatement::OperatorString() const {
switch (type()) {
case DO_LOOP: return "DO";
case FOR_LOOP: return "FOR";
case WHILE_LOOP: return "WHILE";
}
return NULL;
}
#endif // DEBUG
Token::Value Assignment::binary_op() const { Token::Value Assignment::binary_op() const {
switch (op_) { switch (op_) {
case Token::ASSIGN_BIT_OR: return Token::BIT_OR; case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
......
...@@ -64,10 +64,12 @@ namespace internal { ...@@ -64,10 +64,12 @@ namespace internal {
V(WithEnterStatement) \ V(WithEnterStatement) \
V(WithExitStatement) \ V(WithExitStatement) \
V(SwitchStatement) \ V(SwitchStatement) \
V(LoopStatement) \ V(DoWhileStatement) \
V(WhileStatement) \
V(ForStatement) \
V(ForInStatement) \ V(ForInStatement) \
V(TryCatch) \ V(TryCatchStatement) \
V(TryFinally) \ V(TryFinallyStatement) \
V(DebuggerStatement) V(DebuggerStatement)
#define EXPRESSION_NODE_LIST(V) \ #define EXPRESSION_NODE_LIST(V) \
...@@ -294,13 +296,59 @@ class IterationStatement: public BreakableStatement { ...@@ -294,13 +296,59 @@ class IterationStatement: public BreakableStatement {
}; };
class LoopStatement: public IterationStatement { class DoWhileStatement: public IterationStatement {
public: public:
enum Type { DO_LOOP, FOR_LOOP, WHILE_LOOP }; explicit DoWhileStatement(ZoneStringList* labels)
: IterationStatement(labels), cond_(NULL) {
}
void Initialize(Expression* cond, Statement* body) {
IterationStatement::Initialize(body);
cond_ = cond;
}
virtual void Accept(AstVisitor* v);
Expression* cond() const { return cond_; }
private:
Expression* cond_;
};
LoopStatement(ZoneStringList* labels, Type type) class WhileStatement: public IterationStatement {
public:
explicit WhileStatement(ZoneStringList* labels)
: IterationStatement(labels),
cond_(NULL),
may_have_function_literal_(true) {
}
void Initialize(Expression* cond, Statement* body) {
IterationStatement::Initialize(body);
cond_ = cond;
}
virtual void Accept(AstVisitor* v);
Expression* cond() const { return cond_; }
bool may_have_function_literal() const {
return may_have_function_literal_;
}
private:
Expression* cond_;
// True if there is a function literal subexpression in the condition.
bool may_have_function_literal_;
friend class AstOptimizer;
};
class ForStatement: public IterationStatement {
public:
explicit ForStatement(ZoneStringList* labels)
: IterationStatement(labels), : IterationStatement(labels),
type_(type),
init_(NULL), init_(NULL),
cond_(NULL), cond_(NULL),
next_(NULL), next_(NULL),
...@@ -311,8 +359,6 @@ class LoopStatement: public IterationStatement { ...@@ -311,8 +359,6 @@ class LoopStatement: public IterationStatement {
Expression* cond, Expression* cond,
Statement* next, Statement* next,
Statement* body) { Statement* body) {
ASSERT(init == NULL || type_ == FOR_LOOP);
ASSERT(next == NULL || type_ == FOR_LOOP);
IterationStatement::Initialize(body); IterationStatement::Initialize(body);
init_ = init; init_ = init;
cond_ = cond; cond_ = cond;
...@@ -321,7 +367,6 @@ class LoopStatement: public IterationStatement { ...@@ -321,7 +367,6 @@ class LoopStatement: public IterationStatement {
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
Type type() const { return type_; }
Statement* init() const { return init_; } Statement* init() const { return init_; }
Expression* cond() const { return cond_; } Expression* cond() const { return cond_; }
Statement* next() const { return next_; } Statement* next() const { return next_; }
...@@ -329,12 +374,7 @@ class LoopStatement: public IterationStatement { ...@@ -329,12 +374,7 @@ class LoopStatement: public IterationStatement {
return may_have_function_literal_; return may_have_function_literal_;
} }
#ifdef DEBUG
const char* OperatorString() const;
#endif
private: private:
Type type_;
Statement* init_; Statement* init_;
Expression* cond_; Expression* cond_;
Statement* next_; Statement* next_;
...@@ -569,9 +609,11 @@ class TryStatement: public Statement { ...@@ -569,9 +609,11 @@ class TryStatement: public Statement {
}; };
class TryCatch: public TryStatement { class TryCatchStatement: public TryStatement {
public: public:
TryCatch(Block* try_block, Expression* catch_var, Block* catch_block) TryCatchStatement(Block* try_block,
Expression* catch_var,
Block* catch_block)
: TryStatement(try_block), : TryStatement(try_block),
catch_var_(catch_var), catch_var_(catch_var),
catch_block_(catch_block) { catch_block_(catch_block) {
...@@ -589,9 +631,9 @@ class TryCatch: public TryStatement { ...@@ -589,9 +631,9 @@ class TryCatch: public TryStatement {
}; };
class TryFinally: public TryStatement { class TryFinallyStatement: public TryStatement {
public: public:
TryFinally(Block* try_block, Block* finally_block) TryFinallyStatement(Block* try_block, Block* finally_block)
: TryStatement(try_block), : TryStatement(try_block),
finally_block_(finally_block) { } finally_block_(finally_block) { }
......
...@@ -469,6 +469,25 @@ bool CodeGenerator::PatchInlineRuntimeEntry(Handle<String> name, ...@@ -469,6 +469,25 @@ bool CodeGenerator::PatchInlineRuntimeEntry(Handle<String> name,
} }
// Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
// known result for the test expression, with no side effects.
CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition(
Expression* cond) {
if (cond == NULL) return ALWAYS_TRUE;
Literal* lit = cond->AsLiteral();
if (lit == NULL) return DONT_KNOW;
if (lit->IsTrue()) {
return ALWAYS_TRUE;
} else if (lit->IsFalse()) {
return ALWAYS_FALSE;
}
return DONT_KNOW;
}
static inline void RecordPositions(CodeGenerator* cgen, int pos) { static inline void RecordPositions(CodeGenerator* cgen, int pos) {
if (pos != RelocInfo::kNoPosition) { if (pos != RelocInfo::kNoPosition) {
cgen->masm()->RecordStatementPosition(pos); cgen->masm()->RecordStatementPosition(pos);
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
// FindInlineRuntimeLUT // FindInlineRuntimeLUT
// CheckForInlineRuntimeCall // CheckForInlineRuntimeCall
// PatchInlineRuntimeEntry // PatchInlineRuntimeEntry
// AnalyzeCondition
// CodeForFunctionPosition // CodeForFunctionPosition
// CodeForReturnPosition // CodeForReturnPosition
// CodeForStatementPosition // CodeForStatementPosition
......
This diff is collapsed.
...@@ -548,6 +548,14 @@ class CodeGenerator: public AstVisitor { ...@@ -548,6 +548,14 @@ class CodeGenerator: public AstVisitor {
inline void GenerateMathSin(ZoneList<Expression*>* args); inline void GenerateMathSin(ZoneList<Expression*>* args);
inline void GenerateMathCos(ZoneList<Expression*>* args); inline void GenerateMathCos(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
ALWAYS_FALSE,
DONT_KNOW
};
ConditionAnalysis AnalyzeCondition(Expression* cond);
// Methods used to indicate which source code is generated for. Source // Methods used to indicate which source code is generated for. Source
// positions are collected by the assembler and emitted with the relocation // positions are collected by the assembler and emitted with the relocation
// information. // information.
......
...@@ -177,8 +177,8 @@ class Parser { ...@@ -177,8 +177,8 @@ class Parser {
Statement* ParseWithStatement(ZoneStringList* labels, bool* ok); Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok); CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok); SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
LoopStatement* ParseDoStatement(ZoneStringList* labels, bool* ok); DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
LoopStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok); WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
Statement* ParseForStatement(ZoneStringList* labels, bool* ok); Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
Statement* ParseThrowStatement(bool* ok); Statement* ParseThrowStatement(bool* ok);
Expression* MakeCatchContext(Handle<String> id, VariableProxy* value); Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
...@@ -1692,7 +1692,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { ...@@ -1692,7 +1692,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
break; break;
case Token::DO: case Token::DO:
stmt = ParseDoStatement(labels, ok); stmt = ParseDoWhileStatement(labels, ok);
break; break;
case Token::WHILE: case Token::WHILE:
...@@ -2361,7 +2361,7 @@ Block* Parser::WithHelper(Expression* obj, ...@@ -2361,7 +2361,7 @@ Block* Parser::WithHelper(Expression* obj,
exit->AddStatement(NEW(WithExitStatement())); exit->AddStatement(NEW(WithExitStatement()));
// Return a try-finally statement. // Return a try-finally statement.
TryFinally* wrapper = NEW(TryFinally(body, exit)); TryFinallyStatement* wrapper = NEW(TryFinallyStatement(body, exit));
wrapper->set_escaping_targets(collector.targets()); wrapper->set_escaping_targets(collector.targets());
result->AddStatement(wrapper); result->AddStatement(wrapper);
} }
...@@ -2537,7 +2537,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2537,7 +2537,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
// 'try { try { } catch { } } finally { }' // 'try { try { } catch { } } finally { }'
if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) { if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) {
TryCatch* statement = NEW(TryCatch(try_block, catch_var, catch_block)); TryCatchStatement* statement =
NEW(TryCatchStatement(try_block, catch_var, catch_block));
statement->set_escaping_targets(collector.targets()); statement->set_escaping_targets(collector.targets());
try_block = NEW(Block(NULL, 1, false)); try_block = NEW(Block(NULL, 1, false));
try_block->AddStatement(statement); try_block->AddStatement(statement);
...@@ -2548,11 +2549,11 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2548,11 +2549,11 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
if (!is_pre_parsing_) { if (!is_pre_parsing_) {
if (catch_block != NULL) { if (catch_block != NULL) {
ASSERT(finally_block == NULL); ASSERT(finally_block == NULL);
result = NEW(TryCatch(try_block, catch_var, catch_block)); result = NEW(TryCatchStatement(try_block, catch_var, catch_block));
result->set_escaping_targets(collector.targets()); result->set_escaping_targets(collector.targets());
} else { } else {
ASSERT(finally_block != NULL); ASSERT(finally_block != NULL);
result = NEW(TryFinally(try_block, finally_block)); result = NEW(TryFinallyStatement(try_block, finally_block));
// Add the jump targets of the try block and the catch block. // Add the jump targets of the try block and the catch block.
for (int i = 0; i < collector.targets()->length(); i++) { for (int i = 0; i < collector.targets()->length(); i++) {
catch_collector.AddTarget(collector.targets()->at(i)); catch_collector.AddTarget(collector.targets()->at(i));
...@@ -2565,11 +2566,12 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2565,11 +2566,12 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
} }
LoopStatement* Parser::ParseDoStatement(ZoneStringList* labels, bool* ok) { DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
bool* ok) {
// DoStatement :: // DoStatement ::
// 'do' Statement 'while' '(' Expression ')' ';' // 'do' Statement 'while' '(' Expression ')' ';'
LoopStatement* loop = NEW(LoopStatement(labels, LoopStatement::DO_LOOP)); DoWhileStatement* loop = NEW(DoWhileStatement(labels));
Target target(this, loop); Target target(this, loop);
Expect(Token::DO, CHECK_OK); Expect(Token::DO, CHECK_OK);
...@@ -2585,16 +2587,16 @@ LoopStatement* Parser::ParseDoStatement(ZoneStringList* labels, bool* ok) { ...@@ -2585,16 +2587,16 @@ LoopStatement* Parser::ParseDoStatement(ZoneStringList* labels, bool* ok) {
// ExpectSemicolon() functionality here. // ExpectSemicolon() functionality here.
if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
if (loop) loop->Initialize(NULL, cond, NULL, body); if (loop != NULL) loop->Initialize(cond, body);
return loop; return loop;
} }
LoopStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
// WhileStatement :: // WhileStatement ::
// 'while' '(' Expression ')' Statement // 'while' '(' Expression ')' Statement
LoopStatement* loop = NEW(LoopStatement(labels, LoopStatement::WHILE_LOOP)); WhileStatement* loop = NEW(WhileStatement(labels));
Target target(this, loop); Target target(this, loop);
Expect(Token::WHILE, CHECK_OK); Expect(Token::WHILE, CHECK_OK);
...@@ -2603,7 +2605,7 @@ LoopStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { ...@@ -2603,7 +2605,7 @@ LoopStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Statement* body = ParseStatement(NULL, CHECK_OK); Statement* body = ParseStatement(NULL, CHECK_OK);
if (loop) loop->Initialize(NULL, cond, NULL, body); if (loop != NULL) loop->Initialize(cond, body);
return loop; return loop;
} }
...@@ -2676,7 +2678,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2676,7 +2678,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
} }
// Standard 'for' loop // Standard 'for' loop
LoopStatement* loop = NEW(LoopStatement(labels, LoopStatement::FOR_LOOP)); ForStatement* loop = NEW(ForStatement(labels));
Target target(this, loop); Target target(this, loop);
// Parsed initializer at this point. // Parsed initializer at this point.
......
...@@ -147,46 +147,42 @@ void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) { ...@@ -147,46 +147,42 @@ void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
} }
void PrettyPrinter::VisitLoopStatement(LoopStatement* node) { void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
PrintLabels(node->labels()); PrintLabels(node->labels());
switch (node->type()) { Print("do ");
case LoopStatement::DO_LOOP: Visit(node->body());
ASSERT(node->init() == NULL); Print(" while (");
ASSERT(node->next() == NULL); Visit(node->cond());
Print("do "); Print(");");
Visit(node->body()); }
Print(" while (");
Visit(node->cond());
Print(");");
break;
case LoopStatement::FOR_LOOP:
Print("for (");
if (node->init() != NULL) {
Visit(node->init());
Print(" ");
} else {
Print("; ");
}
if (node->cond() != NULL)
Visit(node->cond());
Print("; ");
if (node->next() != NULL)
Visit(node->next()); // prints extra ';', unfortunately
// to fix: should use Expression for next
Print(") ");
Visit(node->body());
break;
case LoopStatement::WHILE_LOOP: void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
ASSERT(node->init() == NULL); PrintLabels(node->labels());
ASSERT(node->next() == NULL); Print("while (");
Print("while ("); Visit(node->cond());
Visit(node->cond()); Print(") ");
Print(") "); Visit(node->body());
Visit(node->body()); }
break;
void PrettyPrinter::VisitForStatement(ForStatement* node) {
PrintLabels(node->labels());
Print("for (");
if (node->init() != NULL) {
Visit(node->init());
Print(" ");
} else {
Print("; ");
}
if (node->cond() != NULL) Visit(node->cond());
Print("; ");
if (node->next() != NULL) {
Visit(node->next()); // prints extra ';', unfortunately
// to fix: should use Expression for next
} }
Print(") ");
Visit(node->body());
} }
...@@ -201,7 +197,7 @@ void PrettyPrinter::VisitForInStatement(ForInStatement* node) { ...@@ -201,7 +197,7 @@ void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
} }
void PrettyPrinter::VisitTryCatch(TryCatch* node) { void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Print("try "); Print("try ");
Visit(node->try_block()); Visit(node->try_block());
Print(" catch ("); Print(" catch (");
...@@ -211,7 +207,7 @@ void PrettyPrinter::VisitTryCatch(TryCatch* node) { ...@@ -211,7 +207,7 @@ void PrettyPrinter::VisitTryCatch(TryCatch* node) {
} }
void PrettyPrinter::VisitTryFinally(TryFinally* node) { void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Print("try "); Print("try ");
Visit(node->try_block()); Visit(node->try_block());
Print(" finally "); Print(" finally ");
...@@ -841,12 +837,28 @@ void AstPrinter::VisitSwitchStatement(SwitchStatement* node) { ...@@ -841,12 +837,28 @@ void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
} }
void AstPrinter::VisitLoopStatement(LoopStatement* node) { void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
IndentedScope indent(node->OperatorString()); IndentedScope indent("DO");
PrintLabelsIndented(NULL, node->labels());
PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("COND", node->cond());
}
void AstPrinter::VisitWhileStatement(WhileStatement* node) {
IndentedScope indent("WHILE");
PrintLabelsIndented(NULL, node->labels());
PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body());
}
void AstPrinter::VisitForStatement(ForStatement* node) {
IndentedScope indent("FOR");
PrintLabelsIndented(NULL, node->labels()); PrintLabelsIndented(NULL, node->labels());
if (node->init()) PrintIndentedVisit("INIT", node->init()); if (node->init()) PrintIndentedVisit("INIT", node->init());
if (node->cond()) PrintIndentedVisit("COND", node->cond()); if (node->cond()) PrintIndentedVisit("COND", node->cond());
if (node->body()) PrintIndentedVisit("BODY", node->body()); PrintIndentedVisit("BODY", node->body());
if (node->next()) PrintIndentedVisit("NEXT", node->next()); if (node->next()) PrintIndentedVisit("NEXT", node->next());
} }
...@@ -859,7 +871,7 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) { ...@@ -859,7 +871,7 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) {
} }
void AstPrinter::VisitTryCatch(TryCatch* node) { void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
IndentedScope indent("TRY CATCH"); IndentedScope indent("TRY CATCH");
PrintIndentedVisit("TRY", node->try_block()); PrintIndentedVisit("TRY", node->try_block());
PrintIndentedVisit("CATCHVAR", node->catch_var()); PrintIndentedVisit("CATCHVAR", node->catch_var());
...@@ -867,7 +879,7 @@ void AstPrinter::VisitTryCatch(TryCatch* node) { ...@@ -867,7 +879,7 @@ void AstPrinter::VisitTryCatch(TryCatch* node) {
} }
void AstPrinter::VisitTryFinally(TryFinally* node) { void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
IndentedScope indent("TRY FINALLY"); IndentedScope indent("TRY FINALLY");
PrintIndentedVisit("TRY", node->try_block()); PrintIndentedVisit("TRY", node->try_block());
PrintIndentedVisit("FINALLY", node->finally_block()); PrintIndentedVisit("FINALLY", node->finally_block());
......
...@@ -100,7 +100,21 @@ void AstOptimizer::VisitIfStatement(IfStatement* node) { ...@@ -100,7 +100,21 @@ void AstOptimizer::VisitIfStatement(IfStatement* node) {
} }
void AstOptimizer::VisitLoopStatement(LoopStatement* node) { void AstOptimizer::VisitDoWhileStatement(DoWhileStatement* node) {
Visit(node->cond());
Visit(node->body());
}
void AstOptimizer::VisitWhileStatement(WhileStatement* node) {
has_function_literal_ = false;
Visit(node->cond());
node->may_have_function_literal_ = has_function_literal_;
Visit(node->body());
}
void AstOptimizer::VisitForStatement(ForStatement* node) {
if (node->init() != NULL) { if (node->init() != NULL) {
Visit(node->init()); Visit(node->init());
} }
...@@ -109,9 +123,7 @@ void AstOptimizer::VisitLoopStatement(LoopStatement* node) { ...@@ -109,9 +123,7 @@ void AstOptimizer::VisitLoopStatement(LoopStatement* node) {
Visit(node->cond()); Visit(node->cond());
node->may_have_function_literal_ = has_function_literal_; node->may_have_function_literal_ = has_function_literal_;
} }
if (node->body() != NULL) { Visit(node->body());
Visit(node->body());
}
if (node->next() != NULL) { if (node->next() != NULL) {
Visit(node->next()); Visit(node->next());
} }
...@@ -125,14 +137,14 @@ void AstOptimizer::VisitForInStatement(ForInStatement* node) { ...@@ -125,14 +137,14 @@ void AstOptimizer::VisitForInStatement(ForInStatement* node) {
} }
void AstOptimizer::VisitTryCatch(TryCatch* node) { void AstOptimizer::VisitTryCatchStatement(TryCatchStatement* node) {
Visit(node->try_block()); Visit(node->try_block());
Visit(node->catch_var()); Visit(node->catch_var());
Visit(node->catch_block()); Visit(node->catch_block());
} }
void AstOptimizer::VisitTryFinally(TryFinally* node) { void AstOptimizer::VisitTryFinallyStatement(TryFinallyStatement* node) {
Visit(node->try_block()); Visit(node->try_block());
Visit(node->finally_block()); Visit(node->finally_block());
} }
...@@ -553,6 +565,8 @@ class Processor: public AstVisitor { ...@@ -553,6 +565,8 @@ class Processor: public AstVisitor {
virtual void Visit##type(type* node); virtual void Visit##type(type* node);
AST_NODE_LIST(DEF_VISIT) AST_NODE_LIST(DEF_VISIT)
#undef DEF_VISIT #undef DEF_VISIT
void VisitIterationStatement(IterationStatement* stmt);
}; };
...@@ -596,25 +610,35 @@ void Processor::VisitIfStatement(IfStatement* node) { ...@@ -596,25 +610,35 @@ void Processor::VisitIfStatement(IfStatement* node) {
} }
void Processor::VisitIterationStatement(IterationStatement* node) {
// Rewrite the body.
void Processor::VisitLoopStatement(LoopStatement* node) {
// Rewrite loop body statement.
bool set_after_loop = is_set_; bool set_after_loop = is_set_;
Visit(node->body()); Visit(node->body());
is_set_ = is_set_ && set_after_loop; is_set_ = is_set_ && set_after_loop;
} }
void Processor::VisitDoWhileStatement(DoWhileStatement* node) {
VisitIterationStatement(node);
}
void Processor::VisitWhileStatement(WhileStatement* node) {
VisitIterationStatement(node);
}
void Processor::VisitForStatement(ForStatement* node) {
VisitIterationStatement(node);
}
void Processor::VisitForInStatement(ForInStatement* node) { void Processor::VisitForInStatement(ForInStatement* node) {
// Rewrite for-in body statement. VisitIterationStatement(node);
bool set_after_for = is_set_;
Visit(node->body());
is_set_ = is_set_ && set_after_for;
} }
void Processor::VisitTryCatch(TryCatch* node) { void Processor::VisitTryCatchStatement(TryCatchStatement* node) {
// Rewrite both try and catch blocks (reversed order). // Rewrite both try and catch blocks (reversed order).
bool set_after_catch = is_set_; bool set_after_catch = is_set_;
Visit(node->catch_block()); Visit(node->catch_block());
...@@ -626,7 +650,7 @@ void Processor::VisitTryCatch(TryCatch* node) { ...@@ -626,7 +650,7 @@ void Processor::VisitTryCatch(TryCatch* node) {
} }
void Processor::VisitTryFinally(TryFinally* node) { void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
// Rewrite both try and finally block (reversed order). // Rewrite both try and finally block (reversed order).
Visit(node->finally_block()); Visit(node->finally_block());
bool save = in_try_; bool save = in_try_;
......
...@@ -159,14 +159,25 @@ void UsageComputer::VisitSwitchStatement(SwitchStatement* node) { ...@@ -159,14 +159,25 @@ void UsageComputer::VisitSwitchStatement(SwitchStatement* node) {
} }
void UsageComputer::VisitLoopStatement(LoopStatement* node) { void UsageComputer::VisitDoWhileStatement(DoWhileStatement* node) {
if (node->init() != NULL) WeightScaler ws(this, 10.0);
Visit(node->init()); Read(node->cond());
Visit(node->body());
}
void UsageComputer::VisitWhileStatement(WhileStatement* node) {
WeightScaler ws(this, 10.0);
Read(node->cond());
Visit(node->body());
}
void UsageComputer::VisitForStatement(ForStatement* node) {
if (node->init() != NULL) Visit(node->init());
{ WeightScaler ws(this, 10.0); // executed in each iteration { WeightScaler ws(this, 10.0); // executed in each iteration
if (node->cond() != NULL) if (node->cond() != NULL) Read(node->cond());
Read(node->cond()); if (node->next() != NULL) Visit(node->next());
if (node->next() != NULL)
Visit(node->next());
Visit(node->body()); Visit(node->body());
} }
} }
...@@ -180,7 +191,7 @@ void UsageComputer::VisitForInStatement(ForInStatement* node) { ...@@ -180,7 +191,7 @@ void UsageComputer::VisitForInStatement(ForInStatement* node) {
} }
void UsageComputer::VisitTryCatch(TryCatch* node) { void UsageComputer::VisitTryCatchStatement(TryCatchStatement* node) {
Visit(node->try_block()); Visit(node->try_block());
{ WeightScaler ws(this, 0.25); { WeightScaler ws(this, 0.25);
Write(node->catch_var()); Write(node->catch_var());
...@@ -189,7 +200,7 @@ void UsageComputer::VisitTryCatch(TryCatch* node) { ...@@ -189,7 +200,7 @@ void UsageComputer::VisitTryCatch(TryCatch* node) {
} }
void UsageComputer::VisitTryFinally(TryFinally* node) { void UsageComputer::VisitTryFinallyStatement(TryFinallyStatement* node) {
Visit(node->try_block()); Visit(node->try_block());
Visit(node->finally_block()); Visit(node->finally_block());
} }
......
This diff is collapsed.
...@@ -548,6 +548,14 @@ class CodeGenerator: public AstVisitor { ...@@ -548,6 +548,14 @@ class CodeGenerator: public AstVisitor {
inline void GenerateMathSin(ZoneList<Expression*>* args); inline void GenerateMathSin(ZoneList<Expression*>* args);
inline void GenerateMathCos(ZoneList<Expression*>* args); inline void GenerateMathCos(ZoneList<Expression*>* args);
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
ALWAYS_FALSE,
DONT_KNOW
};
ConditionAnalysis AnalyzeCondition(Expression* cond);
// Methods used to indicate which source code is generated for. Source // Methods used to indicate which source code is generated for. Source
// positions are collected by the assembler and emitted with the relocation // positions are collected by the assembler and emitted with the relocation
// information. // information.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment