DeleteFrame();
// Process any deferred code using the register allocator.
- ProcessDeferred();
+ if (HasStackOverflow()) {
+ ClearDeferred();
+ } else {
+ ProcessDeferred();
+ }
allocator_ = NULL;
scope_ = NULL;
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
// Exit.
exit.Bind();
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
ASSERT(frame_->height() == original_height);
}
DeleteFrame();
// Process any deferred code using the register allocator.
- ProcessDeferred();
+ if (HasStackOverflow()) {
+ ClearDeferred();
+ } else {
+ ProcessDeferred();
+ }
// There is no need to delete the register allocator, it is a
// stack-allocated local.
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
}
// There are two ways to reach the body: from the corresponding
// test or as the fall through of the previous body.
- if (!clause->body_target()->is_linked() && !has_valid_frame()) {
- // If we have neither, skip this body.
- continue;
- } else if (clause->body_target()->is_linked() && has_valid_frame()) {
- // If we have both, put a jump on the fall through path to avoid
- // the dropping of the switch value on the test path. The
- // exception is the default which has already had the switch
- // value dropped.
- if (clause->is_default()) {
- clause->body_target()->Bind();
+ if (clause->body_target()->is_linked() || has_valid_frame()) {
+ if (clause->body_target()->is_linked()) {
+ if (has_valid_frame()) {
+ // If we have both a jump to the test and a fall through, put
+ // a jump on the fall through path to avoid the dropping of
+ // the switch value on the test path. The exception is the
+ // default which has already had the switch value dropped.
+ if (clause->is_default()) {
+ clause->body_target()->Bind();
+ } else {
+ JumpTarget body(this);
+ body.Jump();
+ clause->body_target()->Bind();
+ frame_->Drop();
+ body.Bind();
+ }
+ } else {
+ // No fall through to worry about.
+ clause->body_target()->Bind();
+ if (!clause->is_default()) {
+ frame_->Drop();
+ }
+ }
} else {
- JumpTarget body(this);
- body.Jump();
- clause->body_target()->Bind();
- frame_->Drop();
- body.Bind();
- }
- } else if (clause->body_target()->is_linked()) {
- // No fall through to worry about.
- clause->body_target()->Bind();
- if (!clause->is_default()) {
- frame_->Drop();
+ // Otherwise, we have only fall through.
+ ASSERT(has_valid_frame());
}
- } else {
- // Otherwise, we have only fall through.
- ASSERT(has_valid_frame());
- }
- // We are now prepared to compile the body.
- Comment cmnt(masm_, "[ Case body");
- VisitStatements(clause->statements());
+ // We are now prepared to compile the body.
+ Comment cmnt(masm_, "[ Case body");
+ VisitStatements(clause->statements());
+ }
+ clause->body_target()->Unuse();
}
// We may not have a valid frame here so bind the break target only
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
}
+ node->break_target()->Unuse();
}
}
DecrementLoopNesting();
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
}
// Exit.
exit.Bind();
+
+ node->continue_target()->Unuse();
+ node->break_target()->Unuse();
}
// CodeGenerator::CodeGenerator
// CodeGenerator::~CodeGenerator
// CodeGenerator::ProcessDeferred
+// CodeGenerator::ClearDeferred
// CodeGenerator::GenCode
// CodeGenerator::BuildBoilerplate
// CodeGenerator::ComputeCallInitialize
virtual void Generate() = 0;
+ // Unuse the entry and exit targets, deallocating all virtual frames
+ // held by them. It will be impossible to emit a (correct) jump
+ // into or out of the deferred code after clearing.
+ void Clear() {
+ enter_.Unuse();
+ exit_.Unuse();
+ }
+
MacroAssembler* masm() const { return masm_; }
CodeGenerator* generator() const { return generator_; }