From f4dbc7a3849988ebe75d3e1031aa50441347c497 Mon Sep 17 00:00:00 2001 From: ko1 Date: Fri, 19 Oct 2012 10:38:30 +0000 Subject: * 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 --- vm_method.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'vm_method.c') 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; -- cgit v1.2.3