diff options
| -rw-r--r-- | include/mruby/class.h | 3 | ||||
| -rw-r--r-- | include/mruby/variable.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c | 17 | ||||
| -rw-r--r-- | src/class.c | 101 | ||||
| -rw-r--r-- | src/variable.c | 70 |
5 files changed, 81 insertions, 111 deletions
diff --git a/include/mruby/class.h b/include/mruby/class.h index 0526386d6..0853bd7f4 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -75,12 +75,13 @@ MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct R MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec); MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); -MRB_API struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *); MRB_API struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); MRB_API struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym); MRB_API struct RClass* mrb_class_real(struct RClass* cl); +void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); +mrb_value mrb_class_find_path(mrb_state*, struct RClass*); void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); void mrb_gc_free_mt(mrb_state*, struct RClass*); diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 2f2bbbf98..addd5f703 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -126,7 +126,6 @@ mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); -mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer); /* GC functions */ void mrb_gc_mark_gv(mrb_state*); diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 4553a965a..a948216e9 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -112,17 +112,6 @@ check_file_lineno(struct mrb_irep *irep, const char *file, uint16_t lineno) return result; } -static const char* -get_class_name(mrb_state *mrb, struct RClass *class_obj) -{ - struct RClass *outer; - mrb_sym class_sym; - - outer = mrb_class_outer_module(mrb, class_obj); - class_sym = mrb_class_sym(mrb, class_obj, outer); - return mrb_sym2name(mrb, class_sym); -} - static int32_t compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) { @@ -139,7 +128,7 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl method_p = &bp->point.methodpoint; if (strcmp(method_p->method_name, method_name) == 0) { - class_name = get_class_name(mrb, class_obj); + class_name = mrb_class_name(mrb, class_obj); if (class_name == NULL) { if (method_p->class_name == NULL) { return bp->bpno; @@ -166,8 +155,8 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl return MRB_DEBUG_OK; } - class_name = get_class_name(mrb, class_obj); - sn = get_class_name(mrb, sc); + class_name = mrb_class_name(mrb, class_obj); + sn = mrb_class_name(mrb, sc); if (strcmp(sn, class_name) == 0) { return bp->bpno; } 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; } |
