Skip to content

Commit 96a0c20

Browse files
committed
Mark RClass instance that may be namespaced with RCLASS_NAMESPACEABLE
1 parent 393e9a5 commit 96a0c20

File tree

6 files changed

+24
-5
lines changed

6 files changed

+24
-5
lines changed

class.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@
4444
* If unset, the prime classext is writable only from the root namespace.
4545
* 3: RCLASS_IS_INITIALIZED
4646
* Class has been initialized.
47+
* 4: RCLASS_NAMESPACEABLE
48+
* Is a builtin class that may be namespaced. It larger than a normal class.
4749
*/
4850

4951
/* Flags of T_ICLASS
5052
*
5153
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
5254
* This module's prime classext is the only classext and writable from any namespaces.
5355
* If unset, the prime classext is writable only from the root namespace.
56+
* 4: RCLASS_NAMESPACEABLE
57+
* Is a builtin class that may be namespaced. It larger than a normal class.
5458
*/
5559

5660
/* Flags of T_MODULE
@@ -65,6 +69,8 @@
6569
* If unset, the prime classext is writable only from the root namespace.
6670
* 3: RCLASS_IS_INITIALIZED
6771
* Module has been initialized.
72+
* 4: RCLASS_NAMESPACEABLE
73+
* Is a builtin class that may be namespaced. It larger than a normal class.
6874
*/
6975

7076
#define METACLASS_OF(k) RBASIC(k)->klass
@@ -662,6 +668,8 @@ class_alloc(enum ruby_value_type type, VALUE klass)
662668

663669
VALUE flags = type;
664670
if (RGENGC_WB_PROTECTED_CLASS) flags |= FL_WB_PROTECTED;
671+
if (!ruby_namespace_init_done) flags |= RCLASS_NAMESPACEABLE;
672+
665673
NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size, 0);
666674

667675
memset(RCLASS_EXT_PRIME(obj), 0, sizeof(rb_classext_t));
@@ -676,7 +684,7 @@ class_alloc(enum ruby_value_type type, VALUE klass)
676684
RCLASS_PRIME_NS((VALUE)obj) = ns;
677685
// Classes/Modules defined in user namespaces are
678686
// writable directly because it exists only in a namespace.
679-
RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, !rb_namespace_available() || NAMESPACE_USER_P(ns) ? true : false);
687+
RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, ruby_namespace_init_done || NAMESPACE_USER_P(ns));
680688

681689
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
682690
RCLASS_SET_REFINED_CLASS((VALUE)obj, Qnil);

internal/class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ static inline void RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool per
293293
#define RCLASS_PRIME_CLASSEXT_WRITABLE FL_USER2
294294
#define RCLASS_IS_INITIALIZED FL_USER3
295295
// 3 is RMODULE_IS_REFINEMENT for RMODULE
296+
#define RCLASS_NAMESPACEABLE FL_USER4
296297

297298
/* class.c */
298299
rb_classext_t * rb_class_duplicate_classext(rb_classext_t *orig, VALUE obj, const rb_namespace_t *ns);

internal/namespace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef struct rb_namespace_struct rb_namespace_t;
5252
#define NAMESPACE_CC_ENTRIES(ccs) (ccs ? NAMESPACE_METHOD_ENTRY(ccs->cme) : NULL)
5353

5454
RUBY_EXTERN bool ruby_namespace_enabled;
55+
RUBY_EXTERN bool ruby_namespace_init_done;
5556

5657
static inline bool
5758
rb_namespace_available(void)
@@ -81,5 +82,5 @@ VALUE rb_namespace_exec(const rb_namespace_t *ns, namespace_exec_func *func, VAL
8182
VALUE rb_namespace_local_extension(VALUE namespace, VALUE fname, VALUE path);
8283

8384
void rb_initialize_main_namespace(void);
84-
85+
void rb_namespace_init_done(void);
8586
#endif /* INTERNAL_NAMESPACE_H */

lib/rubygems.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# frozen_string_literal: true
2-
32
#--
43
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
54
# All rights reserved.

namespace.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,19 @@ static bool tmp_dir_has_dirsep;
4848
#endif
4949

5050
bool ruby_namespace_enabled = false; // extern
51+
bool ruby_namespace_init_done = false; // extern
5152

5253
VALUE rb_resolve_feature_path(VALUE klass, VALUE fname);
5354
static VALUE rb_namespace_inspect(VALUE obj);
5455
static void namespace_push(rb_thread_t *th, VALUE namespace);
5556
static VALUE namespace_pop(VALUE th_value);
5657

58+
void
59+
rb_namespace_init_done(void)
60+
{
61+
ruby_namespace_init_done = true;
62+
}
63+
5764
void
5865
rb_namespace_enable_builtin(void)
5966
{
@@ -1019,6 +1026,9 @@ Init_enable_namespace(void)
10191026
if (env && strlen(env) == 1 && env[0] == '1') {
10201027
ruby_namespace_enabled = true;
10211028
}
1029+
else {
1030+
ruby_namespace_init_done = true;
1031+
}
10221032
}
10231033

10241034
void

ruby.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,8 +1822,6 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
18221822
GET_VM()->running = 1;
18231823
memset(ruby_vm_redefined_flag, 0, sizeof(ruby_vm_redefined_flag));
18241824

1825-
ruby_init_prelude();
1826-
18271825
if (rb_namespace_available())
18281826
rb_initialize_main_namespace();
18291827

@@ -1844,6 +1842,8 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
18441842
Init_builtin_yjit_hook();
18451843
#endif
18461844

1845+
rb_namespace_init_done();
1846+
ruby_init_prelude();
18471847
ruby_set_script_name(opt->script_name);
18481848
require_libraries(&opt->req_list);
18491849
}

0 commit comments

Comments
 (0)