summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-19 10:38:30 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-19 10:38:30 +0000
commitf4dbc7a3849988ebe75d3e1031aa50441347c497 (patch)
tree9750044142c879b0abc569e92dedaeeee5158d12 /vm_method.c
parent0fc7f4bb304ad07e8172f868d885112a1dcceb0f (diff)
* method.h (rb_method_cfunc_t::invoker): add new field (func ptr)
`invoker'. `invoker' function invoke cfunc body (rb_method_cfunc_t::func). `invoker' is set at method definition timing. With this change, the big `switch' (branch) in `call_cfunc()' is no longer needed. However, the performance benefit is only a bit. * vm_core.h (rb_call_info_t::aux::func): add a new field to store cfunc body function pointer. * vm_method.c (call_cfunc_invoker_func): add a new function which returns a suitable invoke function. * vm_method.c (setup_method_cfunc_struct): added. * vm_method.c (rb_add_method): fix to set `invoker'. * vm_eval.c (vm_call0_body): catch up above changes. * vm_insnhelper.c (call_cfunc): removed. * vm_insnhelper.c (vm_call_cfunc): fix to call cfunc body with `invoker' function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37268 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/vm_method.c b/vm_method.c
index 058b03dac6..6cec0ab1f8 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -303,6 +303,41 @@ method_added(VALUE klass, ID mid)
}
}
+static VALUE
+(*call_cfunc_invoker_func(int argc))(const rb_call_info_t *, const VALUE *)
+{
+ switch (argc) {
+ case -2: return call_cfunc_m2;
+ case -1: return call_cfunc_m1;
+ case 0: return call_cfunc_0;
+ case 1: return call_cfunc_1;
+ case 2: return call_cfunc_2;
+ case 3: return call_cfunc_3;
+ case 4: return call_cfunc_4;
+ case 5: return call_cfunc_5;
+ case 6: return call_cfunc_6;
+ case 7: return call_cfunc_7;
+ case 8: return call_cfunc_8;
+ case 9: return call_cfunc_9;
+ case 10: return call_cfunc_10;
+ case 11: return call_cfunc_11;
+ case 12: return call_cfunc_12;
+ case 13: return call_cfunc_13;
+ case 14: return call_cfunc_14;
+ case 15: return call_cfunc_15;
+ default:
+ rb_bug("call_cfunc_func: unsupported length: %d", argc);
+ }
+}
+
+static void
+setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(), int argc)
+{
+ cfunc->func = func;
+ cfunc->argc = argc;
+ cfunc->invoker = call_cfunc_invoker_func(argc);
+}
+
rb_method_entry_t *
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
{
@@ -321,7 +356,10 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
break;
case VM_METHOD_TYPE_CFUNC:
case VM_METHOD_TYPE_CFUNC_FRAMELESS:
- def->body.cfunc = *(rb_method_cfunc_t *)opts;
+ {
+ rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
+ setup_method_cfunc_struct(&def->body.cfunc, cfunc->func, cfunc->argc);
+ }
break;
case VM_METHOD_TYPE_ATTRSET:
case VM_METHOD_TYPE_IVAR:
@@ -338,8 +376,7 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
def->body.proc = (VALUE)opts;
break;
case VM_METHOD_TYPE_NOTIMPLEMENTED:
- def->body.cfunc.func = rb_f_notimplement;
- def->body.cfunc.argc = -1;
+ setup_method_cfunc_struct(&def->body.cfunc, rb_f_notimplement, -1);
break;
case VM_METHOD_TYPE_OPTIMIZED:
def->body.optimize_type = (enum method_optimized_type)opts;