From f962890a928b566c0f5ca7fdff5ef4ce19207e65 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 9 Jul 2015 23:46:54 +0200 Subject: Implement Module#prepend. --- include/mruby/class.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/mruby/class.h b/include/mruby/class.h index 9d5260a24..60310ae9d 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -16,6 +16,7 @@ struct RClass { struct iv_tbl *iv; struct kh_mt *mt; struct RClass *super; + struct RClass *origin; }; #define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v))) -- cgit v1.2.3 From eb172c28d79b4fdf978e78fc7e929caa855dd29b Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Tue, 14 Jul 2015 09:44:04 -0500 Subject: Applied gc patch to fix ORIGIN ICLASS method table leak Based on the gc patch by ko1 https://github.com/ruby/ruby/commit/5922c954614e5947a548780bb3b894626affe6dd --- include/mruby/class.h | 7 +++++-- include/mruby/object.h | 2 ++ src/class.c | 1 + src/gc.c | 12 ++++++++++-- 4 files changed, 18 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/mruby/class.h b/include/mruby/class.h index 60310ae9d..9f2c32bb0 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -49,8 +49,11 @@ mrb_class(mrb_state *mrb, mrb_value v) } } -#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt) -#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff) +// TODO: figure out where to put user flags +#define MRB_FLAG_IS_ORIGIN (1 << 20) +#define MRB_FLAG_IS_INSTANCE (0xFF) +#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_FLAG_IS_INSTANCE) | (char)tt) +#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_FLAG_IS_INSTANCE) MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); diff --git a/include/mruby/object.h b/include/mruby/object.h index fe55620fe..6633a23e8 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -14,6 +14,8 @@ struct RClass *c;\ struct RBasic *gcnext +#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag) + /* white: 011, black: 100, gray: 000 */ #define MRB_GC_GRAY 0 #define MRB_GC_WHITE_A 1 diff --git a/src/class.c b/src/class.c index 14d81495e..58742299b 100644 --- a/src/class.c +++ b/src/class.c @@ -856,6 +856,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) origin = c->origin; if (origin == c) { origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); + origin->flags |= MRB_FLAG_IS_ORIGIN; origin->origin = origin; origin->super = c->super; c->super = origin; diff --git a/src/gc.c b/src/gc.c index 8bd8243f1..15e1bd423 100644 --- a/src/gc.c +++ b/src/gc.c @@ -498,7 +498,12 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: - mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); + { + struct RClass *c = (struct RClass*)obj; + if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) + mrb_gc_mark_mt(mrb, c); + mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); + } break; case MRB_TT_CLASS: @@ -624,7 +629,10 @@ obj_free(mrb_state *mrb, struct RBasic *obj) mrb_gc_free_mt(mrb, (struct RClass*)obj); mrb_gc_free_iv(mrb, (struct RObject*)obj); break; - + case MRB_TT_ICLASS: + if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN)) + mrb_gc_free_mt(mrb, (struct RClass*)obj); + break; case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; -- cgit v1.2.3 From 667f7788db2b3b78cc4cc65c0f37ab38347116c5 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Wed, 15 Jul 2015 07:27:31 -0500 Subject: Renamed MRB_FLAG_IS_INSTANCE to MRB_INSTANCE_TT_MASK --- include/mruby/class.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/mruby/class.h b/include/mruby/class.h index 9f2c32bb0..80a0cbe35 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -51,9 +51,9 @@ mrb_class(mrb_state *mrb, mrb_value v) // TODO: figure out where to put user flags #define MRB_FLAG_IS_ORIGIN (1 << 20) -#define MRB_FLAG_IS_INSTANCE (0xFF) -#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_FLAG_IS_INSTANCE) | (char)tt) -#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_FLAG_IS_INSTANCE) +#define MRB_INSTANCE_TT_MASK (0xFF) +#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt) +#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK) MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); -- cgit v1.2.3 From 26bee4a16b5763b407a842bd1697389961600d68 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Thu, 16 Jul 2015 15:25:27 -0500 Subject: Added mrb_prepend_module to mruby header --- include/mruby.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/mruby.h b/include/mruby.h index 1b792ce90..b4ec13fdc 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -206,6 +206,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass* MRB_API struct RClass *mrb_define_module(mrb_state *, const char*); MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value); MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*); +MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*); MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec); -- cgit v1.2.3