summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorSatoshi Tagomori <s-tagomori@sakura.ad.jp>2025-06-15 18:55:57 +0900
committerSatoshi Tagomori <tagomoris@gmail.com>2025-09-29 01:15:38 +0900
commit4f47327287c00836a9826805a8799678d2c18516 (patch)
tree5d143512012b55c5103169c1a9db42d5b19c19ca /internal
parent43392afb122819e568f35c6a8e528580b9604411 (diff)
Update current namespace management by using control frames and lexical contexts
to fix inconsistent and wrong current namespace detections. This includes: * Moving load_path and related things from rb_vm_t to rb_namespace_t to simplify accessing those values via namespace (instead of accessing either vm or ns) * Initializing root_namespace earlier and consolidate builtin_namespace into root_namespace * Adding VM_FRAME_FLAG_NS_REQUIRE for checkpoints to detect a namespace to load/require files * Removing implicit refinements in the root namespace which was used to determine the namespace to be loaded (replaced by VM_FRAME_FLAG_NS_REQUIRE) * Removing namespaces from rb_proc_t because its namespace can be identified by lexical context * Starting to use ep[VM_ENV_DATA_INDEX_SPECVAL] to store the current namespace when the frame type is MAGIC_TOP or MAGIC_CLASS (block handlers don't exist in this case)
Diffstat (limited to 'internal')
-rw-r--r--internal/class.h16
-rw-r--r--internal/inits.h3
-rw-r--r--internal/namespace.h21
3 files changed, 16 insertions, 24 deletions
diff --git a/internal/class.h b/internal/class.h
index bed69adef7..29b3526cf5 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -390,8 +390,7 @@ RCLASS_EXT_READABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
static inline rb_classext_t *
RCLASS_EXT_READABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
{
- if (!ns
- || NAMESPACE_BUILTIN_P(ns)
+ if (NAMESPACE_ROOT_P(ns)
|| RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
@@ -405,9 +404,9 @@ RCLASS_EXT_READABLE(VALUE obj)
if (RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
- // delay namespace loading to optimize for unmodified classes
+ // delay determining the current namespace to optimize for unmodified classes
ns = rb_current_namespace();
- if (!ns || NAMESPACE_BUILTIN_P(ns)) {
+ if (NAMESPACE_ROOT_P(ns)) {
return RCLASS_EXT_PRIME(obj);
}
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
@@ -440,8 +439,7 @@ RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
static inline rb_classext_t *
RCLASS_EXT_WRITABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
{
- if (!ns
- || NAMESPACE_BUILTIN_P(ns)
+ if (NAMESPACE_ROOT_P(ns)
|| RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
@@ -455,11 +453,9 @@ RCLASS_EXT_WRITABLE(VALUE obj)
if (LIKELY(RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj))) {
return RCLASS_EXT_PRIME(obj);
}
- // delay namespace loading to optimize for unmodified classes
+ // delay determining the current namespace to optimize for unmodified classes
ns = rb_current_namespace();
- if (!ns || NAMESPACE_BUILTIN_P(ns)) {
- // If no namespace is specified, Ruby VM is in bootstrap
- // and the clean class definition is under construction.
+ if (NAMESPACE_ROOT_P(ns)) {
return RCLASS_EXT_PRIME(obj);
}
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
diff --git a/internal/inits.h b/internal/inits.h
index e618d87cc3..c1cf3db94d 100644
--- a/internal/inits.h
+++ b/internal/inits.h
@@ -32,6 +32,9 @@ void Init_enable_namespace(void);
void Init_BareVM(void);
void Init_vm_objects(void);
+/* namespace.c */
+void Init_root_namespace(void);
+
/* vm_backtrace.c */
void Init_vm_backtrace(void);
diff --git a/internal/namespace.h b/internal/namespace.h
index 4cdfbc305f..c68f0987aa 100644
--- a/internal/namespace.h
+++ b/internal/namespace.h
@@ -35,13 +35,14 @@ struct rb_namespace_struct {
VALUE gvar_tbl;
- bool is_builtin;
bool is_user;
bool is_optional;
};
typedef struct rb_namespace_struct rb_namespace_t;
-#define NAMESPACE_BUILTIN_P(ns) (ns && ns->is_builtin)
+#define NAMESPACE_OBJ_P(obj) (CLASS_OF(obj) == rb_cNamespace)
+
+#define NAMESPACE_ROOT_P(ns) (ns && !ns->is_user)
#define NAMESPACE_USER_P(ns) (ns && ns->is_user)
#define NAMESPACE_OPTIONAL_P(ns) (ns && ns->is_optional)
#define NAMESPACE_MAIN_P(ns) (ns && ns->is_user && !ns->is_optional)
@@ -60,24 +61,16 @@ rb_namespace_available(void)
return ruby_namespace_enabled;
}
-void rb_namespace_enable_builtin(void);
-void rb_namespace_disable_builtin(void);
-void rb_namespace_push_loading_namespace(const rb_namespace_t *);
-void rb_namespace_pop_loading_namespace(const rb_namespace_t *);
-rb_namespace_t * rb_root_namespace(void);
-const rb_namespace_t *rb_builtin_namespace(void);
-rb_namespace_t * rb_main_namespace(void);
-const rb_namespace_t * rb_definition_namespace(void);
-const rb_namespace_t * rb_loading_namespace(void);
+const rb_namespace_t * rb_root_namespace(void);
+const rb_namespace_t * rb_main_namespace(void);
const rb_namespace_t * rb_current_namespace(void);
-VALUE rb_current_namespace_details(VALUE);
+const rb_namespace_t * rb_loading_namespace(void);
void rb_namespace_entry_mark(void *);
+void rb_namespace_gc_update_references(void *ptr);
rb_namespace_t * rb_get_namespace_t(VALUE ns);
VALUE rb_get_namespace_object(rb_namespace_t *ns);
-typedef VALUE namespace_exec_func(VALUE arg);
-VALUE rb_namespace_exec(const rb_namespace_t *ns, namespace_exec_func *func, VALUE arg);
VALUE rb_namespace_local_extension(VALUE namespace, VALUE fname, VALUE path);