diff --git a/include/mruby/class.h b/include/mruby/class.h index a3e1c0d1e..1bf71aa6c 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -57,7 +57,8 @@ mrb_class(mrb_state *mrb, mrb_value v) 19: is_prepended 18: is_origin 17: is_inherited (used by method cache) - 6-16: unused + 7-16: unused + 6: prohibit Class#allocate 0-5: instance type */ #define MRB_FL_CLASS_IS_PREPENDED (1 << 19) @@ -74,6 +75,9 @@ mrb_class(mrb_state *mrb, mrb_value v) #define MRB_INSTANCE_TT_MASK (0x1F) #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) +#define MRB_FL_UNDEF_ALLOCATE (1 << 6) +#define MRB_UNDEF_ALLOCATOR(c) (mrb_assert((c)->tt == MRB_TT_CLASS), (c)->flags |= MRB_FL_UNDEF_ALLOCATE) +#define MRB_UNDEF_ALLOCATOR_P(c) ((c)->flags & MRB_FL_UNDEF_ALLOCATE) MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t); MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index 08e81fb72..c269facfc 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -397,7 +397,8 @@ void mrb_mruby_binding_gem_init(mrb_state *mrb) { struct RClass *binding = mrb_define_class(mrb, "Binding", mrb->object_class); - MRB_SET_INSTANCE_TT(binding, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(binding, MRB_TT_OBJECT); + MRB_UNDEF_ALLOCATOR(binding); mrb_undef_class_method(mrb, binding, "new"); mrb_undef_class_method(mrb, binding, "allocate"); diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index f0e5829d1..a2c579058 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -395,7 +395,8 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) struct RClass *comp; comp = mrb_define_class_id(mrb, MRB_SYM(Complex), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(comp, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(comp, MRB_TT_COMPLEX); + MRB_UNDEF_ALLOCATOR(comp); mrb_undef_class_method(mrb, comp, "new"); mrb_define_class_method(mrb, comp, "rectangular", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); diff --git a/mrbgems/mruby-data/src/data.c b/mrbgems/mruby-data/src/data.c index dd077619c..2fbc51242 100644 --- a/mrbgems/mruby-data/src/data.c +++ b/mrbgems/mruby-data/src/data.c @@ -492,7 +492,8 @@ mrb_mruby_data_gem_init(mrb_state* mrb) { struct RClass *d; d = mrb_define_class(mrb, "Data", mrb->object_class); - MRB_SET_INSTANCE_TT(d, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(d, MRB_TT_STRUCT); + MRB_UNDEF_ALLOCATOR(d); mrb_undef_class_method(mrb, d, "new"); mrb_define_class_method(mrb, d, "define", mrb_data_s_def, MRB_ARGS_ANY()); diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index deb37b4a5..f12cc44b6 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -546,7 +546,8 @@ mrb_mruby_method_gem_init(mrb_state* mrb) struct RClass *unbound_method = mrb_define_class_id(mrb, MRB_SYM(UnboundMethod), mrb->object_class); struct RClass *method = mrb_define_class_id(mrb, MRB_SYM(Method), mrb->object_class); - MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_OBJECT); + MRB_UNDEF_ALLOCATOR(unbound_method); mrb_undef_class_method(mrb, unbound_method, "new"); mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1)); mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE()); @@ -561,7 +562,8 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE()); - MRB_SET_INSTANCE_TT(method, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(method, MRB_TT_OBJECT); + MRB_UNDEF_ALLOCATOR(method); mrb_undef_class_method(mrb, method, "new"); mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1)); mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 2fadf5d60..b3a5f945c 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -767,7 +767,8 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) struct RClass *rat; rat = mrb_define_class_id(mrb, MRB_SYM(Rational), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(rat, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(rat, MRB_TT_RATIONAL); + MRB_UNDEF_ALLOCATOR(rat); mrb_undef_class_method(mrb, rat, "new"); mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2)); mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 4f6dadcfb..f4a5bab9a 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -697,7 +697,8 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) { struct RClass *st; st = mrb_define_class(mrb, "Struct", mrb->object_class); - MRB_SET_INSTANCE_TT(st, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(st, MRB_TT_STRUCT); + MRB_UNDEF_ALLOCATOR(st); mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ diff --git a/src/class.c b/src/class.c index 8f33cd736..4eac5f240 100644 --- a/src/class.c +++ b/src/class.c @@ -1949,10 +1949,10 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) else if (ttype == 0) { ttype = MRB_TT_OBJECT; } + if (MRB_UNDEF_ALLOCATOR_P(c)) { + mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv); + } if (ttype <= MRB_TT_CPTR) { - if (ttype == MRB_TT_UNDEF) { - mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv); - } mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv); } o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); diff --git a/src/gc.c b/src/gc.c index 9eb84311b..39f63c62b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -476,7 +476,6 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) } tt = MRB_INSTANCE_TT(cls); if (tt != MRB_TT_FALSE && - tt != MRB_TT_UNDEF && ttype != MRB_TT_SCLASS && ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && diff --git a/src/numeric.c b/src/numeric.c index 5b098c8b8..743cdb3ae 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -2227,7 +2227,8 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ mrb->integer_class = integer = mrb_define_class_id(mrb, MRB_SYM(Integer), numeric); /* 15.2.8 */ - MRB_SET_INSTANCE_TT(integer, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER); + MRB_UNDEF_ALLOCATOR(integer); mrb_undef_class_method_id(mrb, integer, MRB_SYM(new)); mrb_define_method_id(mrb, integer, MRB_OPSYM(pow), int_pow, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, integer, MRB_OPSYM(cmp), num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ @@ -2272,7 +2273,8 @@ mrb_init_numeric(mrb_state *mrb) #ifndef MRB_NO_FLOAT /* Float Class */ mrb->float_class = fl = mrb_define_class_id(mrb, MRB_SYM(Float), numeric); /* 15.2.9 */ - MRB_SET_INSTANCE_TT(fl, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); + MRB_UNDEF_ALLOCATOR(fl); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method_id(mrb, fl, MRB_OPSYM(pow), flo_pow, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, fl, MRB_OPSYM(div), flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ diff --git a/src/proc.c b/src/proc.c index 978813f76..6aca2b84e 100644 --- a/src/proc.c +++ b/src/proc.c @@ -490,9 +490,8 @@ mrb_init_proc(mrb_state *mrb) mrb_method_t m; struct RClass *pc = mrb->proc_class = mrb_define_class_id(mrb, MRB_SYM(Proc), mrb->object_class); /* 15.2.17 */ - MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); - - MRB_SET_INSTANCE_TT(pc, MRB_TT_UNDEF); + MRB_SET_INSTANCE_TT(pc, MRB_TT_PROC); + MRB_UNDEF_ALLOCATOR(pc); mrb_define_class_method_id(mrb, pc, MRB_SYM(new), mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); mrb_define_method_id(mrb, pc, MRB_SYM(initialize_copy), mrb_proc_init_copy, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, pc, MRB_SYM(arity), proc_arity, MRB_ARGS_NONE()); /* 15.2.17.4.2 */