Index: src/cfg.cc |
=================================================================== |
--- src/cfg.cc (revision 2602) |
+++ src/cfg.cc (working copy) |
@@ -36,32 +36,37 @@ |
namespace internal { |
-ExitNode* Cfg::global_exit_ = NULL; |
+CfgGlobals* CfgGlobals::top_ = NULL; |
-void CfgNode::Reset() { |
+CfgGlobals::CfgGlobals(FunctionLiteral* fun) |
+ : global_fun_(fun), |
+ global_exit_(new ExitNode()), |
#ifdef DEBUG |
- node_counter_ = 0; |
+ node_counter_(0), |
#endif |
+ previous_(top_) { |
+ top_ = this; |
} |
-void Cfg::Reset(FunctionLiteral* fun) { |
- global_exit_ = new ExitNode(fun); |
- CfgNode::Reset(); |
-} |
- |
- |
#define BAILOUT(reason) \ |
do { return NULL; } while (false) |
-Cfg* Cfg::Build(FunctionLiteral* fun) { |
+Cfg* Cfg::Build() { |
+ FunctionLiteral* fun = CfgGlobals::current()->fun(); |
+ if (fun->scope()->num_heap_slots() > 0) { |
+ BAILOUT("function has context slots"); |
+ } |
+ if (fun->scope()->arguments() != NULL) { |
+ BAILOUT("function uses .arguments"); |
+ } |
+ |
ZoneList<Statement*>* body = fun->body(); |
if (body->is_empty()) { |
BAILOUT("empty function body"); |
} |
- Cfg::Reset(fun); |
StatementBuilder builder; |
builder.VisitStatements(body); |
Cfg* cfg = builder.cfg(); |
@@ -71,16 +76,16 @@ |
if (cfg->has_exit()) { |
BAILOUT("control path without explicit return"); |
} |
- cfg->PrependEntryNode(fun); |
+ cfg->PrependEntryNode(); |
return cfg; |
} |
#undef BAILOUT |
-void Cfg::PrependEntryNode(FunctionLiteral* fun) { |
+void Cfg::PrependEntryNode() { |
ASSERT(!is_empty()); |
- entry_ = new EntryNode(fun, InstructionBlock::cast(entry())); |
+ entry_ = new EntryNode(InstructionBlock::cast(entry())); |
} |
@@ -93,21 +98,12 @@ |
void Cfg::AppendReturnInstruction(Value* value) { |
Append(new ReturnInstr(value)); |
- InstructionBlock::cast(exit_)->set_successor(global_exit_); |
+ ExitNode* global_exit = CfgGlobals::current()->exit(); |
+ InstructionBlock::cast(exit_)->set_successor(global_exit); |
exit_ = NULL; |
} |
-EntryNode::EntryNode(FunctionLiteral* fun, InstructionBlock* succ) |
- : successor_(succ), local_count_(fun->scope()->num_stack_slots()) { |
-} |
- |
- |
-ExitNode::ExitNode(FunctionLiteral* fun) |
- : parameter_count_(fun->scope()->num_parameters()) { |
-} |
- |
- |
void InstructionBlock::Unmark() { |
if (is_marked_) { |
is_marked_ = false; |
@@ -124,16 +120,17 @@ |
} |
-void ExitNode::Unmark() {} |
+void ExitNode::Unmark() { is_marked_ = false; } |
Kasper Lund
2009/08/03 05:55:44
I would put this on three lines.
Kevin Millikin (Chromium)
2009/08/03 07:54:43
Done.
|
-Handle<Code> Cfg::Compile(FunctionLiteral* fun, Handle<Script> script) { |
+Handle<Code> Cfg::Compile(Handle<Script> script) { |
const int kInitialBufferSize = 4 * KB; |
MacroAssembler* masm = new MacroAssembler(NULL, kInitialBufferSize); |
entry()->Compile(masm); |
entry()->Unmark(); |
CodeDesc desc; |
masm->GetCode(&desc); |
+ FunctionLiteral* fun = CfgGlobals::current()->fun(); |
ZoneScopeInfo info(fun->scope()); |
InLoopFlag in_loop = fun->loop_nesting() ? IN_LOOP : NOT_IN_LOOP; |
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop); |
@@ -149,8 +146,9 @@ |
PrintF("--- Raw source ---\n"); |
StringInputBuffer stream(String::cast(script->source())); |
stream.Seek(fun->start_position()); |
- // fun->end_position() points to the last character in the stream. We |
- // need to compensate by adding one to calculate the length. |
+ // fun->end_position() points to the last character in the |
+ // stream. We need to compensate by adding one to calculate the |
+ // length. |
int source_len = fun->end_position() - fun->start_position() + 1; |
for (int i = 0; i < source_len; i++) { |
if (stream.has_more()) PrintF("%c", stream.GetNext()); |
@@ -207,7 +205,15 @@ |
void ExpressionBuilder::VisitVariableProxy(VariableProxy* expr) { |
- BAILOUT("VariableProxy"); |
+ Expression* rewrite = expr->var()->rewrite(); |
+ if (rewrite == NULL || rewrite->AsSlot() == NULL) { |
+ BAILOUT("unsupported variable (not a slot)"); |
+ } |
+ Slot* slot = rewrite->AsSlot(); |
+ if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) { |
+ BAILOUT("unsupported slot type (not a parameter or local)"); |
+ } |
+ value_ = new SlotLocation(slot->type(), slot->index()); |
} |
@@ -416,10 +422,27 @@ |
void Constant::Print() { |
+ PrintF("Constant("); |
handle_->Print(); |
+ PrintF(")"); |
} |
+void SlotLocation::Print() { |
+ PrintF("Slot("); |
+ switch (type_) { |
+ case Slot::PARAMETER: |
+ PrintF("PARAMETER, %d)", index_); |
+ break; |
+ case Slot::LOCAL: |
+ PrintF("LOCAL, %d)", index_); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
void ReturnInstr::Print() { |
PrintF("Return "); |
value_->Print(); |
@@ -427,9 +450,6 @@ |
} |
-int CfgNode::node_counter_ = 0; |
- |
- |
void InstructionBlock::Print() { |
if (!is_marked_) { |
is_marked_ = true; |