From fdf71d8f2dec7a2ca8777adae3d55f42d1cf9b17 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 29 Jan 2025 17:24:36 +0900 Subject: [PATCH] class.c: first step to private methods; #1835 Now each method entry holds visibility information in flag bits. --- include/mruby/class.h | 2 ++ include/mruby/proc.h | 9 ++++--- src/class.c | 63 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/include/mruby/class.h b/include/mruby/class.h index 5be1b8e91..de0846897 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -79,6 +79,8 @@ mrb_class(mrb_state *mrb, mrb_value v) #define MRB_UNDEF_ALLOCATOR(c) (mrb_assert((c)->tt == MRB_TT_CLASS), (c)->flags |= MRB_FL_UNDEF_ALLOCATE) #define MRB_UNDEF_ALLOCATOR_P(c) ((c)->flags & MRB_FL_UNDEF_ALLOCATE) #define MRB_DEFINE_ALLOCATOR(c) ((c)->flags &= ~MRB_FL_UNDEF_ALLOCATE) +#define MRB_SET_VISIBILITY(c,v) ((c)->flags = (((c)->flags & ~(0x3<<7)) | (((v)&0x3)<<7))) +#define MRB_VISIBILITY(c) (((c)->flags>>7) & 0x3) MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t); MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 76203d778..489b4c95e 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -109,10 +109,11 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); /* old name */ #define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx) -#define MRB_METHOD_FUNC_FL 1 -#define MRB_METHOD_NOARG_FL 2 -#define MRB_METHOD_PRIVATE_FL 4 -#define MRB_METHOD_PROTECTED_FL 8 +#define MRB_METHOD_FUNC_FL 8 +#define MRB_METHOD_NOARG_FL 4 +#define MRB_METHOD_PUBLIC_FL 0 +#define MRB_METHOD_PRIVATE_FL 1 +#define MRB_METHOD_PROTECTED_FL 2 #define MRB_METHOD_FUNC_P(m) ((m).flags&MRB_METHOD_FUNC_FL) #define MRB_METHOD_NOARG_P(m) (((m).flags&MRB_METHOD_NOARG_FL)?1:0) diff --git a/src/class.c b/src/class.c index 404bb99dc..e57af106e 100644 --- a/src/class.c +++ b/src/class.c @@ -26,16 +26,18 @@ union mt_ptr { mrb_func_t func; }; -#define MT_KEY_SHIFT 2 -#define MT_KEY_MASK ((1<<2)-1) +#define MT_KEY_SHIFT 4 +#define MT_KEY_MASK ((1<>MT_KEY_SHIFT) != 0) #define MT_FUNC MRB_METHOD_FUNC_FL #define MT_NOARG MRB_METHOD_NOARG_FL +#define MT_PUBLIC MRB_METHOD_PUBLIC_FL +#define MT_PRIVATE MRB_METHOD_PRIVATE_FL +#define MT_PROTECTED MRB_METHOD_PROTECTED_FL #define MT_EMPTY 0 #define MT_DELETED 1 #define MT_KEY(sym, flags) ((sym)<>MT_KEY_SHIFT) #define MT_KEY_FLG(k) ((k)&MT_KEY_MASK) @@ -349,6 +351,7 @@ setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) { mrb_class_name_class(mrb, outer, c, id); mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); + MRB_SET_VISIBILITY(c, MT_PUBLIC); } #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) @@ -776,7 +779,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ else { ptr.func = MRB_METHOD_FUNC(m); } - mt_put(mrb, h, mid, MT_FLAGS(MRB_METHOD_FUNC_P(m), MRB_METHOD_NOARG_P(m)), ptr); + mt_put(mrb, h, mid, (MT_KEY_FLG(m.flags)&0xC)|MRB_VISIBILITY(c), ptr); mc_clear_by_id(mrb, mid); } @@ -1629,9 +1632,51 @@ mrb_mod_initialize(mrb_state *mrb, mrb_value mod) return mod; } -static mrb_value -mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) +static void +mrb_mod_visibility(mrb_state *mrb, mrb_value mod, int visibility) { + mrb_assert((visibility&0x3)==visibility); + mrb_int argc; + mrb_value *argv; + struct RClass *c = mrb_class_ptr(mod); + + mrb_get_args(mrb, "*!", &argv, &argc); + if (argc == 0) { + MRB_SET_VISIBILITY(c, visibility); + } + else { + mt_tbl *h = c->mt; + for (int i=0; i