diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class.c | 101 | ||||
| -rw-r--r-- | src/variable.c | 70 |
2 files changed, 76 insertions, 95 deletions
diff --git a/src/class.c b/src/class.c index f2fc126ef..97a4c9c57 100644 --- a/src/class.c +++ b/src/class.c @@ -50,22 +50,36 @@ mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) kh_destroy(mt, mrb, c->mt); } -static void -name_class(mrb_state *mrb, struct RClass *c, mrb_sym name) +void +mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) { - mrb_obj_iv_set(mrb, (struct RObject*)c, - mrb_intern_lit(mrb, "__classid__"), mrb_symbol_value(name)); + mrb_value name; + mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); + + if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return; + if (outer == NULL || outer == mrb->object_class) { + name = mrb_symbol_value(id); + } + else { + name = mrb_class_path(mrb, outer); + if (mrb_nil_p(name)) { /* unnamed outer class */ + if (outer != mrb->object_class) { + mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), + mrb_obj_value(outer)); + } + return; + } + mrb_str_cat_cstr(mrb, name, "::"); + mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id)); + } + mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name); } static void setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) { - name_class(mrb, c, id); + mrb_class_name_class(mrb, outer, c, id); mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); - if (outer != mrb->object_class) { - mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), - mrb_obj_value(outer)); - } } #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) @@ -136,27 +150,6 @@ class_ptr_p(mrb_value obj) } } -MRB_API struct RClass* -mrb_class_outer_module(mrb_state *mrb, struct RClass *c) -{ - mrb_value outer; - struct RClass *cls; - - outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__")); - if (mrb_nil_p(outer)) return NULL; - cls = mrb_class_ptr(outer); - if (cls->tt == MRB_TT_SCLASS) - { - mrb_value klass; - klass = mrb_obj_iv_get(mrb, (struct RObject *)cls, - mrb_intern_lit(mrb, "__attached__")); - if (class_ptr_p(klass)) { - cls = mrb_class_ptr(klass); - } - } - return cls; -} - static void check_if_class_or_module(mrb_state *mrb, mrb_value obj) { @@ -1601,40 +1594,20 @@ MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c) { mrb_value path; - const char *name; - mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__"); + mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); - path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath); + path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym); if (mrb_nil_p(path)) { - struct RClass *outer = mrb_class_outer_module(mrb, c); - mrb_sym sym = mrb_class_sym(mrb, c, outer); + /* no name (yet) */ + return mrb_class_find_path(mrb, c); + } + else if (mrb_symbol_p(path)) { + /* topleve class/module */ + const char *str; mrb_int len; - if (sym == 0) { - return mrb_nil_value(); - } - else if (outer && outer != c && outer != mrb->object_class) { - mrb_value base = mrb_class_path(mrb, outer); - path = mrb_str_buf_new(mrb, 0); - if (mrb_nil_p(base)) { - mrb_str_cat_lit(mrb, path, "#<Class:"); - mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer)); - mrb_str_cat_lit(mrb, path, ">"); - } - else { - mrb_str_concat(mrb, path, base); - } - mrb_str_cat_lit(mrb, path, "::"); - name = mrb_sym2name_len(mrb, sym, &len); - mrb_str_cat(mrb, path, name, len); - } - else { - name = mrb_sym2name_len(mrb, sym, &len); - path = mrb_str_new(mrb, name, len); - } - if (!MRB_FROZEN_P(c)) { - mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path); - } + str = mrb_sym2name_len(mrb, mrb_symbol(path), &len); + return mrb_str_new(mrb, str, len); } return mrb_str_dup(mrb, path); } @@ -2338,10 +2311,10 @@ mrb_init_class(mrb_state *mrb) mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls)); /* name each classes */ - name_class(mrb, bob, mrb_intern_lit(mrb, "BasicObject")); - name_class(mrb, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ - name_class(mrb, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ - name_class(mrb, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ + mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject")); + mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ + mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ + mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */ MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); diff --git a/src/variable.c b/src/variable.c index b700081a5..91081e867 100644 --- a/src/variable.c +++ b/src/variable.c @@ -869,18 +869,9 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) MRB_API void mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) { - mrb_sym id = mrb_intern_lit(mrb, "__classid__"); - mod_const_check(mrb, mod); - if ((mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) - && !mrb_obj_iv_defined(mrb, mrb_obj_ptr(v), id)) { - struct RObject *c = mrb_obj_ptr(v); - - /* name unnamed classes/modules */ - mrb_obj_iv_set(mrb, c, id, mrb_symbol_value(sym)); - if (mrb_class_ptr(mod) != mrb->object_class) { - mrb_obj_iv_set(mrb, c, mrb_intern_lit(mrb, "__outer__"), mod); - } + if (mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) { + mrb_class_name_class(mrb, mrb_class_ptr(mod), mrb_class_ptr(v), sym); } mrb_iv_set(mrb, mod, sym, v); } @@ -1077,37 +1068,54 @@ struct csym_arg { struct RClass *c; mrb_sym sym; }; - + static int csym_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) { struct csym_arg *a = (struct csym_arg*)p; struct RClass *c = a->c; - + if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) { a->sym = sym; return 1; /* stop iteration */ } return 0; } - -mrb_sym -mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer) + +static mrb_sym +find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c) { - mrb_value name; - - name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__classid__")); - if (mrb_nil_p(name)) { - - if (!outer) return 0; - else { - struct csym_arg arg; + struct csym_arg arg; + + if (!outer) return 0; + arg.c = c; + arg.sym = 0; + iv_foreach(mrb, outer->iv, csym_i, &arg); + return arg.sym; +} - arg.c = c; - arg.sym = 0; - iv_foreach(mrb, outer->iv, csym_i, &arg); - return arg.sym; - } - } - return mrb_symbol(name); +mrb_value +mrb_class_find_path(mrb_state *mrb, struct RClass *c) +{ + mrb_value outer, path; + mrb_sym name; + const char *str; + mrb_int len; + mrb_sym osym = mrb_intern_lit(mrb, "__outer__"); + + outer = mrb_obj_iv_get(mrb, (struct RObject*)c, osym); + if (mrb_nil_p(outer)) return outer; + name = find_class_sym(mrb, mrb_class_ptr(outer), c); + if (name == 0) return mrb_nil_value(); + str = mrb_class_name(mrb, mrb_class_ptr(outer)); + path = mrb_str_buf_new(mrb, 0); + mrb_str_cat_cstr(mrb, path, str); + mrb_str_cat_cstr(mrb, path, "::"); + + str = mrb_sym2name_len(mrb, name, &len); + mrb_str_cat(mrb, path, str, len); + iv_del(mrb, c->iv, osym, NULL); + iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path); + mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path); + return path; } |
