From 09550d14b6fb6b9f3eae9de2949f4983c44e8396 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 4 May 2016 10:10:07 +0000 Subject: [PATCH] proc.c: separate rb_method_call_with_block * proc.c (rb_method_call_with_block): separate the cases with and without tag for optimization. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54910 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- proc.c | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/proc.c b/proc.c index d67d61e178..9a252f4b95 100644 --- a/proc.c +++ b/proc.c @@ -1961,39 +1961,53 @@ method_callable_method_entry(const struct METHOD *data) return (const rb_callable_method_entry_t *)data->me; } +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 */ + int state; + + 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) { - VALUE result = Qnil; /* OK */ - struct METHOD *data; - int state; - volatile int safe = -1; + 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); } /**********************************************************************