@@ -644,14 +644,18 @@ class_switch_superclass(VALUE super, VALUE klass)
644644 * @note this function is not Class#allocate.
645645 */
646646static VALUE
647- class_alloc (enum ruby_value_type type , VALUE klass )
647+ class_alloc0 (enum ruby_value_type type , VALUE klass , bool namespaceable )
648648{
649649 rb_ns_subclasses_t * ns_subclasses ;
650650 rb_subclass_anchor_t * anchor ;
651651 const rb_namespace_t * ns = rb_definition_namespace ();
652652
653- size_t alloc_size = sizeof (struct RClass_and_rb_classext_t );
654653 if (!ruby_namespace_init_done ) {
654+ namespaceable = true;
655+ }
656+
657+ size_t alloc_size = sizeof (struct RClass_and_rb_classext_t );
658+ if (namespaceable ) {
655659 alloc_size = sizeof (struct RClass_namespaceable );
656660 }
657661
@@ -672,7 +676,7 @@ class_alloc(enum ruby_value_type type, VALUE klass)
672676
673677 VALUE flags = type ;
674678 if (RGENGC_WB_PROTECTED_CLASS ) flags |= FL_WB_PROTECTED ;
675- if (! ruby_namespace_init_done ) flags |= RCLASS_NAMESPACEABLE ;
679+ if (namespaceable ) flags |= RCLASS_NAMESPACEABLE ;
676680
677681 NEWOBJ_OF (obj , struct RClass , klass , flags , alloc_size , 0 );
678682
@@ -688,7 +692,7 @@ class_alloc(enum ruby_value_type type, VALUE klass)
688692 RCLASS_PRIME_NS ((VALUE )obj ) = ns ;
689693 // Classes/Modules defined in user namespaces are
690694 // writable directly because it exists only in a namespace.
691- RCLASS_SET_PRIME_CLASSEXT_WRITABLE ((VALUE )obj , ruby_namespace_init_done || NAMESPACE_USER_P (ns ));
695+ RCLASS_SET_PRIME_CLASSEXT_WRITABLE ((VALUE )obj , ! namespaceable || NAMESPACE_USER_P (ns ));
692696
693697 RCLASS_SET_ORIGIN ((VALUE )obj , (VALUE )obj );
694698 RCLASS_SET_REFINED_CLASS ((VALUE )obj , Qnil );
@@ -698,6 +702,12 @@ class_alloc(enum ruby_value_type type, VALUE klass)
698702 return (VALUE )obj ;
699703}
700704
705+ static VALUE
706+ class_alloc (enum ruby_value_type type , VALUE klass )
707+ {
708+ return class_alloc0 (type , klass , false);
709+ }
710+
701711static VALUE
702712class_associate_super (VALUE klass , VALUE super , bool init )
703713{
@@ -733,19 +743,10 @@ class_clear_method_table(VALUE c)
733743 RCLASS_WRITE_M_TBL_EVEN_WHEN_PROMOTED (c , rb_id_table_create (0 ));
734744}
735745
736- /**
737- * A utility function that wraps class_alloc.
738- *
739- * allocates a class and initializes safely.
740- * @param super a class from which the new class derives.
741- * @return a class object.
742- * @pre `super` must be a class.
743- * @post the metaclass of the new class is Class.
744- */
745- VALUE
746- rb_class_boot (VALUE super )
746+ static VALUE
747+ class_boot_namespaceable (VALUE super , bool namespaceable )
747748{
748- VALUE klass = class_alloc (T_CLASS , rb_cClass );
749+ VALUE klass = class_alloc0 (T_CLASS , rb_cClass , namespaceable );
749750
750751 // initialize method table prior to class_associate_super()
751752 // because class_associate_super() may cause GC and promote klass
@@ -759,6 +760,21 @@ rb_class_boot(VALUE super)
759760 return (VALUE )klass ;
760761}
761762
763+ /**
764+ * A utility function that wraps class_alloc.
765+ *
766+ * allocates a class and initializes safely.
767+ * @param super a class from which the new class derives.
768+ * @return a class object.
769+ * @pre `super` must be a class.
770+ * @post the metaclass of the new class is Class.
771+ */
772+ VALUE
773+ rb_class_boot (VALUE super )
774+ {
775+ return class_boot_namespaceable (super , false);
776+ }
777+
762778static VALUE *
763779class_superclasses_including_self (VALUE klass )
764780{
@@ -1254,7 +1270,7 @@ static inline VALUE
12541270make_metaclass (VALUE klass )
12551271{
12561272 VALUE super ;
1257- VALUE metaclass = rb_class_boot (Qundef );
1273+ VALUE metaclass = class_boot_namespaceable (Qundef , FL_TEST_RAW ( klass , RCLASS_NAMESPACEABLE ) );
12581274
12591275 FL_SET (metaclass , FL_SINGLETON );
12601276 rb_singleton_class_attached (metaclass , klass );
@@ -1290,7 +1306,7 @@ static inline VALUE
12901306make_singleton_class (VALUE obj )
12911307{
12921308 VALUE orig_class = METACLASS_OF (obj );
1293- VALUE klass = rb_class_boot (orig_class );
1309+ VALUE klass = class_boot_namespaceable (orig_class , FL_TEST_RAW ( orig_class , RCLASS_NAMESPACEABLE ) );
12941310
12951311 FL_SET (klass , FL_SINGLETON );
12961312 RBASIC_SET_CLASS (obj , klass );
0 commit comments