Lazy variable declarations. They are for speed tune.

This commit is contained in:
Masaki Muranaka
2013-03-18 23:04:31 +09:00
parent f3db337814
commit 632875a618
+67 -62
View File
@@ -129,8 +129,9 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
static void
stack_extend(mrb_state *mrb, int room, int keep)
{
int size, off;
if (mrb->stack + room >= mrb->stend) {
int size, off;
mrb_value *oldbase = mrb->stbase;
size = mrb->stend - mrb->stbase;
@@ -275,14 +276,13 @@ mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
mrb_sym mid = mrb_intern(mrb, name);
va_list ap;
int i;
if (argc == 0) {
return mrb_funcall_argv(mrb, self, mid, 0, 0);
}
else if (argc == 1) {
mrb_value v;
va_list ap;
va_start(ap, argc);
v = va_arg(ap, mrb_value);
@@ -291,6 +291,8 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
}
else {
mrb_value argv[MRB_FUNCALL_ARGC_MAX];
va_list ap;
int i;
if (argc > MRB_FUNCALL_ARGC_MAX) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX);
@@ -308,11 +310,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk)
{
struct RProc *p;
struct RClass *c;
mrb_sym undef = 0;
mrb_callinfo *ci;
int n;
mrb_value val;
if (!mrb->jmp) {
@@ -325,66 +322,74 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
cipop(mrb);
}
mrb->jmp = 0;
return mrb_nil_value();
val = mrb_nil_value();
}
else {
mrb->jmp = &c_jmp;
/* recursive call */
val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
mrb->jmp = 0;
}
mrb->jmp = &c_jmp;
/* recursive call */
val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
mrb->jmp = 0;
return val;
}
else {
struct RProc *p;
struct RClass *c;
mrb_sym undef = 0;
mrb_callinfo *ci;
int n;
if (!mrb->stack) {
stack_init(mrb);
}
n = mrb->ci->nregs;
if (argc < 0) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
}
c = mrb_class(mrb, self);
p = mrb_method_search_vm(mrb, &c, mid);
if (!p) {
undef = mid;
mid = mrb_intern(mrb, "method_missing");
if (!mrb->stack) {
stack_init(mrb);
}
n = mrb->ci->nregs;
if (argc < 0) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
}
c = mrb_class(mrb, self);
p = mrb_method_search_vm(mrb, &c, mid);
n++; argc++;
}
ci = cipush(mrb);
ci->mid = mid;
ci->proc = p;
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = argc;
ci->target_class = p->target_class;
if (MRB_PROC_CFUNC_P(p)) {
ci->nregs = argc + 2;
}
else {
ci->nregs = p->body.irep->nregs + 2;
}
ci->acc = -1;
mrb->stack = mrb->stack + n;
if (!p) {
undef = mid;
mid = mrb_intern(mrb, "method_missing");
p = mrb_method_search_vm(mrb, &c, mid);
n++; argc++;
}
ci = cipush(mrb);
ci->mid = mid;
ci->proc = p;
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = argc;
ci->target_class = p->target_class;
if (MRB_PROC_CFUNC_P(p)) {
ci->nregs = argc + 2;
}
else {
ci->nregs = p->body.irep->nregs + 2;
}
ci->acc = -1;
mrb->stack = mrb->stack + n;
stack_extend(mrb, ci->nregs, 0);
mrb->stack[0] = self;
if (undef) {
mrb->stack[1] = mrb_symbol_value(undef);
stack_copy(mrb->stack+2, argv, argc-1);
}
else if (argc > 0) {
stack_copy(mrb->stack+1, argv, argc);
}
mrb->stack[argc+1] = blk;
stack_extend(mrb, ci->nregs, 0);
mrb->stack[0] = self;
if (undef) {
mrb->stack[1] = mrb_symbol_value(undef);
stack_copy(mrb->stack+2, argv, argc-1);
}
else if (argc > 0) {
stack_copy(mrb->stack+1, argv, argc);
}
mrb->stack[argc+1] = blk;
if (MRB_PROC_CFUNC_P(p)) {
int ai = mrb_gc_arena_save(mrb);
val = p->body.func(mrb, self);
mrb_gc_arena_restore(mrb, ai);
mrb_gc_protect(mrb, val);
mrb->stack = mrb->stbase + mrb->ci->stackidx;
cipop(mrb);
}
else {
val = mrb_run(mrb, p, self);
if (MRB_PROC_CFUNC_P(p)) {
int ai = mrb_gc_arena_save(mrb);
val = p->body.func(mrb, self);
mrb_gc_arena_restore(mrb, ai);
mrb_gc_protect(mrb, val);
mrb->stack = mrb->stbase + mrb->ci->stackidx;
cipop(mrb);
}
else {
val = mrb_run(mrb, p, self);
}
}
return val;
}