mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Lazy variable declarations. They are for speed tune.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user