summaryrefslogtreecommitdiffhomepage
path: root/src/kernel.c
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/kernel.c
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/kernel.c')
-rw-r--r--src/kernel.c18
1 files changed, 14 insertions, 4 deletions
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);
}