diff --git a/include/mruby/value.h b/include/mruby/value.h index 60c018ab4..c9a735611 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -164,7 +164,7 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; f(MRB_TT_RATIONAL, struct RRational, "Rational") \ f(MRB_TT_BIGINT, struct RBigint, "Integer") \ f(MRB_TT_BACKTRACE, struct RBacktrace, "backtrace") \ - f(MRB_TT_SET, struct RData, "Set") + f(MRB_TT_SET, struct RSet, "Set") enum mrb_vtype { #define MRB_VTYPE_DEFINE(tt, type, name) tt, diff --git a/mrbgems/mruby-set/src/set.c b/mrbgems/mruby-set/src/set.c index f64df6fc6..5e08eacc3 100644 --- a/mrbgems/mruby-set/src/set.c +++ b/mrbgems/mruby-set/src/set.c @@ -19,6 +19,11 @@ KHASH_DECLARE(set, mrb_value, char, FALSE) KHASH_DEFINE(set, mrb_value, char, FALSE, mrb_obj_hash_code, mrb_eql) +struct RSet { + MRB_OBJECT_HEADER; + khash_t(set) *kh; +}; + static void set_copy_elements(mrb_state *mrb, khash_t(set) *target_kh, khash_t(set) *source_kh) { @@ -31,48 +36,28 @@ set_copy_elements(mrb_state *mrb, khash_t(set) *target_kh, khash_t(set) *source_ } } -#define SET_KHASH_IV MRB_SYM(khash) - -static void -set_free(mrb_state *mrb, void *ptr) -{ - khash_t(set) *kh = (khash_t(set)*)ptr; - if (kh) { - kh_destroy(set, mrb, kh); - } -} - -static const struct mrb_data_type set_data_type = { - "Set", set_free -}; - +#define mrb_set_ptr(o) ((struct RSet*)mrb_obj_ptr(o)) static void set_set_khash(mrb_state *mrb, mrb_value self, khash_t(set) *kh) { - /* When MRB_TT_SET is used, RData's type field is not strictly necessary */ - /* for type checking if mrb_type() is MRB_TT_SET. However, it can still hold */ - /* the dfree function if we choose to use it via a generic RData path. */ - /* For now, keeping it for set_free via set_data_type if needed. */ - ((struct RData*)mrb_obj_ptr(self))->type = &set_data_type; - ((struct RData*)mrb_obj_ptr(self))->data = kh; + mrb_check_type(mrb, self, MRB_TT_SET); + struct RSet *set = mrb_set_ptr(self); + set->kh = kh; } static khash_t(set) * set_get_khash(mrb_state *mrb, mrb_value self) { - mrb_assert(mrb_type(self) == MRB_TT_SET); - return (khash_t(set)*)((struct RData*)mrb_obj_ptr(self))->data; + mrb_check_type(mrb, self, MRB_TT_SET); + return mrb_set_ptr(self)->kh; } -#ifdef MRB_USE_SET /* Mark function for Set instances */ size_t mrb_gc_mark_set(mrb_state *mrb, struct RBasic *obj) { - struct RData *d = (struct RData*)obj; - if (!d->data) return 0; - - khash_t(set) *kh = (khash_t(set)*)d->data; + struct RSet *s = (struct RSet*)obj; + khash_t(set) *kh = s->kh; if (!kh) return 0; KHASH_FOREACH(mrb, kh, k) { @@ -86,16 +71,14 @@ mrb_gc_mark_set(mrb_state *mrb, struct RBasic *obj) void mrb_gc_free_set(mrb_state *mrb, struct RBasic *obj) { - struct RData *d = (struct RData*)obj; - if (d->data) { - khash_t(set) *kh = (khash_t(set)*)d->data; + struct RSet *s = (struct RSet*)obj; + if (s->kh) { + khash_t(set) *kh = s->kh; if (kh) { kh_destroy(set, mrb, kh); } } - mrb_gc_free_iv(mrb, (struct RObject*)obj); } -#endif /* Helper function to check if a value is a Set and return a boolean result */ static mrb_bool