summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-06 14:48:07 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-06 14:48:07 +0000
commitbf4626ed723a122c43a9edf73d68873ed4ca56d5 (patch)
tree140d75adfdb1c8fb78e81b5f8f4ff37125fafb8e /vm_insnhelper.c
parent12cec48616032e92c640614d45cc01843bb3db17 (diff)
* 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
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c164
1 files changed, 84 insertions, 80 deletions
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; i<opts; i++) {
- orig_argv[i + m] = Qnil;
- }
- opt_pc = iseq->arg_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; i<opts; i++) {
+ orig_argv[i + m] = Qnil;
+ }
+ opt_pc = iseq->arg_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;