mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Allocate singleton classes as namespaceable if their parent are
This commit is contained in:
parent
32ee3fab0a
commit
c6dd07d66f
1 changed files with 34 additions and 18 deletions
52
class.c
52
class.c
|
@ -644,14 +644,18 @@ class_switch_superclass(VALUE super, VALUE klass)
|
|||
* @note this function is not Class#allocate.
|
||||
*/
|
||||
static VALUE
|
||||
class_alloc(enum ruby_value_type type, VALUE klass)
|
||||
class_alloc0(enum ruby_value_type type, VALUE klass, bool namespaceable)
|
||||
{
|
||||
rb_ns_subclasses_t *ns_subclasses;
|
||||
rb_subclass_anchor_t *anchor;
|
||||
const rb_namespace_t *ns = rb_definition_namespace();
|
||||
|
||||
size_t alloc_size = sizeof(struct RClass_and_rb_classext_t);
|
||||
if (!ruby_namespace_init_done) {
|
||||
namespaceable = true;
|
||||
}
|
||||
|
||||
size_t alloc_size = sizeof(struct RClass_and_rb_classext_t);
|
||||
if (namespaceable) {
|
||||
alloc_size = sizeof(struct RClass_namespaceable);
|
||||
}
|
||||
|
||||
|
@ -672,7 +676,7 @@ class_alloc(enum ruby_value_type type, VALUE klass)
|
|||
|
||||
VALUE flags = type;
|
||||
if (RGENGC_WB_PROTECTED_CLASS) flags |= FL_WB_PROTECTED;
|
||||
if (!ruby_namespace_init_done) flags |= RCLASS_NAMESPACEABLE;
|
||||
if (namespaceable) flags |= RCLASS_NAMESPACEABLE;
|
||||
|
||||
NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size, 0);
|
||||
|
||||
|
@ -688,7 +692,7 @@ class_alloc(enum ruby_value_type type, VALUE klass)
|
|||
RCLASS_PRIME_NS((VALUE)obj) = ns;
|
||||
// Classes/Modules defined in user namespaces are
|
||||
// writable directly because it exists only in a namespace.
|
||||
RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, ruby_namespace_init_done || NAMESPACE_USER_P(ns));
|
||||
RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, !namespaceable || NAMESPACE_USER_P(ns));
|
||||
|
||||
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
|
||||
RCLASS_SET_REFINED_CLASS((VALUE)obj, Qnil);
|
||||
|
@ -698,6 +702,12 @@ class_alloc(enum ruby_value_type type, VALUE klass)
|
|||
return (VALUE)obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
class_alloc(enum ruby_value_type type, VALUE klass)
|
||||
{
|
||||
return class_alloc0(type, klass, false);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
class_associate_super(VALUE klass, VALUE super, bool init)
|
||||
{
|
||||
|
@ -733,6 +743,23 @@ class_clear_method_table(VALUE c)
|
|||
RCLASS_WRITE_M_TBL_EVEN_WHEN_PROMOTED(c, rb_id_table_create(0));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
class_boot_namespaceable(VALUE super, bool namespaceable)
|
||||
{
|
||||
VALUE klass = class_alloc0(T_CLASS, rb_cClass, namespaceable);
|
||||
|
||||
// initialize method table prior to class_associate_super()
|
||||
// because class_associate_super() may cause GC and promote klass
|
||||
class_initialize_method_table(klass);
|
||||
|
||||
class_associate_super(klass, super, true);
|
||||
if (super && !UNDEF_P(super)) {
|
||||
rb_class_set_initialized(klass);
|
||||
}
|
||||
|
||||
return (VALUE)klass;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility function that wraps class_alloc.
|
||||
*
|
||||
|
@ -745,18 +772,7 @@ class_clear_method_table(VALUE c)
|
|||
VALUE
|
||||
rb_class_boot(VALUE super)
|
||||
{
|
||||
VALUE klass = class_alloc(T_CLASS, rb_cClass);
|
||||
|
||||
// initialize method table prior to class_associate_super()
|
||||
// because class_associate_super() may cause GC and promote klass
|
||||
class_initialize_method_table(klass);
|
||||
|
||||
class_associate_super(klass, super, true);
|
||||
if (super && !UNDEF_P(super)) {
|
||||
rb_class_set_initialized(klass);
|
||||
}
|
||||
|
||||
return (VALUE)klass;
|
||||
return class_boot_namespaceable(super, false);
|
||||
}
|
||||
|
||||
static VALUE *
|
||||
|
@ -1254,7 +1270,7 @@ static inline VALUE
|
|||
make_metaclass(VALUE klass)
|
||||
{
|
||||
VALUE super;
|
||||
VALUE metaclass = rb_class_boot(Qundef);
|
||||
VALUE metaclass = class_boot_namespaceable(Qundef, FL_TEST_RAW(klass, RCLASS_NAMESPACEABLE));
|
||||
|
||||
FL_SET(metaclass, FL_SINGLETON);
|
||||
rb_singleton_class_attached(metaclass, klass);
|
||||
|
@ -1290,7 +1306,7 @@ static inline VALUE
|
|||
make_singleton_class(VALUE obj)
|
||||
{
|
||||
VALUE orig_class = METACLASS_OF(obj);
|
||||
VALUE klass = rb_class_boot(orig_class);
|
||||
VALUE klass = class_boot_namespaceable(orig_class, FL_TEST_RAW(orig_class, RCLASS_NAMESPACEABLE));
|
||||
|
||||
FL_SET(klass, FL_SINGLETON);
|
||||
RBASIC_SET_CLASS(obj, klass);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue