diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-04 10:10:07 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-04 10:10:07 +0000 |
commit | 09550d14b6fb6b9f3eae9de2949f4983c44e8396 (patch) | |
tree | 823ffbd883e683bc3da0d0d41038d03446770ad4 /proc.c | |
parent | 759773bf0e26265fcc209875b6e1c5584b91e16c (diff) | |
download | ruby-09550d14b6fb6b9f3eae9de2949f4983c44e8396.tar.gz |
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
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 52 |
1 files changed, 33 insertions, 19 deletions
@@ -1961,39 +1961,53 @@ method_callable_method_entry(const struct METHOD *data) 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); } /********************************************************************** |