1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2016-05-04 10:10:07 +00:00
parent 759773bf0e
commit 09550d14b6

52
proc.c
View file

@ -1961,39 +1961,53 @@ method_callable_method_entry(const struct METHOD *data)
return (const rb_callable_method_entry_t *)data->me; 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 VALUE
rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE pass_procval) rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE pass_procval)
{ {
VALUE result = Qnil; /* OK */ const struct METHOD *data;
struct METHOD *data; rb_thread_t *const th = GET_THREAD();
int state;
volatile int safe = -1;
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
if (data->recv == Qundef) { if (data->recv == Qundef) {
rb_raise(rb_eTypeError, "can't call unbound method; bind first"); rb_raise(rb_eTypeError, "can't call unbound method; bind first");
} }
PUSH_TAG();
if (OBJ_TAINTED(method)) { if (OBJ_TAINTED(method)) {
const int safe_level_to_run = RUBY_SAFE_LEVEL_MAX; 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) { if (safe < safe_level_to_run) {
rb_set_safe_level_force(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) { return call_method_data(th, data, argc, argv, pass_procval);
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;
} }
/********************************************************************** /**********************************************************************