ruby-changes:42836
From: nobu <ko1@a...>
Date: Wed, 4 May 2016 18:13:31 +0900 (JST)
Subject: [ruby-changes:42836] nobu:r54910 (trunk): proc.c: separate rb_method_call_with_block
nobu 2016-05-04 19:10:07 +0900 (Wed, 04 May 2016) New Revision: 54910 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54910 Log: proc.c: separate rb_method_call_with_block * proc.c (rb_method_call_with_block): separate the cases with and without tag for optimization. Modified files: trunk/proc.c Index: proc.c =================================================================== --- proc.c (revision 54909) +++ proc.c (revision 54910) @@ -1961,39 +1961,53 @@ method_callable_method_entry(const struc https://github.com/ruby/ruby/blob/trunk/proc.c#L1961 return (const rb_callable_method_entry_t *)data->me; } -VALUE -rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE pass_procval) +static inline VALUE +call_method_data(rb_thread_t *th, const struct METHOD *data, + int argc, const VALUE *argv, VALUE pass_procval) +{ + th->passed_block = passed_block(pass_procval); + return rb_vm_call(th, data->recv, data->me->called_id, argc, argv, + method_callable_method_entry(data)); +} + +static VALUE +call_method_data_safe(rb_thread_t *th, const struct METHOD *data, + int argc, const VALUE *argv, VALUE pass_procval, + int safe) { VALUE result = Qnil; /* OK */ - struct METHOD *data; int state; - volatile int safe = -1; + + TH_PUSH_TAG(th); + if ((state = TH_EXEC_TAG()) == 0) { + result = call_method_data(th, data, argc, argv, pass_procval); + } + TH_POP_TAG(); + rb_set_safe_level_force(safe); + if (state) + JUMP_TAG(state); + return result; +} + +VALUE +rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE pass_procval) +{ + const struct METHOD *data; + rb_thread_t *const th = GET_THREAD(); TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } - PUSH_TAG(); if (OBJ_TAINTED(method)) { const int safe_level_to_run = RUBY_SAFE_LEVEL_MAX; - safe = rb_safe_level(); + int safe = rb_safe_level(); if (safe < safe_level_to_run) { rb_set_safe_level_force(safe_level_to_run); + return call_method_data_safe(th, data, argc, argv, pass_procval, safe); } } - if ((state = EXEC_TAG()) == 0) { - rb_thread_t *th = GET_THREAD(); - - th->passed_block = passed_block(pass_procval); - VAR_INITIALIZED(data); - result = rb_vm_call(th, data->recv, data->me->called_id, argc, argv, method_callable_method_entry(data)); - } - POP_TAG(); - if (safe >= 0) - rb_set_safe_level_force(safe); - if (state) - JUMP_TAG(state); - return result; + return call_method_data(th, data, argc, argv, pass_procval); } /********************************************************************** -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/