Index: src/jump-target.cc |
=================================================================== |
--- src/jump-target.cc (revision 1668) |
+++ src/jump-target.cc (working copy) |
@@ -298,12 +298,17 @@ |
} |
+void JumpTarget::Jump() { |
+ DoJump(); |
+} |
+ |
+ |
void JumpTarget::Jump(Result* arg) { |
ASSERT(cgen_ != NULL); |
ASSERT(cgen_->has_valid_frame()); |
cgen_->frame()->Push(arg); |
- Jump(); |
+ DoJump(); |
} |
@@ -313,7 +318,7 @@ |
cgen_->frame()->Push(arg0); |
cgen_->frame()->Push(arg1); |
- Jump(); |
+ DoJump(); |
} |
@@ -324,10 +329,15 @@ |
cgen_->frame()->Push(arg0); |
cgen_->frame()->Push(arg1); |
cgen_->frame()->Push(arg2); |
- Jump(); |
+ DoJump(); |
} |
+void JumpTarget::Branch(Condition cc, Hint hint) { |
+ DoBranch(cc, hint); |
+} |
+ |
+ |
#ifdef DEBUG |
#define DECLARE_ARGCHECK_VARS(name) \ |
Result::Type name##_type = name->type(); \ |
@@ -352,7 +362,7 @@ |
DECLARE_ARGCHECK_VARS(arg); |
cgen_->frame()->Push(arg); |
- Branch(cc, hint); |
+ DoBranch(cc, hint); |
*arg = cgen_->frame()->Pop(); |
ASSERT_ARGCHECK(arg); |
@@ -370,7 +380,7 @@ |
cgen_->frame()->Push(arg0); |
cgen_->frame()->Push(arg1); |
- Branch(cc, hint); |
+ DoBranch(cc, hint); |
*arg1 = cgen_->frame()->Pop(); |
*arg0 = cgen_->frame()->Pop(); |
@@ -396,7 +406,7 @@ |
cgen_->frame()->Push(arg0); |
cgen_->frame()->Push(arg1); |
cgen_->frame()->Push(arg2); |
- Branch(cc, hint); |
+ DoBranch(cc, hint); |
*arg2 = cgen_->frame()->Pop(); |
*arg1 = cgen_->frame()->Pop(); |
*arg0 = cgen_->frame()->Pop(); |
@@ -427,7 +437,7 @@ |
cgen_->frame()->Push(arg1); |
cgen_->frame()->Push(arg2); |
cgen_->frame()->Push(arg3); |
- Branch(cc, hint); |
+ DoBranch(cc, hint); |
*arg3 = cgen_->frame()->Pop(); |
*arg2 = cgen_->frame()->Pop(); |
*arg1 = cgen_->frame()->Pop(); |
@@ -439,17 +449,47 @@ |
ASSERT_ARGCHECK(arg3); |
} |
+ |
+void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { |
+ ASSERT(cgen_ != NULL); |
+ ASSERT(cgen_->has_valid_frame()); |
+ |
+ int count = cgen_->frame()->height() - expected_height_; |
+ if (count > 0) { |
+ // We negate and branch here rather than using DoBranch's negate |
+ // and branch. This gives us a hook to remove statement state |
+ // from the frame. |
+ JumpTarget fall_through(cgen_); |
+ // Branch to fall through will not negate, because it is a |
+ // forward-only target. |
+ fall_through.Branch(NegateCondition(cc), NegateHint(hint)); |
+ Jump(arg); // May emit merge code here. |
+ fall_through.Bind(); |
+ } else { |
+ DECLARE_ARGCHECK_VARS(arg); |
+ cgen_->frame()->Push(arg); |
+ DoBranch(cc, hint); |
+ *arg = cgen_->frame()->Pop(); |
+ ASSERT_ARGCHECK(arg); |
+ } |
+} |
+ |
#undef DECLARE_ARGCHECK_VARS |
#undef ASSERT_ARGCHECK |
+void JumpTarget::Bind(int mergable_elements) { |
+ DoBind(mergable_elements); |
+} |
+ |
+ |
void JumpTarget::Bind(Result* arg, int mergable_elements) { |
ASSERT(cgen_ != NULL); |
if (cgen_->has_valid_frame()) { |
cgen_->frame()->Push(arg); |
} |
- Bind(mergable_elements); |
+ DoBind(mergable_elements); |
*arg = cgen_->frame()->Pop(); |
} |
@@ -461,7 +501,7 @@ |
cgen_->frame()->Push(arg0); |
cgen_->frame()->Push(arg1); |
} |
- Bind(mergable_elements); |
+ DoBind(mergable_elements); |
*arg1 = cgen_->frame()->Pop(); |
*arg0 = cgen_->frame()->Pop(); |
} |
@@ -478,7 +518,7 @@ |
cgen_->frame()->Push(arg1); |
cgen_->frame()->Push(arg2); |
} |
- Bind(mergable_elements); |
+ DoBind(mergable_elements); |
*arg2 = cgen_->frame()->Pop(); |
*arg1 = cgen_->frame()->Pop(); |
*arg0 = cgen_->frame()->Pop(); |
@@ -498,7 +538,7 @@ |
cgen_->frame()->Push(arg2); |
cgen_->frame()->Push(arg3); |
} |
- Bind(mergable_elements); |
+ DoBind(mergable_elements); |
*arg3 = cgen_->frame()->Pop(); |
*arg2 = cgen_->frame()->Pop(); |
*arg1 = cgen_->frame()->Pop(); |
@@ -548,22 +588,32 @@ |
ASSERT(cgen_ != NULL); |
ASSERT(cgen_->has_valid_frame()); |
- // This is a break target so drop leftover statement state from the |
- // frame before merging. |
+ // Drop leftover statement state from the frame before merging. |
cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); |
- JumpTarget::Jump(); |
+ DoJump(); |
} |
+void BreakTarget::Jump(Result* arg) { |
+ ASSERT(cgen_ != NULL); |
+ ASSERT(cgen_->has_valid_frame()); |
+ |
+ // Drop leftover statement state from the frame before merging. |
+ cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); |
+ cgen_->frame()->Push(arg); |
+ DoJump(); |
+} |
+ |
+ |
void BreakTarget::Branch(Condition cc, Hint hint) { |
ASSERT(cgen_ != NULL); |
ASSERT(cgen_->has_valid_frame()); |
int count = cgen_->frame()->height() - expected_height_; |
if (count > 0) { |
- // We negate and branch here rather than using |
- // JumpTarget::Branch's negate and branch. This gives us a hook |
- // to remove statement state from the frame. |
+ // We negate and branch here rather than using DoBranch's negate |
+ // and branch. This gives us a hook to remove statement state |
+ // from the frame. |
JumpTarget fall_through(cgen_); |
// Branch to fall through will not negate, because it is a |
// forward-only target. |
@@ -571,14 +621,13 @@ |
Jump(); // May emit merge code here. |
fall_through.Bind(); |
} else { |
- JumpTarget::Branch(cc, hint); |
+ DoBranch(cc, hint); |
} |
} |
void BreakTarget::Bind(int mergable_elements) { |
#ifdef DEBUG |
- ASSERT(mergable_elements == kAllElements); |
ASSERT(cgen_ != NULL); |
// All the forward-reaching frames should have been adjusted at the |
// jumps to this target. |
@@ -587,16 +636,38 @@ |
reaching_frames_[i]->height() == expected_height_); |
} |
#endif |
- // This is a break target so we drop leftover statement state from |
- // the frame before merging, even on the fall through. This is |
- // because we can bind the return target with state on the frame. |
+ // Drop leftover statement state from the frame before merging, even |
+ // on the fall through. This is so we can bind the return target |
+ // with state on the frame. |
if (cgen_->has_valid_frame()) { |
cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); |
} |
- JumpTarget::Bind(mergable_elements); |
+ DoBind(mergable_elements); |
} |
+void BreakTarget::Bind(Result* arg, int mergable_elements) { |
+#ifdef DEBUG |
+ ASSERT(cgen_ != NULL); |
+ // All the forward-reaching frames should have been adjusted at the |
+ // jumps to this target. |
+ for (int i = 0; i < reaching_frames_.length(); i++) { |
+ ASSERT(reaching_frames_[i] == NULL || |
+ reaching_frames_[i]->height() == expected_height_ + 1); |
+ } |
+#endif |
+ // Drop leftover statement state from the frame before merging, even |
+ // on the fall through. This is so we can bind the return target |
+ // with state on the frame. |
+ if (cgen_->has_valid_frame()) { |
+ cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); |
+ cgen_->frame()->Push(arg); |
+ } |
+ DoBind(mergable_elements); |
+ *arg = cgen_->frame()->Pop(); |
+} |
+ |
+ |
// ------------------------------------------------------------------------- |
// ShadowTarget implementation. |