summaryrefslogtreecommitdiff
path: root/vm_eval.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 16:59:05 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 16:59:05 +0000
commitcbd597e9bc05eac7249e91dcdb4f1c1c75a53cf5 (patch)
tree8f570f2e813466ef8fa0ac3f564a638b69164773 /vm_eval.c
parente8c234577fa7061a22f0dc515aefdc8dbc61f3b5 (diff)
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using parameters such as `op_id', 'op_argc', `blockiseq' and flag. These information are stored in rb_call_info_t at the compile time. This technique simplifies parameter passings at related function calls (~10% speedups for simple mehtod invocation at my machine). `rb_call_info_t' also has new function pointer variable `call'. This `call' variable enables to customize method (block) invocation process for each place. However, it always call `vm_call_general()' at this changes. `rb_call_info_t' also has temporary variables for method (block) invocation. * vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP VM_CALL macro. This flag indicates that this call can skip caller_setup (block arg and splat arg). * compile.c: catch up above changes. * iseq.c: catch up above changes (especially for TS_CALLINFO). * tool/instruction.rb: catch up above chagnes. * vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions parameters are changed. * vm_eval.c (vm_call0): ditto (it will be rewriten soon). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r--vm_eval.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/vm_eval.c b/vm_eval.c
index 1346aea3c3..c42703f78f 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -37,14 +37,23 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
{
const rb_method_definition_t *def = me->def;
VALUE val;
- VALUE klass = defined_class;
- const rb_block_t *blockptr = 0;
+ rb_call_info_t ci_entry, *ci = &ci_entry;
+
+ ci->flag = 0;
+ ci->mid = id;
+ ci->recv = recv;
+ ci->defined_class = defined_class;
+ ci->argc = argc;
+ ci->me = me;
if (!def) return Qnil;
if (th->passed_block) {
- blockptr = th->passed_block;
+ ci->blockptr = (rb_block_t *)th->passed_block;
th->passed_block = 0;
}
+ else {
+ ci->blockptr = 0;
+ }
again:
switch (def->type) {
@@ -59,20 +68,19 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
*reg_cfp->sp++ = argv[i];
}
- vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */,
- me, klass);
+ vm_setup_method(th, reg_cfp, ci);
th->cfp->flag |= VM_FRAME_FLAG_FINISH;
val = vm_exec(th);
break;
}
case VM_METHOD_TYPE_NOTIMPLEMENTED:
case VM_METHOD_TYPE_CFUNC: {
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
+ EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, ci->recv, ci->mid, ci->defined_class);
{
rb_control_frame_t *reg_cfp = th->cfp;
rb_control_frame_t *cfp =
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
- recv, klass, VM_ENVVAL_BLOCK_PTR(blockptr),
+ ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr),
0, reg_cfp->sp, 1, me);
cfp->me = me;
@@ -83,7 +91,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
}
vm_pop_frame(th);
}
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
+ EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class);
break;
}
case VM_METHOD_TYPE_ATTRSET: {
@@ -97,13 +105,13 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
break;
}
case VM_METHOD_TYPE_BMETHOD: {
- val = vm_call_bmethod(th, recv, argc, argv, blockptr, me, klass);
+ val = vm_call_bmethod(th, recv, argc, argv, ci->blockptr, me, ci->defined_class);
break;
}
case VM_METHOD_TYPE_ZSUPER: {
- klass = RCLASS_SUPER(klass);
- if (!klass || !(me = rb_method_entry(klass, id, &klass))) {
- return method_missing(recv, id, argc, argv, NOEX_SUPER);
+ ci->defined_class = RCLASS_SUPER(ci->defined_class);
+ if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, id, &ci->defined_class))) {
+ return method_missing(recv, ci->mid, ci->argc, argv, NOEX_SUPER);
}
RUBY_VM_CHECK_INTS(th);
if (!(def = me->def)) return Qnil;
@@ -113,10 +121,9 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
VALUE new_args = rb_ary_new4(argc, argv);
RB_GC_GUARD(new_args);
- rb_ary_unshift(new_args, ID2SYM(id));
- th->passed_block = blockptr;
- return rb_funcall2(recv, idMethodMissing,
- argc+1, RARRAY_PTR(new_args));
+ rb_ary_unshift(new_args, ID2SYM(ci->mid));
+ th->passed_block = ci->blockptr;
+ return rb_funcall2(ci->recv, idMethodMissing, argc+1, RARRAY_PTR(new_args));
}
case VM_METHOD_TYPE_OPTIMIZED: {
switch (def->body.optimize_type) {
@@ -126,7 +133,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
case OPTIMIZED_METHOD_TYPE_CALL: {
rb_proc_t *proc;
GetProcPtr(recv, proc);
- val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr);
+ val = rb_vm_invoke_proc(th, proc, argc, argv, ci->blockptr);
break;
}
default: