| 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.
|
|
|
|
|