From bf4626ed723a122c43a9edf73d68873ed4ca56d5 Mon Sep 17 00:00:00 2001 From: ko1 Date: Fri, 6 Jun 2008 14:48:07 +0000 Subject: * vm_insnhelper.c (vm_callee_setup_arg): check simple flag before calling setup_arg function(). this change reduce function call. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16868 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- vm_insnhelper.c | 164 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 84 insertions(+), 80 deletions(-) (limited to 'vm_insnhelper.c') diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 495213525e..8a8f032413 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -98,109 +98,111 @@ vm_pop_frame(rb_thread_t *th) /* method dispatch */ +#define VM_CALLEE_SETUP_ARG(ret, th, iseq, orig_argc, orig_argv, block) \ + if (LIKELY(iseq->arg_simple & 0x01)) { \ + /* simple check */ \ + if (orig_argc != iseq->argc) { \ + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", orig_argc, iseq->argc); \ + } \ + ret = 0; \ + } \ + else { \ + ret = vm_callee_setup_arg_complex(th, iseq, orig_argc, orig_argv, block); \ + } + static inline int -vm_callee_setup_arg(rb_thread_t *th, const rb_iseq_t * iseq, - int orig_argc, VALUE * orig_argv, const rb_block_t **block) +vm_callee_setup_arg_complex(rb_thread_t *th, const rb_iseq_t * iseq, + int orig_argc, VALUE * orig_argv, + const rb_block_t **block) { const int m = iseq->argc; + int argc = orig_argc; + VALUE *argv = orig_argv; + int opt_pc = 0; - if (LIKELY(iseq->arg_simple & 0x01)) { - /* simple check */ - if (orig_argc != m) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - orig_argc, m); - } - return 0; + th->mark_stack_len = argc + iseq->arg_size; + + /* mandatory */ + if (argc < (m + iseq->arg_post_len)) { /* check with post arg */ + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, m + iseq->arg_post_len); } - else { - int argc = orig_argc; - VALUE *argv = orig_argv; - int opt_pc = 0; - th->mark_stack_len = argc + iseq->arg_size; + argv += m; + argc -= m; - /* mandatory */ - if (argc < (m + iseq->arg_post_len)) { /* check with post arg */ - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - argc, m + iseq->arg_post_len); + /* post arguments */ + if (iseq->arg_post_len) { + if (!(orig_argc < iseq->arg_post_start)) { + VALUE *new_argv = ALLOCA_N(VALUE, argc); + MEMCPY(new_argv, argv, VALUE, argc); + argv = new_argv; } - argv += m; - argc -= m; + MEMCPY(&orig_argv[iseq->arg_post_start], &argv[argc -= iseq->arg_post_len], + VALUE, iseq->arg_post_len); + } - /* post arguments */ - if (iseq->arg_post_len) { - if (!(orig_argc < iseq->arg_post_start)) { - VALUE *new_argv = ALLOCA_N(VALUE, argc); - MEMCPY(new_argv, argv, VALUE, argc); - argv = new_argv; - } + /* opt arguments */ + if (iseq->arg_opts) { + const int opts = iseq->arg_opts - 1 /* no opt */; - MEMCPY(&orig_argv[iseq->arg_post_start], &argv[argc -= iseq->arg_post_len], - VALUE, iseq->arg_post_len); + if (iseq->arg_rest == -1 && argc > opts) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + orig_argc, m + opts + iseq->arg_post_len); } - /* opt arguments */ - if (iseq->arg_opts) { - const int opts = iseq->arg_opts - 1 /* no opt */; - - if (iseq->arg_rest == -1 && argc > opts) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - orig_argc, m + opts + iseq->arg_post_len); - } - - if (argc > opts) { - argc -= opts; - argv += opts; - opt_pc = iseq->arg_opt_table[opts]; /* no opt */ - } - else { - int i; - for (i = argc; iarg_opt_table[argc]; - argc = 0; - } + if (argc > opts) { + argc -= opts; + argv += opts; + opt_pc = iseq->arg_opt_table[opts]; /* no opt */ } - - /* rest arguments */ - if (iseq->arg_rest != -1) { - orig_argv[iseq->arg_rest] = rb_ary_new4(argc, argv); + else { + int i; + for (i = argc; iarg_opt_table[argc]; argc = 0; } + } - /* block arguments */ - if (block && iseq->arg_block != -1) { - VALUE blockval = Qnil; - const rb_block_t *blockptr = *block; + /* rest arguments */ + if (iseq->arg_rest != -1) { + orig_argv[iseq->arg_rest] = rb_ary_new4(argc, argv); + argc = 0; + } - if (argc != 0) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - orig_argc, m + iseq->arg_post_len); - } + /* block arguments */ + if (block && iseq->arg_block != -1) { + VALUE blockval = Qnil; + const rb_block_t *blockptr = *block; - if (blockptr) { - /* make Proc object */ - if (blockptr->proc == 0) { - rb_proc_t *proc; + if (argc != 0) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + orig_argc, m + iseq->arg_post_len); + } - blockval = vm_make_proc(th, th->cfp, blockptr); + if (blockptr) { + /* make Proc object */ + if (blockptr->proc == 0) { + rb_proc_t *proc; - GetProcPtr(blockval, proc); - *block = &proc->block; - } - else { - blockval = blockptr->proc; - } - } + blockval = vm_make_proc(th, th->cfp, blockptr); - orig_argv[iseq->arg_block] = blockval; /* Proc or nil */ + GetProcPtr(blockval, proc); + *block = &proc->block; + } + else { + blockval = blockptr->proc; + } } - th->mark_stack_len = 0; - return opt_pc; + orig_argv[iseq->arg_block] = blockval; /* Proc or nil */ } + + th->mark_stack_len = 0; + return opt_pc; } static inline int @@ -436,7 +438,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, /* TODO: eliminate it */ GetISeqPtr(iseqval, iseq); - opt_pc = vm_callee_setup_arg(th, iseq, argc, rsp, &blockptr); + VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, rsp, &blockptr); /* stack overflow check */ CHECK_STACK_OVERFLOW(cfp, iseq->stack_max); @@ -694,7 +696,9 @@ vm_yield_setup_args(rb_thread_t * const th, const rb_iseq_t *iseq, if (lambda) { /* call as method */ - return vm_callee_setup_arg(th, iseq, orig_argc, argv, &blockptr); + int opt_pc; + VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, orig_argc, argv, &blockptr); + return opt_pc; } else { int i; -- cgit v1.2.3