summaryrefslogtreecommitdiff
path: root/vm_eval.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 17:54:21 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 17:54:21 +0000
commit7f052a7213e21c800fa4bd80f61e7903804bcf4f (patch)
tree0d3f09463a017b44a5ffe2c6196c65a0ab9924bc /vm_eval.c
parentca968ee45eabd35e21c1f3f602ae33816ae64d23 (diff)
* vm_eval.c (vm_call0_body): add new function.
`vm_call0()' makes call_info struct and calls `vm_call0_body()' with this struct. In near future, `vm_call0()' will be removed because all of `vm_call0()' users setup call_info struct by itself. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37183 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r--vm_eval.c88
1 files changed, 49 insertions, 39 deletions
diff --git a/vm_eval.c b/vm_eval.c
index c42703f78f..b05d62f6b5 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -31,12 +31,12 @@ typedef enum call_type {
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
-static inline VALUE
+static VALUE vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv);
+
+static VALUE
vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
const rb_method_entry_t *me, VALUE defined_class)
{
- const rb_method_definition_t *def = me->def;
- VALUE val;
rb_call_info_t ci_entry, *ci = &ci_entry;
ci->flag = 0;
@@ -46,7 +46,17 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
ci->argc = argc;
ci->me = me;
- if (!def) return Qnil;
+ return vm_call0_body(th, ci, argv);
+}
+
+/* `ci' should pointe temporal value (on stack value) */
+static VALUE
+vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
+{
+ VALUE val;
+
+ if (!ci->me->def) return Qnil;
+
if (th->passed_block) {
ci->blockptr = (rb_block_t *)th->passed_block;
th->passed_block = 0;
@@ -56,15 +66,15 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
}
again:
- switch (def->type) {
+ switch (ci->me->def->type) {
case VM_METHOD_TYPE_ISEQ: {
rb_control_frame_t *reg_cfp = th->cfp;
int i;
- CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);
+ CHECK_STACK_OVERFLOW(reg_cfp, ci->argc + 1);
- *reg_cfp->sp++ = recv;
- for (i = 0; i < argc; i++) {
+ *reg_cfp->sp++ = ci->recv;
+ for (i = 0; i < ci->argc; i++) {
*reg_cfp->sp++ = argv[i];
}
@@ -78,13 +88,13 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
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,
- ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr),
- 0, reg_cfp->sp, 1, me);
+ rb_control_frame_t *cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
+ ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr),
+ 0, reg_cfp->sp, 1, ci->me);
- cfp->me = me;
- val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
+ cfp->me = ci->me;
+ val = call_cfunc(ci->me->def->body.cfunc.func, ci->recv,
+ ci->me->def->body.cfunc.argc, ci->argc, argv);
if (reg_cfp != th->cfp + 1) {
rb_bug("cfp consistency error - call0");
@@ -95,56 +105,58 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
break;
}
case VM_METHOD_TYPE_ATTRSET: {
- rb_check_arity(argc, 1, 1);
- val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
+ rb_check_arity(ci->argc, 1, 1);
+ val = rb_ivar_set(ci->recv, ci->me->def->body.attr.id, argv[0]);
break;
}
case VM_METHOD_TYPE_IVAR: {
- rb_check_arity(argc, 0, 0);
- val = rb_attr_get(recv, def->body.attr.id);
+ rb_check_arity(ci->argc, 0, 0);
+ val = rb_attr_get(ci->recv, ci->me->def->body.attr.id);
break;
}
case VM_METHOD_TYPE_BMETHOD: {
- val = vm_call_bmethod(th, recv, argc, argv, ci->blockptr, me, ci->defined_class);
+ val = vm_call_bmethod(th, ci->recv, ci->argc, argv, ci->blockptr, ci->me, ci->defined_class);
break;
}
- case VM_METHOD_TYPE_ZSUPER: {
- 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);
+ case VM_METHOD_TYPE_ZSUPER:
+ {
+ ci->defined_class = RCLASS_SUPER(ci->defined_class);
+
+ if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, ci->mid, &ci->defined_class))) {
+ return method_missing(ci->recv, ci->mid, ci->argc, argv, NOEX_SUPER);
+ }
+ RUBY_VM_CHECK_INTS(th);
+ if (!ci->me->def) return Qnil;
+ goto again;
}
- RUBY_VM_CHECK_INTS(th);
- if (!(def = me->def)) return Qnil;
- goto again;
- }
case VM_METHOD_TYPE_MISSING: {
- VALUE new_args = rb_ary_new4(argc, argv);
+ VALUE new_args = rb_ary_new4(ci->argc, argv);
RB_GC_GUARD(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));
+ return rb_funcall2(ci->recv, idMethodMissing, ci->argc+1, RARRAY_PTR(new_args));
}
case VM_METHOD_TYPE_OPTIMIZED: {
- switch (def->body.optimize_type) {
+ switch (ci->me->def->body.optimize_type) {
case OPTIMIZED_METHOD_TYPE_SEND:
- val = send_internal(argc, argv, recv, CALL_FCALL);
+ val = send_internal(ci->argc, argv, ci->recv, CALL_FCALL);
break;
case OPTIMIZED_METHOD_TYPE_CALL: {
rb_proc_t *proc;
- GetProcPtr(recv, proc);
- val = rb_vm_invoke_proc(th, proc, argc, argv, ci->blockptr);
+ GetProcPtr(ci->recv, proc);
+ val = rb_vm_invoke_proc(th, proc, ci->argc, argv, ci->blockptr);
break;
}
default:
- rb_bug("vm_call0: unsupported optimized method type (%d)", def->body.optimize_type);
+ rb_bug("vm_call0: unsupported optimized method type (%d)", ci->me->def->body.optimize_type);
val = Qundef;
break;
}
break;
}
default:
- rb_bug("vm_call0: unsupported method type (%d)", def->type);
+ rb_bug("vm_call0: unsupported method type (%d)", ci->me->def->type);
val = Qundef;
}
RUBY_VM_CHECK_INTS(th);
@@ -282,8 +294,7 @@ check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
args[0] = ID2SYM(mid);
args[1] = Qtrue;
- if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me,
- defined_class))) {
+ if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me, defined_class))) {
return Qundef;
}
}
@@ -392,8 +403,7 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
rb_id2name(mid), type, (void *)recv, flags, klass);
}
}
- return rb_method_entry_get_with_refinements(Qnil, klass, mid,
- defined_class_ptr);
+ return rb_method_entry_get_with_refinements(Qnil, klass, mid, defined_class_ptr);
}
static inline int