summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-20 22:03:06 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-20 22:03:06 +0000
commitca61b4c4e007346d2a4bee51c998050b26c25991 (patch)
tree95d3959d682db7daf96a707c4c2673f4d9f58cad
parenta65ee87bf26a4823c61adf7301c10d6ccc8aefd0 (diff)
vm.c: vm_invoke_bmethod
* vm.c (vm_invoke_bmethod): bmethod does not need EXEC_TAG as it does not set safe level. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--vm.c29
-rw-r--r--vm_insnhelper.c2
2 files changed, 22 insertions, 9 deletions
diff --git a/vm.c b/vm.c
index fda3ec5ffd..75304c34aa 100644
--- a/vm.c
+++ b/vm.c
@@ -116,6 +116,9 @@ static void vm_collect_usage_register(int reg, int isset);
#endif
static VALUE
+vm_invoke_bmethod(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
+ int argc, const VALUE *argv, const rb_block_t *blockptr);
+static VALUE
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
int argc, const VALUE *argv, const rb_block_t *blockptr);
@@ -896,17 +899,13 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class
TH_PUSH_TAG(th);
if ((state = EXEC_TAG()) == 0) {
- if (!proc->is_from_method) {
- th->safe_level = proc->safe_level;
- }
+ th->safe_level = proc->safe_level;
val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0,
defined_class, 0);
}
TH_POP_TAG();
- if (!proc->is_from_method) {
- th->safe_level = stored_safe;
- }
+ th->safe_level = stored_safe;
if (state) {
JUMP_TAG(state);
@@ -914,12 +913,26 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class
return val;
}
+static VALUE
+vm_invoke_bmethod(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
+ int argc, const VALUE *argv, const rb_block_t *blockptr)
+{
+ return invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0,
+ defined_class, 0);
+}
+
VALUE
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
int argc, const VALUE *argv, const rb_block_t *blockptr)
{
- return vm_invoke_proc(th, proc, proc->block.self, proc->block.klass,
- argc, argv, blockptr);
+ VALUE self = proc->block.self;
+ VALUE defined_class = proc->block.klass;
+ if (proc->is_from_method) {
+ return vm_invoke_bmethod(th, proc, self, defined_class, argc, argv, blockptr);
+ }
+ else {
+ return vm_invoke_proc(th, proc, self, defined_class, argc, argv, blockptr);
+ }
}
/* special variable */
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 365a8bf773..712a90a04e 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1539,7 +1539,7 @@ vm_call_bmethod_body(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
/* control block frame */
th->passed_bmethod_me = ci->me;
GetProcPtr(ci->me->def->body.proc, proc);
- val = vm_invoke_proc(th, proc, ci->recv, ci->defined_class, ci->argc, argv, ci->blockptr);
+ val = vm_invoke_bmethod(th, proc, ci->recv, ci->defined_class, ci->argc, argv, ci->blockptr);
return val;
}