diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-11-20 06:21:22 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-11-20 18:33:41 +0900 |
| commit | 8f2c62407c0659d84126545e19505a851059e750 (patch) | |
| tree | 7a073d389fc2f5fc7c14f86ffa96d0145bff9f82 /src | |
| parent | 6c06e77446f3cca4a92b3df8d0a5fe568c5fdc65 (diff) | |
| download | mruby-8f2c62407c0659d84126545e19505a851059e750.tar.gz mruby-8f2c62407c0659d84126545e19505a851059e750.zip | |
Add `MRB_METHOD_TABLE_INLINE` option.
Now the method tables (in classes/modules and caches) keeps C function
pointers without wrapping in `struct RProc` objects. For the sake of
portability, `mrb_method_t` is represented by the struct and union, but
if the most significant bit of the pointer is not used by the platform,
`mrb_method_t` should be packed in `uintptr_t` to reduce memory usage.
`MRB_METHOD_TABLE_INLINE` is turned on by default for linux.
Diffstat (limited to 'src')
| -rw-r--r-- | src/class.c | 88 | ||||
| -rw-r--r-- | src/kernel.c | 18 | ||||
| -rw-r--r-- | src/proc.c | 19 | ||||
| -rw-r--r-- | src/vm.c | 98 |
4 files changed, 129 insertions, 94 deletions
diff --git a/src/class.c b/src/class.c index fb394cc89..c65038b87 100644 --- a/src/class.c +++ b/src/class.c @@ -16,7 +16,7 @@ #include <mruby/data.h> #include <mruby/istruct.h> -KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal) +KHASH_DEFINE(mt, mrb_sym, mrb_method_t, TRUE, kh_int_hash_func, kh_int_hash_equal) void mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) @@ -27,9 +27,11 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) if (!h) return; for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)) { - struct RProc *m = kh_value(h, k); - if (m) { - mrb_gc_mark(mrb, (struct RBasic*)m); + mrb_method_t m = kh_value(h, k); + + if (MRB_METHOD_PROC_P(m)) { + struct RProc *p = MRB_METHOD_PROC(m); + mrb_gc_mark(mrb, (struct RBasic*)p); } } } @@ -419,7 +421,7 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s } MRB_API void -mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) +mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m) { khash_t(mt) *h; khiter_t k; @@ -434,8 +436,11 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro } if (!h) h = c->mt = kh_init(mt, mrb); k = kh_put(mt, mrb, h, mid); - kh_value(h, k) = p; - if (p) { + kh_value(h, k) = m; + if (MRB_METHOD_PROC_P(m) && !MRB_METHOD_UNDEF_P(m)) { + struct RProc *p = MRB_METHOD_PROC(m); + + p->flags |= MRB_PROC_SCOPE; p->c = NULL; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); MRB_PROC_SET_TARGET_CLASS(p, c); @@ -447,13 +452,11 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) { - struct RProc *p; + mrb_method_t m; int ai = mrb_gc_arena_save(mrb); - p = mrb_proc_new_cfunc(mrb, func); - MRB_PROC_SET_TARGET_CLASS(p, c); - p->flags |= MRB_PROC_SCOPE; - mrb_define_method_raw(mrb, c, mid, p); + MRB_METHOD_FROM_FUNC(m, func); + mrb_define_method_raw(mrb, c, mid, m); mrb_gc_arena_restore(mrb, ai); } @@ -1383,11 +1386,11 @@ mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid) } #endif -MRB_API struct RProc* +MRB_API mrb_method_t mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) { khiter_t k; - struct RProc *m; + mrb_method_t m; struct RClass *c = *cp; #ifdef MRB_METHOD_CACHE struct RClass *oc = c; @@ -1406,7 +1409,7 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) k = kh_get(mt, mrb, h, mid); if (k != kh_end(h)) { m = kh_value(h, k); - if (!m) break; + if (MRB_METHOD_UNDEF_P(m)) break; *cp = c; #ifdef MRB_METHOD_CACHE mc->c = oc; @@ -1418,16 +1421,17 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) } c = c->super; } - return NULL; /* no method */ + MRB_METHOD_FROM_PROC(m, NULL); + return m; /* no method */ } -MRB_API struct RProc* +MRB_API mrb_method_t mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) { - struct RProc *m; + mrb_method_t m; m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0); if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); @@ -1458,6 +1462,8 @@ mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) for (i=0; i<argc; i++) { mrb_value name, str; mrb_sym method, sym; + struct RProc *p; + mrb_method_t m; method = to_sym(mrb, argv[i]); name = mrb_sym2str(mrb, method); @@ -1467,8 +1473,9 @@ mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) sym = mrb_intern_str(mrb, str); mrb_iv_check(mrb, sym); name = mrb_symbol_value(sym); - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name)); + p = mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name); + MRB_METHOD_FROM_PROC(m, p); + mrb_define_method_raw(mrb, c, method, m); mrb_gc_arena_restore(mrb, ai); } return mrb_nil_value(); @@ -1498,6 +1505,8 @@ mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) for (i=0; i<argc; i++) { mrb_value name, str, attr; mrb_sym method, sym; + struct RProc *p; + mrb_method_t m; method = to_sym(mrb, argv[i]); @@ -1516,8 +1525,9 @@ mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) mrb_str_cat_lit(mrb, str, "="); method = mrb_intern_str(mrb, str); - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr)); + p = mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr); + MRB_METHOD_FROM_PROC(m, p); + mrb_define_method_raw(mrb, c, method, m); mrb_gc_arena_restore(mrb, ai); } return mrb_nil_value(); @@ -1560,15 +1570,16 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv) mrb_value *argv; mrb_int argc; mrb_sym init; - struct RProc *p; + mrb_method_t m; mrb_get_args(mrb, "*&", &argv, &argc, &blk); obj = mrb_instance_alloc(mrb, cv); init = mrb_intern_lit(mrb, "initialize"); - p = mrb_method_search(mrb, mrb_class(mrb, obj), init); - if (MRB_PROC_CFUNC_P(p)) { - if (p->body.func != mrb_bob_init) { - p->body.func(mrb, obj); + m = mrb_method_search(mrb, mrb_class(mrb, obj), init); + if (MRB_METHOD_CFUNC_P(m)) { + mrb_func_t f = MRB_METHOD_CFUNC(m); + if (f != mrb_bob_init) { + f(mrb, obj); } } else { @@ -1703,10 +1714,10 @@ mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self) MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid) { - struct RProc *m; + mrb_method_t m; m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { return FALSE; } return TRUE; @@ -1846,7 +1857,7 @@ mrb_obj_class(mrb_state *mrb, mrb_value obj) MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) { - struct RProc *m = mrb_method_search(mrb, c, b); + mrb_method_t m = mrb_method_search(mrb, c, b); mrb_define_method_raw(mrb, c, a, m); } @@ -1940,7 +1951,10 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); } else { - mrb_define_method_raw(mrb, c, a, NULL); + mrb_method_t m; + + MRB_METHOD_FROM_PROC(m, NULL); + mrb_define_method_raw(mrb, c, a, m); } } @@ -1976,6 +1990,7 @@ mod_define_method(mrb_state *mrb, mrb_value self) { struct RClass *c = mrb_class_ptr(self); struct RProc *p; + mrb_method_t m; mrb_sym mid; mrb_value proc = mrb_undef_value(); mrb_value blk; @@ -1998,7 +2013,8 @@ mod_define_method(mrb_state *mrb, mrb_value self) p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); mrb_proc_copy(p, mrb_proc_ptr(blk)); p->flags |= MRB_PROC_STRICT; - mrb_define_method_raw(mrb, c, mid, p); + MRB_METHOD_FROM_PROC(m, p); + mrb_define_method_raw(mrb, c, mid, m); return mrb_symbol_value(mid); } @@ -2379,7 +2395,7 @@ mrb_mod_module_function(mrb_state *mrb, mrb_value mod) mrb_value *argv; mrb_int argc, i; mrb_sym mid; - struct RProc *method_rproc; + mrb_method_t m; struct RClass *rclass; int ai; @@ -2399,11 +2415,11 @@ mrb_mod_module_function(mrb_state *mrb, mrb_value mod) mid = mrb_symbol(argv[i]); rclass = mrb_class_ptr(mod); - method_rproc = mrb_method_search(mrb, rclass, mid); + m = mrb_method_search(mrb, rclass, mid); prepare_singleton_class(mrb, (struct RBasic*)rclass); ai = mrb_gc_arena_save(mrb); - mrb_define_method_raw(mrb, rclass->c, mid, method_rproc); + mrb_define_method_raw(mrb, rclass->c, mid, m); mrb_gc_arena_restore(mrb, ai); } diff --git a/src/kernel.c b/src/kernel.c index 4a20e18c1..1ac49ed04 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -31,8 +31,14 @@ typedef enum { MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) { - struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); - if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) + mrb_method_t m = mrb_method_search(mrb, mrb_class(mrb, obj), mid); + struct RProc *p; + + if (MRB_METHOD_UNDEF_P(m)) return FALSE; + if (MRB_METHOD_FUNC_P(m)) + return MRB_METHOD_FUNC(m) == func; + p = MRB_METHOD_PROC(m); + if (MRB_PROC_CFUNC_P(p) && (MRB_PROC_CFUNC(p) == func)) return TRUE; return FALSE; } @@ -677,7 +683,9 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) khash_t(mt) *h = klass->mt; if (!h || kh_size(h) == 0) return; for (i=0;i<kh_end(h);i++) { - if (kh_exist(h, i) && kh_value(h, i)) { + if (kh_exist(h, i)) { + mrb_method_t m = kh_value(h, i); + if (MRB_METHOD_UNDEF_P(m)) continue; kh_put(st, mrb, set, kh_key(h, i)); } } @@ -1134,6 +1142,7 @@ static mrb_value mod_define_singleton_method(mrb_state *mrb, mrb_value self) { struct RProc *p; + mrb_method_t m; mrb_sym mid; mrb_value blk = mrb_nil_value(); @@ -1144,7 +1153,8 @@ mod_define_singleton_method(mrb_state *mrb, mrb_value self) p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); mrb_proc_copy(p, mrb_proc_ptr(blk)); p->flags |= MRB_PROC_STRICT; - mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p); + MRB_METHOD_FROM_PROC(m, p); + mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, m); return mrb_symbol_value(mid); } diff --git a/src/proc.c b/src/proc.c index 69a9c0299..bd93de618 100644 --- a/src/proc.c +++ b/src/proc.c @@ -99,7 +99,7 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); p->body.func = func; - p->flags |= MRB_PROC_CFUNC; + p->flags |= MRB_PROC_CFUNC_FL; p->upper = 0; p->e.target_class = 0; @@ -141,11 +141,12 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) { struct RProc *p = mrb->c->ci->proc; - struct REnv *e = MRB_PROC_ENV(p); + struct REnv *e; - if (!MRB_PROC_CFUNC_P(p)) { + if (!p || !MRB_PROC_CFUNC_P(p)) { mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); } + e = MRB_PROC_ENV(p); if (!e) { mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); } @@ -216,12 +217,6 @@ mrb_proc_cfunc_p(struct RProc *p) return MRB_PROC_CFUNC_P(p); } -mrb_value -mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) -{ - return (p->body.func)(mrb, self); -} - /* 15.2.17.4.2 */ static mrb_value mrb_proc_arity(mrb_state *mrb, mrb_value self) @@ -293,7 +288,8 @@ proc_lambda(mrb_state *mrb, mrb_value self) void mrb_init_proc(mrb_state *mrb) { - struct RProc *m; + struct RProc *p; + mrb_method_t m; mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); static const mrb_irep mrb_irep_zero = { 0 }; @@ -307,7 +303,8 @@ mrb_init_proc(mrb_state *mrb) mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE()); - m = mrb_proc_new(mrb, call_irep); + p = mrb_proc_new(mrb, call_irep); + MRB_METHOD_FROM_PROC(m, p); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m); @@ -400,7 +400,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb->jmp = 0; } else { - struct RProc *p; + mrb_method_t m; struct RClass *c; mrb_callinfo *ci; int n; @@ -414,12 +414,12 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); } c = mrb_class(mrb, self); - p = mrb_method_search_vm(mrb, &c, mid); - if (!p) { + m = mrb_method_search_vm(mrb, &c, mid); + if (MRB_METHOD_UNDEF_P(m)) { mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - p = mrb_method_search_vm(mrb, &c, missing); - if (!p) { + m = mrb_method_search_vm(mrb, &c, missing); + if (MRB_METHOD_UNDEF_P(m)) { mrb_method_missing(mrb, mid, self, args); } mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); @@ -432,7 +432,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc } ci = cipush(mrb); ci->mid = mid; - ci->proc = p; ci->stackent = mrb->c->stack; ci->argc = (int)argc; ci->target_class = c; @@ -440,7 +439,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; } - if (MRB_PROC_CFUNC_P(p)) { + if (MRB_METHOD_CFUNC_P(m)) { ci->nregs = (int)(argc + 2); stack_extend(mrb, ci->nregs); } @@ -452,6 +451,8 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc argc = 1; } else { + struct RProc *p = MRB_METHOD_PROC(m); + ci->proc = p; if (argc < 0) argc = 1; ci->nregs = (int)(p->body.irep->nregs + argc); stack_extend(mrb, ci->nregs); @@ -465,18 +466,18 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc } mrb->c->stack[argc+1] = blk; - if (MRB_PROC_CFUNC_P(p)) { + if (MRB_METHOD_CFUNC_P(m)) { int ai = mrb_gc_arena_save(mrb); ci->acc = CI_ACC_DIRECT; - val = p->body.func(mrb, self); + val = MRB_METHOD_CFUNC(m)(mrb, self); mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); mrb_gc_arena_restore(mrb, ai); } else { ci->acc = CI_ACC_SKIP; - val = mrb_run(mrb, p, self); + val = mrb_run(mrb, MRB_METHOD_PROC(m), self); } } mrb_gc_protect(mrb, val); @@ -499,7 +500,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) ci->proc = p; ci->target_class = MRB_PROC_TARGET_CLASS(p); if (MRB_PROC_CFUNC_P(p)) { - return p->body.func(mrb, self); + return MRB_PROC_CFUNC(p)(mrb, self); } ci->nregs = p->body.irep->nregs; if (ci->argc < 0) keep = 3; @@ -547,7 +548,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) mrb_sym name; mrb_value block, *argv, *regs; mrb_int argc, i, len; - struct RProc *p; + mrb_method_t m; struct RClass *c; mrb_callinfo *ci; @@ -559,9 +560,8 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } c = mrb_class(mrb, self); - p = mrb_method_search_vm(mrb, &c, name); - - if (!p) { /* call method_mising */ + m = mrb_method_search_vm(mrb, &c, name); + if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */ goto funcall; } @@ -579,7 +579,10 @@ mrb_f_send(mrb_state *mrb, mrb_value self) mrb_ary_shift(mrb, regs[0]); } - return mrb_exec_irep(mrb, self, p); + if (MRB_METHOD_CFUNC_P(m)) { + return MRB_METHOD_CFUNC(m)(mrb, self); + } + return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m)); } static mrb_value @@ -606,7 +609,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb->c->stack[0] = self; mrb->c->stack[1] = self; mrb->c->stack[2] = mrb_nil_value(); - return p->body.func(mrb, self); + return MRB_PROC_CFUNC(p)(mrb, self); } ci->nregs = p->body.irep->nregs; stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); @@ -725,7 +728,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb->c->stack[argc+1] = mrb_nil_value(); if (MRB_PROC_CFUNC_P(p)) { - val = p->body.func(mrb, self); + val = MRB_PROC_CFUNC(p)(mrb, self); mrb->c->stack = mrb->c->ci->stackent; } else { @@ -1376,7 +1379,7 @@ RETRY_TRY_BLOCK: int n = GETARG_C(i); int argc = (n == CALL_MAXARGS) ? -1 : n; int bidx = (argc < 0) ? a+2 : a+n+1; - struct RProc *m; + mrb_method_t m; struct RClass *c; mrb_callinfo *ci = mrb->c->ci; mrb_value recv, blk; @@ -1400,10 +1403,10 @@ RETRY_TRY_BLOCK: } c = mrb_class(mrb, recv); m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); ERR_PC_SET(mrb, pc); mrb_method_missing(mrb, mid, recv, args); @@ -1423,7 +1426,6 @@ RETRY_TRY_BLOCK: /* push callinfo */ ci = cipush(mrb); ci->mid = mid; - ci->proc = m; ci->stackent = mrb->c->stack; ci->target_class = c; ci->argc = argc; @@ -1434,9 +1436,17 @@ RETRY_TRY_BLOCK: /* prepare stack */ mrb->c->stack += a; - if (MRB_PROC_CFUNC_P(m)) { + if (MRB_METHOD_CFUNC_P(m)) { ci->nregs = (argc < 0) ? 3 : n+2; - recv = m->body.func(mrb, recv); + if (MRB_METHOD_PROC_P(m)) { + struct RProc *p = MRB_METHOD_PROC(m); + + ci->proc = p; + recv = p->body.func(mrb, recv); + } + else { + recv = MRB_METHOD_FUNC(m)(mrb, recv); + } mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; @@ -1471,8 +1481,8 @@ RETRY_TRY_BLOCK: } else { /* setup environment for calling method */ - proc = mrb->c->ci->proc = m; - irep = m->body.irep; + proc = ci->proc = MRB_METHOD_PROC(m); + irep = proc->body.irep; pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; @@ -1511,7 +1521,7 @@ RETRY_TRY_BLOCK: /* prepare stack */ if (MRB_PROC_CFUNC_P(m)) { - recv = m->body.func(mrb, recv); + recv = MRB_PROC_CFUNC(m)(mrb, recv); mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; @@ -1560,7 +1570,7 @@ RETRY_TRY_BLOCK: int n = GETARG_C(i); int argc = (n == CALL_MAXARGS) ? -1 : n; int bidx = (argc < 0) ? a+2 : a+n+1; - struct RProc *m; + mrb_method_t m; struct RClass *c; mrb_callinfo *ci = mrb->c->ci; mrb_value recv, blk; @@ -1584,10 +1594,10 @@ RETRY_TRY_BLOCK: } c = ci->target_class->super; m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); ERR_PC_SET(mrb, pc); mrb_method_missing(mrb, mid, recv, args); @@ -1607,7 +1617,6 @@ RETRY_TRY_BLOCK: /* push callinfo */ ci = cipush(mrb); ci->mid = mid; - ci->proc = m; ci->stackent = mrb->c->stack; ci->target_class = c; ci->pc = pc + 1; @@ -1617,10 +1626,10 @@ RETRY_TRY_BLOCK: mrb->c->stack += a; mrb->c->stack[0] = recv; - if (MRB_PROC_CFUNC_P(m)) { + if (MRB_METHOD_CFUNC_P(m)) { mrb_value v; ci->nregs = (argc < 0) ? 3 : n+2; - v = m->body.func(mrb, recv); + v = MRB_METHOD_CFUNC(m)(mrb, recv); mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; @@ -1649,8 +1658,8 @@ RETRY_TRY_BLOCK: ci->acc = a; /* setup environment for calling method */ - ci->proc = m; - irep = m->body.irep; + proc = ci->proc = MRB_METHOD_PROC(m); + irep = proc->body.irep; pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; @@ -1934,7 +1943,7 @@ RETRY_TRY_BLOCK: /* Fall through to OP_R_NORMAL otherwise */ if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) { mrb_callinfo *cibase = mrb->c->cibase; - dst = top_proc(mrb, proc); + dst = top_proc(mrb, proc); if (MRB_PROC_ENV_P(dst)) { struct REnv *e = MRB_PROC_ENV(dst); @@ -2075,7 +2084,7 @@ RETRY_TRY_BLOCK: int a = GETARG_A(i); int b = GETARG_B(i); int n = GETARG_C(i); - struct RProc *m; + mrb_method_t m; struct RClass *c; mrb_callinfo *ci; mrb_value recv; @@ -2084,11 +2093,11 @@ RETRY_TRY_BLOCK: recv = regs[a]; c = mrb_class(mrb, recv); m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_value sym = mrb_symbol_value(mid); mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, missing); - if (!m) { + if (MRB_METHOD_UNDEF_P(m)) { mrb_value args; if (n == CALL_MAXARGS) { @@ -2124,15 +2133,16 @@ RETRY_TRY_BLOCK: /* move stack */ value_move(mrb->c->stack, ®s[a], ci->argc+1); - if (MRB_PROC_CFUNC_P(m)) { - mrb_value v = m->body.func(mrb, recv); + if (MRB_METHOD_CFUNC_P(m)) { + mrb_value v = MRB_METHOD_CFUNC(m)(mrb, recv); mrb->c->stack[0] = v; mrb_gc_arena_restore(mrb, ai); goto L_RETURN; } else { /* setup environment for calling method */ - irep = m->body.irep; + struct RProc *p = MRB_METHOD_PROC(m); + irep = p->body.irep; pool = irep->pool; syms = irep->syms; if (ci->argc < 0) { @@ -2824,8 +2834,10 @@ RETRY_TRY_BLOCK: int a = GETARG_A(i); struct RClass *c = mrb_class_ptr(regs[a]); struct RProc *p = mrb_proc_ptr(regs[a+1]); + mrb_method_t m; - mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p); + MRB_METHOD_FROM_PROC(m, p); + mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], m); mrb_gc_arena_restore(mrb, ai); NEXT; } |
