From d3128ce58a90c90f4c557e1a6bc2fa3860c992a2 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 9 Apr 2023 21:14:07 +0900 Subject: [PATCH] Allow `Class#allocate` to be prohibited Calling `Class#allocate` with `UnboundMethod#bind_call` usually succeeds without problems. If this behavior does not make us happy, we can now prohibit it with `MRB_SET_INSTANCE_TT(klass, MRB_TT_UNDEF)`. At the same time, it applies to the `Binding`, `Complex`, `Data`, `Float`, `Integer`, `Method`, `Rational` and `UnboundMethod` classes. --- mrbgems/mruby-binding/src/binding.c | 2 ++ mrbgems/mruby-complex/src/complex.c | 2 +- mrbgems/mruby-data/src/data.c | 2 +- mrbgems/mruby-method/src/method.c | 2 ++ mrbgems/mruby-rational/src/rational.c | 2 +- src/class.c | 3 +++ src/gc.c | 1 + src/numeric.c | 4 ++-- 8 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index f94c532a4..b4cbda2af 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -413,6 +414,7 @@ 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_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 ad88a67ec..c4e6c0b7a 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -392,7 +392,7 @@ 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_COMPLEX); + MRB_SET_INSTANCE_TT(comp, MRB_TT_UNDEF); 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 055914ef4..f25dc88d1 100644 --- a/mrbgems/mruby-data/src/data.c +++ b/mrbgems/mruby-data/src/data.c @@ -433,7 +433,7 @@ 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_STRUCT); + MRB_SET_INSTANCE_TT(d, MRB_TT_UNDEF); 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 f02d9bd1a..eecfbdd37 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -517,6 +517,7 @@ 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_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()); @@ -531,6 +532,7 @@ 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_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 3b13fb57c..a54324f47 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -769,7 +769,7 @@ 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_RATIONAL); + MRB_SET_INSTANCE_TT(rat, MRB_TT_UNDEF); 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/src/class.c b/src/class.c index 3c9346668..03abce021 100644 --- a/src/class.c +++ b/src/class.c @@ -1945,6 +1945,9 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) ttype = MRB_TT_OBJECT; } 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 e5488dfcc..bc57586cc 100644 --- a/src/gc.c +++ b/src/gc.c @@ -515,6 +515,7 @@ 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 d45a49841..649e0229e 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -2219,7 +2219,7 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ mrb->integer_class = integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ - MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER); + MRB_SET_INSTANCE_TT(integer, MRB_TT_UNDEF); mrb_undef_class_method(mrb, integer, "new"); mrb_define_method(mrb, integer, "**", int_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, integer, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ @@ -2264,7 +2264,7 @@ mrb_init_numeric(mrb_state *mrb) #ifndef MRB_NO_FLOAT /* Float Class */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ - MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); + MRB_SET_INSTANCE_TT(fl, MRB_TT_UNDEF); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method(mrb, fl, "**", flo_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */