diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-28 04:05:36 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-28 04:05:36 +0000 |
commit | d50483df23383caf098c23c25c133f4eefca5917 (patch) | |
tree | d2e94e5ec61e548687a0b67d06a0662063650a31 /vm_insnhelper.c | |
parent | 8124d67988ea5aa995f1721446c229a83a8b356d (diff) |
* vm_core.h: remove rb_control_frame_t::bp (bp: base pointer).
`bp' can be calculate by `sp' (stack pointer) of previous frame.
Now, `bp_check' field is remained for debug. You can eliminate
this field by setting VM_DEBUG_BP_CHECK as 0.
* vm_insnhelper.c (vm_base_ptr): add `vm_base_ptr(cfp).
This function calculates base pointer from cfp.
* vm_insnhelper.c (vm_setup_method): push `recv' value on top of
value stack (before method parameters).
This change is for keeping consistency with normal method dispatch.
* insns.def: fix to use vm_base_ptr().
* vm.c (vm_exec): ditto.
* vm_dump.c: remove `bp' related dumps.
* cont.c (fiber_init): fix to check VM_DEBUG_BP_CHECK.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37043 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 46ef7e1a1c..808d73cb9f 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -57,7 +57,9 @@ vm_push_frame(rb_thread_t *th, cfp->pc = (VALUE *)pc; cfp->sp = sp + 1; - cfp->bp = sp + 1; +#if VM_DEBUG_BP_CHECK + cfp->bp_check = sp + 1; +#endif cfp->ep = sp; cfp->iseq = (rb_iseq_t *) iseq; cfp->flag = type; @@ -494,19 +496,16 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, const rb_method_entry_t *me, VALUE defined_class) { int opt_pc, i; - VALUE *sp, *rsp = cfp->sp - argc; + VALUE *sp, *argv = cfp->sp - argc; rb_iseq_t *iseq = me->def->body.iseq; - VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, rsp, &blockptr); + VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, argv, &blockptr); /* stack overflow check */ CHECK_STACK_OVERFLOW(cfp, iseq->stack_max); - - sp = rsp + iseq->arg_size; + sp = argv + iseq->arg_size; if (LIKELY(!(flag & VM_CALL_TAILCALL_BIT))) { - if (0) printf("local_size: %d, arg_size: %d\n", - iseq->local_size, iseq->arg_size); /* clear local variables */ for (i = 0; i < iseq->local_size - iseq->arg_size; i++) { @@ -517,30 +516,36 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, VM_ENVVAL_BLOCK_PTR(blockptr), iseq->iseq_encoded + opt_pc, sp, 0, me); - cfp->sp = rsp - 1 /* recv */; + cfp->sp = argv - 1 /* recv */; } else { - VALUE *p_rsp; - int is_finish_frame = VM_FRAME_TYPE_FINISH_P(cfp); + VALUE *src_argv = argv; + VALUE *sp_orig; + int src_argc = sp - src_argv; + VALUE finish_flag = VM_FRAME_TYPE_FINISH_P(cfp) ? VM_FRAME_FLAG_FINISH : 0; + cfp = th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); /* pop cf */ - th->cfp++; /* pop cf */ - p_rsp = th->cfp->sp; + sp = sp_orig = cfp->sp; + + /* push self */ + sp[0] = recv; + sp++; /* copy arguments */ - for (i=0; i < (sp - rsp); i++) { - p_rsp[i] = rsp[i]; + for (i=0; i < src_argc; i++) { + *sp++ = src_argv[i]; } - sp -= rsp - p_rsp; - /* clear local variables */ for (i = 0; i < iseq->local_size - iseq->arg_size; i++) { *sp++ = Qnil; } - vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | (is_finish_frame ? VM_FRAME_FLAG_FINISH : 0), + vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag, recv, defined_class, VM_ENVVAL_BLOCK_PTR(blockptr), iseq->iseq_encoded + opt_pc, sp, 0, me); + + cfp->sp = sp_orig; } } @@ -1902,3 +1907,27 @@ double_cmp_ge(double a, double b) CHECK_CMP_NAN(a, b); return a >= b ? Qtrue : Qfalse; } + +static VALUE * +vm_base_ptr(rb_control_frame_t *cfp) +{ + rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1; + + if (cfp->iseq->type == ISEQ_TYPE_METHOD) { + /* adjust `self' */ + bp += 1; + } + +#if VM_DEBUG_BP_CHECK + if (bp != cfp->bp_check) { + fprintf(stderr, "bp_check: %d, bp: %d\n", + cfp->bp_check - GET_THREAD()->stack, + bp - GET_THREAD()->stack); + rb_bug("vm_base_ptr: unreachable"); + } +#endif + + return bp; +} + |