* 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
This commit is contained in:
parent
ca968ee45e
commit
7f052a7213
@ -1,3 +1,10 @@
|
|||||||
|
Mon Oct 15 02:51:16 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
Mon Oct 15 01:38:06 2012 Koichi Sasada <ko1@atdot.net>
|
Mon Oct 15 01:38:06 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
|
||||||
|
88
vm_eval.c
88
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 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,
|
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_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;
|
rb_call_info_t ci_entry, *ci = &ci_entry;
|
||||||
|
|
||||||
ci->flag = 0;
|
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->argc = argc;
|
||||||
ci->me = me;
|
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) {
|
if (th->passed_block) {
|
||||||
ci->blockptr = (rb_block_t *)th->passed_block;
|
ci->blockptr = (rb_block_t *)th->passed_block;
|
||||||
th->passed_block = 0;
|
th->passed_block = 0;
|
||||||
@ -56,15 +66,15 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
switch (def->type) {
|
switch (ci->me->def->type) {
|
||||||
case VM_METHOD_TYPE_ISEQ: {
|
case VM_METHOD_TYPE_ISEQ: {
|
||||||
rb_control_frame_t *reg_cfp = th->cfp;
|
rb_control_frame_t *reg_cfp = th->cfp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);
|
CHECK_STACK_OVERFLOW(reg_cfp, ci->argc + 1);
|
||||||
|
|
||||||
*reg_cfp->sp++ = recv;
|
*reg_cfp->sp++ = ci->recv;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < ci->argc; i++) {
|
||||||
*reg_cfp->sp++ = argv[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);
|
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 *reg_cfp = th->cfp;
|
||||||
rb_control_frame_t *cfp =
|
rb_control_frame_t *cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
|
||||||
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
|
ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr),
|
||||||
ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr),
|
0, reg_cfp->sp, 1, ci->me);
|
||||||
0, reg_cfp->sp, 1, me);
|
|
||||||
|
|
||||||
cfp->me = me;
|
cfp->me = ci->me;
|
||||||
val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
|
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) {
|
if (reg_cfp != th->cfp + 1) {
|
||||||
rb_bug("cfp consistency error - call0");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_ATTRSET: {
|
case VM_METHOD_TYPE_ATTRSET: {
|
||||||
rb_check_arity(argc, 1, 1);
|
rb_check_arity(ci->argc, 1, 1);
|
||||||
val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
|
val = rb_ivar_set(ci->recv, ci->me->def->body.attr.id, argv[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_IVAR: {
|
case VM_METHOD_TYPE_IVAR: {
|
||||||
rb_check_arity(argc, 0, 0);
|
rb_check_arity(ci->argc, 0, 0);
|
||||||
val = rb_attr_get(recv, def->body.attr.id);
|
val = rb_attr_get(ci->recv, ci->me->def->body.attr.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_BMETHOD: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_ZSUPER: {
|
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))) {
|
ci->defined_class = RCLASS_SUPER(ci->defined_class);
|
||||||
return method_missing(recv, ci->mid, ci->argc, argv, NOEX_SUPER);
|
|
||||||
|
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: {
|
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_GC_GUARD(new_args);
|
||||||
rb_ary_unshift(new_args, ID2SYM(ci->mid));
|
rb_ary_unshift(new_args, ID2SYM(ci->mid));
|
||||||
th->passed_block = ci->blockptr;
|
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: {
|
case VM_METHOD_TYPE_OPTIMIZED: {
|
||||||
switch (def->body.optimize_type) {
|
switch (ci->me->def->body.optimize_type) {
|
||||||
case OPTIMIZED_METHOD_TYPE_SEND:
|
case OPTIMIZED_METHOD_TYPE_SEND:
|
||||||
val = send_internal(argc, argv, recv, CALL_FCALL);
|
val = send_internal(ci->argc, argv, ci->recv, CALL_FCALL);
|
||||||
break;
|
break;
|
||||||
case OPTIMIZED_METHOD_TYPE_CALL: {
|
case OPTIMIZED_METHOD_TYPE_CALL: {
|
||||||
rb_proc_t *proc;
|
rb_proc_t *proc;
|
||||||
GetProcPtr(recv, proc);
|
GetProcPtr(ci->recv, proc);
|
||||||
val = rb_vm_invoke_proc(th, proc, argc, argv, ci->blockptr);
|
val = rb_vm_invoke_proc(th, proc, ci->argc, argv, ci->blockptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
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;
|
val = Qundef;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
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;
|
val = Qundef;
|
||||||
}
|
}
|
||||||
RUBY_VM_CHECK_INTS(th);
|
RUBY_VM_CHECK_INTS(th);
|
||||||
@ -282,8 +294,7 @@ check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
|
|||||||
|
|
||||||
args[0] = ID2SYM(mid);
|
args[0] = ID2SYM(mid);
|
||||||
args[1] = Qtrue;
|
args[1] = Qtrue;
|
||||||
if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me,
|
if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me, defined_class))) {
|
||||||
defined_class))) {
|
|
||||||
return Qundef;
|
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);
|
rb_id2name(mid), type, (void *)recv, flags, klass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rb_method_entry_get_with_refinements(Qnil, klass, mid,
|
return rb_method_entry_get_with_refinements(Qnil, klass, mid, defined_class_ptr);
|
||||||
defined_class_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user