diff options
| author | Satoshi Tagomori <s-tagomori@sakura.ad.jp> | 2025-06-15 18:55:57 +0900 |
|---|---|---|
| committer | Satoshi Tagomori <tagomoris@gmail.com> | 2025-09-29 01:15:38 +0900 |
| commit | 4f47327287c00836a9826805a8799678d2c18516 (patch) | |
| tree | 5d143512012b55c5103169c1a9db42d5b19c19ca /internal | |
| parent | 43392afb122819e568f35c6a8e528580b9604411 (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.h | 16 | ||||
| -rw-r--r-- | internal/inits.h | 3 | ||||
| -rw-r--r-- | internal/namespace.h | 21 |
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); |
