Inherit MRB_FL_UNDEF_ALLOCATE in subclasses

If `Class#allocate` is prohibited, subclasses should also be implicitly prohibited.

```ruby
p Class.new(Struct).allocate.class
# => #<Class:0x82362ac00>                                             by #6122
# => allocator undefined for #<Class:0x000000083a983220> (TypeError)  by Ruby 3.2
```

Added `MRB_DEFINE_ALLOCATOR()` to allow subclasses to use `Class#allocate`.

Supplement to #6122.
This commit is contained in:
dearblue
2023-12-23 21:01:42 +09:00
parent 63580581f7
commit 2a1ea7d605
4 changed files with 4 additions and 0 deletions
+1
View File
@@ -78,6 +78,7 @@ mrb_class(mrb_state *mrb, mrb_value v)
#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)
#define MRB_DEFINE_ALLOCATOR(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);
+1
View File
@@ -228,6 +228,7 @@ make_data_class(mrb_state *mrb, mrb_value members, struct RClass *klass)
{
struct RClass *c = mrb_class_new(mrb, klass);
MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT);
MRB_DEFINE_ALLOCATOR(c);
mrb_value data = mrb_obj_value(c);
mrb_iv_set(mrb, data, MRB_SYM(__members__), members);
+1
View File
@@ -210,6 +210,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl
c = mrb_define_class_under_id(mrb, klass, id, klass);
}
MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT);
MRB_DEFINE_ALLOCATOR(c);
nstr = mrb_obj_value(c);
mrb_iv_set(mrb, nstr, MRB_SYM(__members__), members);
+1
View File
@@ -2207,6 +2207,7 @@ mrb_class_new(mrb_state *mrb, struct RClass *super)
c = boot_defclass(mrb, super);
if (super) {
MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
c->flags |= super->flags & MRB_FL_UNDEF_ALLOCATE;
}
make_metaclass(mrb, c);