allocator_(NULL),
cc_reg_(al),
state_(NULL),
+ loop_nesting_(0),
function_return_is_shadowed_(false) {
}
ASSERT(frame_ == NULL);
frame_ = new VirtualFrame();
cc_reg_ = al;
+
+ // Adjust for function-level loop nesting.
+ ASSERT_EQ(0, loop_nesting_);
+ loop_nesting_ = info->loop_nesting();
+
{
CodeGenState state(this);
masm_->InstructionsGeneratedSince(&check_exit_codesize));
}
+ // Adjust for function-level loop nesting.
+ ASSERT(loop_nesting_ == info->loop_nesting());
+ loop_nesting_ = 0;
+
// Code generation state must be reset.
ASSERT(!has_cc());
ASSERT(state_ == NULL);
CodeForStatementPosition(node);
node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
JumpTarget body(JumpTarget::BIDIRECTIONAL);
+ IncrementLoopNesting();
// Label the top of the loop for the backward CFG edge. If the test
// is always true we can use the continue target, and if the test is
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ DecrementLoopNesting();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
if (info == ALWAYS_FALSE) return;
node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
+ IncrementLoopNesting();
// Label the top of the loop with the continue target for the backward
// CFG edge.
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ DecrementLoopNesting();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
if (info == ALWAYS_FALSE) return;
node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
+ IncrementLoopNesting();
// If there is no update statement, label the top of the loop with the
// continue target, otherwise with the loop target.
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ DecrementLoopNesting();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
JumpTarget* true_target() const { return state_->true_target(); }
JumpTarget* false_target() const { return state_->false_target(); }
- // We don't track loop nesting level on ARM yet.
- int loop_nesting() const { return 0; }
+ // Track loop nesting level.
+ int loop_nesting() const { return loop_nesting_; }
+ void IncrementLoopNesting() { loop_nesting_++; }
+ void DecrementLoopNesting() { loop_nesting_--; }
// Node visitors.
void VisitStatements(ZoneList<Statement*>* statements);
void LoadFromSlot(Slot* slot, TypeofState typeof_state);
// Store the value on top of the stack to a slot.
void StoreToSlot(Slot* slot, InitState init_state);
+
// Load a keyed property, leaving it in r0. The receiver and key are
// passed on the stack, and remain there.
void EmitKeyedLoad(bool is_global);
RegisterAllocator* allocator_;
Condition cc_reg_;
CodeGenState* state_;
+ int loop_nesting_;
// Jump targets
BreakTarget function_return_;
set_in_spilled_code(false);
// Adjust for function-level loop nesting.
- loop_nesting_ += info->loop_nesting();
+ ASSERT_EQ(0, loop_nesting_);
+ loop_nesting_ = info->loop_nesting();
JumpTarget::set_compiling_deferred_code(false);
}
// Adjust for function-level loop nesting.
- loop_nesting_ -= info->loop_nesting();
+ ASSERT_EQ(info->loop_nesting(), loop_nesting_);
+ loop_nesting_ = 0;
// Code generation state must be reset.
ASSERT(state_ == NULL);
set_in_spilled_code(false);
// Adjust for function-level loop nesting.
+ ASSERT_EQ(0, loop_nesting_);
loop_nesting_ += info->loop_nesting();
JumpTarget::set_compiling_deferred_code(false);
}
// Adjust for function-level loop nesting.
- loop_nesting_ -= info->loop_nesting();
+ ASSERT_EQ(loop_nesting_, info->loop_nesting());
+ loop_nesting_ = 0;
// Code generation state must be reset.
ASSERT(state_ == NULL);
- ASSERT(loop_nesting() == 0);
ASSERT(!function_return_is_shadowed_);
function_return_.Unuse();
DeleteFrame();