class.c: first step to private methods; #1835

Now each method entry holds visibility information in flag bits.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-01-29 17:24:36 +09:00
parent 3a3e877ae5
commit fdf71d8f2d
3 changed files with 61 additions and 13 deletions
+2
View File
@@ -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);
+5 -4
View File
@@ -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)
+54 -9
View File
@@ -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)-1)
#define MT_KEY_P(k) (((k)>>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|(flags))
#define MT_FLAGS(isfunc, isnoarg) ((isfunc)?MT_FUNC:0)|((isnoarg)?MT_NOARG:0)
#define MT_KEY_SYM(k) ((k)>>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<argc; i++) {
mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
mrb_sym mid = mrb_symbol(argv[i]);
union mt_ptr ptr;
mrb_sym ret = mt_get(mrb, h, mid, &ptr);
if (ret == 0) {
mrb_raisef(mrb, E_NAME_ERROR, "undefined method %n for %C", mid, c);
}
mt_put(mrb, h, mid, (ret&0xC)|visibility, ptr);
}
}
}
static mrb_value
mrb_mod_public(mrb_state *mrb, mrb_value mod)
{
mrb_mod_visibility(mrb, mod, MT_PUBLIC);
return mod;
}
static mrb_value
mrb_mod_private(mrb_state *mrb, mrb_value mod)
{
mrb_mod_visibility(mrb, mod, MT_PRIVATE);
return mod;
}
static mrb_value
mrb_mod_protected(mrb_state *mrb, mrb_value mod)
{
mrb_mod_visibility(mrb, mod, MT_PROTECTED);
return mod;
}
@@ -2989,9 +3034,9 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method_id(mrb, mod, MRB_SYM(initialize), mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
mrb_define_method_id(mrb, mod, MRB_SYM(module_eval), mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
mrb_define_method_id(mrb, mod, MRB_SYM(module_function), mrb_mod_module_function, MRB_ARGS_ANY());
mrb_define_method_id(mrb, mod, MRB_SYM(private), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
mrb_define_method_id(mrb, mod, MRB_SYM(protected), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
mrb_define_method_id(mrb, mod, MRB_SYM(public), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
mrb_define_method_id(mrb, mod, MRB_SYM(private), mrb_mod_private, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
mrb_define_method_id(mrb, mod, MRB_SYM(protected), mrb_mod_protected, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
mrb_define_method_id(mrb, mod, MRB_SYM(public), mrb_mod_public, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
mrb_define_method_id(mrb, mod, MRB_SYM(attr_reader), mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
mrb_define_method_id(mrb, mod, MRB_SYM(attr_writer), mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
mrb_define_method_id(mrb, mod, MRB_SYM(to_s), mrb_mod_to_s, MRB_ARGS_NONE());