summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-02 23:14:21 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-02 23:14:21 +0000
commit831e33c7809a92da6d14f0e518f960034c5dabd0 (patch)
treea0308f28d043d963e8e2b21d68f0633655105693 /vm_insnhelper.c
parent5d1f152fa342f6bb5fa9b546e3971843ee81c6b1 (diff)
* vm_core.h: change iseq parameter data structure.
https://bugs.ruby-lang.org/issues/10440#change-49694 * change terminology `arg' to `param'. * move rb_iseq_t::arg_* to rb_iseq_t::param. * move rb_iseq_t::arg_size to rb_iseq_t::param::size. * move rb_iseq_t::argc to rb_iseq_t::param::lead_num. * move rb_iseq_t::arg_opts to rb_iseq_t::param::opt_num. * move rb_iseq_t::arg_rest to rb_iseq_t::param::rest_start. * move rb_iseq_t::arg_post_num to rb_iseq_t::param::post_num. * move rb_iseq_t::arg_post_start to rb_iseq_t::param::post_start. * move rb_iseq_t::arg_block to rb_iseq_t::param::block_start. * move rb_iseq_t::arg_keyword* to rb_iseq_t::param::keyword. rb_iseq_t::param::keyword is allocated only when keyword parameters are available. * introduce rb_iseq_t::param::flags to represent parameter availability. For example, rb_iseq_t::param::flags::has_kw represents that this iseq has keyword parameters and rb_iseq_t::param::keyword is allocated. We don't need to compare with -1 to check availability. * remove rb_iseq_t::arg_simple. * compile.c: catch up this change. * iseq.c: ditto. * proc.c: ditto. * vm.c, vm_args.c, vm_dump.c, vm_insnhelper.c: ditto. * iseq.c (iseq_data_to_ary): support keyword argument. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 95d232e740..d67fd50db5 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1008,19 +1008,30 @@ vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *i
int i;
long len = RARRAY_LEN(ary);
- CHECK_VM_STACK_OVERFLOW(cfp, iseq->argc);
+ CHECK_VM_STACK_OVERFLOW(cfp, iseq->param.lead_num);
- for (i=0; i<len && i<iseq->argc; i++) {
+ for (i=0; i<len && i<iseq->param.lead_num; i++) {
argv[i] = RARRAY_AREF(ary, i);
}
return i;
}
+static inline int
+simple_iseq_p(const rb_iseq_t *iseq)
+{
+ return iseq->param.flags.has_opt == FALSE &&
+ iseq->param.flags.has_rest == FALSE &&
+ iseq->param.flags.has_post == FALSE &&
+ iseq->param.flags.has_kw == FALSE &&
+ iseq->param.flags.has_kwrest == FALSE &&
+ iseq->param.flags.has_block == FALSE;
+}
+
static inline void
vm_callee_setup_block_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *argv, const enum arg_setup_type arg_setup_type)
{
- if (LIKELY(iseq->arg_simple & 0x01)) {
+ if (LIKELY(simple_iseq_p(iseq))) {
rb_control_frame_t *cfp = th->cfp;
VALUE arg0;
@@ -1028,31 +1039,32 @@ vm_callee_setup_block_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *
if (arg_setup_type == arg_setup_block &&
ci->argc == 1 &&
- iseq->argc > 0 && !(iseq->arg_simple & 0x02) &&
+ iseq->param.flags.has_lead &&
+ !iseq->param.flags.ambiguous_param0 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) {
ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
}
- if (ci->argc != iseq->argc) {
+ if (ci->argc != iseq->param.lead_num) {
if (arg_setup_type == arg_setup_block) {
- if (ci->argc < iseq->argc) {
+ if (ci->argc < iseq->param.lead_num) {
int i;
- CHECK_VM_STACK_OVERFLOW(cfp, iseq->argc);
- for (i=ci->argc; i<iseq->argc; i++) argv[i] = Qnil;
- ci->argc = iseq->argc; /* fill rest parameters */
+ CHECK_VM_STACK_OVERFLOW(cfp, iseq->param.lead_num);
+ for (i=ci->argc; i<iseq->param.lead_num; i++) argv[i] = Qnil;
+ ci->argc = iseq->param.lead_num; /* fill rest parameters */
}
- else if (ci->argc > iseq->argc) {
- ci->argc = iseq->argc; /* simply truncate arguments */
+ else if (ci->argc > iseq->param.lead_num) {
+ ci->argc = iseq->param.lead_num; /* simply truncate arguments */
}
}
else if (arg_setup_type == arg_setup_lambda &&
ci->argc == 1 &&
!NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv)) &&
- RARRAY_LEN(arg0) == iseq->argc) {
+ RARRAY_LEN(arg0) == iseq->param.lead_num) {
ci->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
}
else {
- argument_error(iseq, ci->argc, iseq->argc, iseq->argc);
+ argument_error(iseq, ci->argc, iseq->param.lead_num, iseq->param.lead_num);
}
}
@@ -1066,13 +1078,13 @@ vm_callee_setup_block_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *
static inline void
vm_callee_setup_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *argv)
{
- if (LIKELY(iseq->arg_simple & 0x01)) {
+ if (LIKELY(simple_iseq_p(iseq))) {
rb_control_frame_t *cfp = th->cfp;
CALLER_SETUP_ARG(cfp, ci); /* splat arg */
- if (ci->argc != iseq->argc) {
- argument_error(iseq, ci->argc, iseq->argc, iseq->argc);
+ if (ci->argc != iseq->param.lead_num) {
+ argument_error(iseq, ci->argc, iseq->param.lead_num, iseq->param.lead_num);
}
ci->aux.opt_pc = 0;
@@ -1110,10 +1122,10 @@ vm_call_iseq_setup_normal(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info
int i, local_size;
VALUE *argv = cfp->sp - ci->argc;
rb_iseq_t *iseq = ci->me->def->body.iseq;
- VALUE *sp = argv + iseq->arg_size;
+ VALUE *sp = argv + iseq->param.size;
/* clear local variables (arg_size...local_size) */
- for (i = iseq->arg_size, local_size = iseq->local_size; i < local_size; i++) {
+ for (i = iseq->param.size, local_size = iseq->local_size; i < local_size; i++) {
*sp++ = Qnil;
}
@@ -1146,12 +1158,12 @@ vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_in
sp++;
/* copy arguments */
- for (i=0; i < iseq->arg_size; i++) {
+ for (i=0; i < iseq->param.size; i++) {
*sp++ = src_argv[i];
}
/* clear local variables */
- for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
+ for (i = 0; i < iseq->local_size - iseq->param.size; i++) {
*sp++ = Qnil;
}
@@ -2031,7 +2043,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
if (BUILTIN_TYPE(iseq) != T_NODE) {
int opt_pc;
- const int arg_size = iseq->arg_size;
+ const int arg_size = iseq->param.size;
int is_lambda = block_proc_is_lambda(block->proc);
VALUE * const rsp = GET_SP() - ci->argc;