static inline int vm_yield_setup_args(rb_thread_t * const th, const rb_iseq_t *iseq, int argc, VALUE *argv, const rb_block_t *blockptr, int lambda) { if (0) { /* for debug */ printf(" argc: %d\n", argc); printf("iseq argc: %d\n", iseq->argc); printf("iseq opts: %d\n", iseq->arg_opts); printf("iseq rest: %d\n", iseq->arg_rest); printf("iseq post: %d\n", iseq->arg_post_len); printf("iseq blck: %d\n", iseq->arg_block); printf("iseq smpl: %d\n", iseq->arg_simple); printf(" lambda: %s\n", lambda ? "true" : "false"); } if (lambda) { /* call as method */ int opt_pc; VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, argv, &blockptr); return opt_pc; } else { return vm_yield_setup_block_args(th, iseq, argc, argv, blockptr); } }
static inline void vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, const int argc, const rb_block_t *blockptr, const VALUE flag, const VALUE iseqval, const VALUE recv) { rb_iseq_t *iseq; int opt_pc, i; VALUE *sp, *rsp = cfp->sp - argc; /* TODO: eliminate it */ GetISeqPtr(iseqval, iseq); VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, rsp, &blockptr); /* stack overflow check */ CHECK_STACK_OVERFLOW(cfp, iseq->stack_max); sp = rsp + 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++) { *sp++ = Qnil; } vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr, iseq->iseq_encoded + opt_pc, sp, 0, 0); cfp->sp = rsp - 1 /* recv */; } else { VALUE *p_rsp; th->cfp++; /* pop cf */ p_rsp = th->cfp->sp; /* copy arguments */ for (i=0; i < (sp - rsp); i++) { p_rsp[i] = rsp[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, recv, (VALUE) blockptr, iseq->iseq_encoded + opt_pc, sp, 0, 0); } }