diff options
Diffstat (limited to 'mrbgems/mruby-objectspace/src/mruby_objectspace.c')
| -rw-r--r-- | mrbgems/mruby-objectspace/src/mruby_objectspace.c | 139 |
1 files changed, 90 insertions, 49 deletions
diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index ac6189ded..9871663fb 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -1,23 +1,24 @@ #include <mruby.h> #include <mruby/gc.h> #include <mruby/hash.h> -#include <mruby/value.h> +#include <mruby/class.h> struct os_count_struct { - size_t total; - size_t freed; - size_t counts[MRB_TT_MAXDEFINE+1]; + mrb_int total; + mrb_int freed; + mrb_int counts[MRB_TT_MAXDEFINE+1]; }; -void -os_count_object_type(mrb_state *mrb, struct RBasic* obj, void *data) +static void +os_count_object_type(mrb_state *mrb, struct RBasic *obj, void *data) { - struct os_count_struct* obj_count; - obj_count = (struct os_count_struct*)(data); + struct os_count_struct *obj_count; + obj_count = (struct os_count_struct*)data; if (is_dead(mrb, obj)) { obj_count->freed++; - } else { + } + else { obj_count->counts[obj->tt]++; obj_count->total++; } @@ -33,8 +34,8 @@ os_count_object_type(mrb_state *mrb, struct RBasic* obj, void *data) * { * :TOTAL=>10000, * :FREE=>3011, - * :MRB_TT_OBJECT=>6, - * :MRB_TT_CLASS=>404, + * :T_OBJECT=>6, + * :T_CLASS=>404, * # ... * } * @@ -43,11 +44,11 @@ os_count_object_type(mrb_state *mrb, struct RBasic* obj, void *data) * */ -mrb_value +static mrb_value os_count_objects(mrb_state *mrb, mrb_value self) { - struct os_count_struct obj_count; - size_t i; + struct os_count_struct obj_count = { 0 }; + enum mrb_vtype i; mrb_value hash; if (mrb_get_args(mrb, "|H", &hash) == 0) { @@ -58,43 +59,38 @@ os_count_objects(mrb_state *mrb, mrb_value self) mrb_hash_clear(mrb, hash); } - for (i = 0; i <= MRB_TT_MAXDEFINE; i++) { - obj_count.counts[i] = 0; - } - obj_count.total = 0; - obj_count.freed = 0; - mrb_objspace_each_objects(mrb, os_count_object_type, &obj_count); - mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_cstr(mrb, "TOTAL")), mrb_fixnum_value(obj_count.total)); - mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_cstr(mrb, "FREE")), mrb_fixnum_value(obj_count.freed)); + mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "TOTAL")), mrb_fixnum_value(obj_count.total)); + mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "FREE")), mrb_fixnum_value(obj_count.freed)); - for (i = 0; i < MRB_TT_MAXDEFINE; i++) { + for (i = MRB_TT_FALSE; i < MRB_TT_MAXDEFINE; i++) { mrb_value type; switch (i) { -#define COUNT_TYPE(t) case (t): type = mrb_symbol_value(mrb_intern_cstr(mrb, #t)); break; - COUNT_TYPE(MRB_TT_FALSE); - COUNT_TYPE(MRB_TT_FREE); - COUNT_TYPE(MRB_TT_TRUE); - COUNT_TYPE(MRB_TT_FIXNUM); - COUNT_TYPE(MRB_TT_SYMBOL); - COUNT_TYPE(MRB_TT_UNDEF); - COUNT_TYPE(MRB_TT_FLOAT); - COUNT_TYPE(MRB_TT_CPTR); - COUNT_TYPE(MRB_TT_OBJECT); - COUNT_TYPE(MRB_TT_CLASS); - COUNT_TYPE(MRB_TT_MODULE); - COUNT_TYPE(MRB_TT_ICLASS); - COUNT_TYPE(MRB_TT_SCLASS); - COUNT_TYPE(MRB_TT_PROC); - COUNT_TYPE(MRB_TT_ARRAY); - COUNT_TYPE(MRB_TT_HASH); - COUNT_TYPE(MRB_TT_STRING); - COUNT_TYPE(MRB_TT_RANGE); - COUNT_TYPE(MRB_TT_EXCEPTION); - COUNT_TYPE(MRB_TT_FILE); - COUNT_TYPE(MRB_TT_ENV); - COUNT_TYPE(MRB_TT_DATA); +#define COUNT_TYPE(t) case (MRB_T ## t): type = mrb_symbol_value(mrb_intern_lit(mrb, #t)); break; + COUNT_TYPE(T_FALSE); + COUNT_TYPE(T_FREE); + COUNT_TYPE(T_TRUE); + COUNT_TYPE(T_FIXNUM); + COUNT_TYPE(T_SYMBOL); + COUNT_TYPE(T_UNDEF); + COUNT_TYPE(T_FLOAT); + COUNT_TYPE(T_CPTR); + COUNT_TYPE(T_OBJECT); + COUNT_TYPE(T_CLASS); + COUNT_TYPE(T_MODULE); + COUNT_TYPE(T_ICLASS); + COUNT_TYPE(T_SCLASS); + COUNT_TYPE(T_PROC); + COUNT_TYPE(T_ARRAY); + COUNT_TYPE(T_HASH); + COUNT_TYPE(T_STRING); + COUNT_TYPE(T_RANGE); + COUNT_TYPE(T_EXCEPTION); + COUNT_TYPE(T_FILE); + COUNT_TYPE(T_ENV); + COUNT_TYPE(T_DATA); + COUNT_TYPE(T_FIBER); #undef COUNT_TYPE default: type = mrb_fixnum_value(i); break; @@ -106,12 +102,57 @@ os_count_objects(mrb_state *mrb, mrb_value self) return hash; } +struct os_each_object_data { + mrb_value block; + struct RClass *target_module; + mrb_int count; +}; + +static void +os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud) +{ + struct os_each_object_data *d = (struct os_each_object_data*)ud; + + /* filter dead objects */ + if (is_dead(mrb, obj)) { + return; + } + + /* filter class kind if target module defined */ + if (d->target_module && !mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), d->target_module)) { + return; + } + + mrb_yield(mrb, d->block, mrb_obj_value(obj)); + ++d->count; +} + +static mrb_value +os_each_object(mrb_state *mrb, mrb_value self) +{ + mrb_value cls = mrb_nil_value(); + struct os_each_object_data d; + mrb_get_args(mrb, "&|C", &d.block, &cls); + + if (mrb_nil_p(d.block)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object."); + } + + d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls); + d.count = 0; + mrb_objspace_each_objects(mrb, os_each_object_cb, &d); + return mrb_fixnum_value(d.count); +} + void -mrb_mruby_objectspace_gem_init(mrb_state* mrb) { +mrb_mruby_objectspace_gem_init(mrb_state *mrb) +{ struct RClass *os = mrb_define_module(mrb, "ObjectSpace"); - mrb_define_class_method(mrb, os, "count_objects", os_count_objects, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, os, "count_objects", os_count_objects, MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, os, "each_object", os_each_object, MRB_ARGS_OPT(1)); } void -mrb_mruby_objectspace_gem_final(mrb_state* mrb) { +mrb_mruby_objectspace_gem_final(mrb_state *mrb) +{ } |
