summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-11-20 06:21:22 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-11-20 18:33:41 +0900
commit8f2c62407c0659d84126545e19505a851059e750 (patch)
tree7a073d389fc2f5fc7c14f86ffa96d0145bff9f82 /src
parent6c06e77446f3cca4a92b3df8d0a5fe568c5fdc65 (diff)
downloadmruby-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.c88
-rw-r--r--src/kernel.c18
-rw-r--r--src/proc.c19
-rw-r--r--src/vm.c98
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);
diff --git a/src/vm.c b/src/vm.c
index 8dfabdafe..170cb832d 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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, &regs[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;
}