diff options
author | Satoshi Tagomori <[email protected]> | 2025-04-30 13:48:02 +0900 |
---|---|---|
committer | Satoshi Tagomori <[email protected]> | 2025-05-11 23:32:50 +0900 |
commit | 382645d440d5da66a0c04557f3ff2ca226de3a27 () | |
tree | b7453449930197237e739d0985561b664f51b0f3 /variable.c | |
parent | 49742414f6444960838bb968bab43db27f5872c1 (diff) |
namespace on read
-rw-r--r-- | variable.c | 263 |
1 files changed, 228 insertions, 35 deletions
@@ -25,6 +25,7 @@ #include "internal/error.h" #include "internal/eval.h" #include "internal/hash.h" #include "internal/object.h" #include "internal/gc.h" #include "internal/re.h" @@ -109,10 +110,10 @@ classname(VALUE klass, bool *permanent) { *permanent = false; - VALUE classpath = RCLASS_EXT(klass)->classpath; if (classpath == 0) return Qnil; - *permanent = RCLASS_EXT(klass)->permanent_classpath; return classpath; } @@ -210,7 +211,7 @@ static enum rb_id_table_iterator_result set_sub_temporary_name_i(ID id, VALUE val, void *data) { val = ((rb_const_entry_t *)val)->value; - if (rb_namespace_p(val) && !RCLASS_EXT(val)->permanent_classpath) { VALUE arg = (VALUE)data; struct sub_temporary_name_args *args = data; args->last = id; @@ -222,7 +223,7 @@ set_sub_temporary_name_i(ID id, VALUE val, void *data) static void set_sub_temporary_name_foreach(VALUE mod, struct sub_temporary_name_args *args, VALUE name) { - RCLASS_SET_CLASSPATH(mod, name, FALSE); struct rb_id_table *tbl = RCLASS_CONST_TBL(mod); if (!tbl) return; if (!name) { @@ -296,7 +297,7 @@ VALUE rb_mod_set_temporary_name(VALUE mod, VALUE name) { // We don't allow setting the name if the classpath is already permanent: - if (RCLASS_EXT(mod)->permanent_classpath) { rb_raise(rb_eRuntimeError, "can't change permanent name"); } @@ -529,6 +530,7 @@ struct rb_global_variable { rb_gvar_marker_t *marker; rb_gvar_compact_t *compactor; struct trace_var *trace; }; struct rb_global_entry { @@ -604,6 +606,13 @@ rb_gvar_ractor_local(const char *name) entry->ractor_local = true; } static void rb_gvar_undef_compactor(void *var) { @@ -629,6 +638,7 @@ rb_global_entry(ID id) var->block_trace = 0; var->trace = 0; rb_id_table_insert(rb_global_tbl, id, (VALUE)entry); } return entry; @@ -982,13 +992,27 @@ rb_gvar_set_entry(struct rb_global_entry *entry, VALUE val) return val; } VALUE rb_gvar_set(ID id, VALUE val) { struct rb_global_entry *entry; entry = rb_global_entry(id); - return rb_gvar_set_entry(entry, val); } VALUE @@ -1000,9 +1024,27 @@ rb_gv_set(const char *name, VALUE val) VALUE rb_gvar_get(ID id) { struct rb_global_entry *entry = rb_global_entry(id); struct rb_global_variable *var = entry->var; - return (*var->getter)(entry->id, var->data); } VALUE @@ -1056,6 +1098,7 @@ rb_f_global_variables(void) if (!rb_ractor_main_p()) { rb_raise(rb_eRactorIsolationError, "can not access global variables from non-main Ractors"); } rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary); if (!NIL_P(backref)) { @@ -1335,7 +1378,7 @@ rb_obj_field_get(VALUE obj, rb_shape_t *target_shape) case T_CLASS: case T_MODULE: ASSERT_vm_locking(); - fields = RCLASS_FIELDS(obj); break; case T_OBJECT: fields = ROBJECT_FIELDS(obj); @@ -1392,7 +1435,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef) found = rb_shape_get_iv_index(shape, id, &index); if (found) { - ivar_list = RCLASS_FIELDS(obj); RUBY_ASSERT(ivar_list); val = ivar_list[index]; @@ -1501,7 +1544,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - table = RCLASS_FIELDS_HASH(obj); break; case T_OBJECT: @@ -1551,7 +1594,7 @@ obj_transition_too_complex(VALUE obj, st_table *table) break; case T_CLASS: case T_MODULE: - old_fields = RCLASS_FIELDS(obj); rb_shape_set_shape_id(obj, shape_id); RCLASS_SET_FIELDS_HASH(obj, table); break; @@ -2124,7 +2167,7 @@ rb_ivar_defined(VALUE obj, ID id) switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - table = (st_table *)RCLASS_FIELDS(obj); break; case T_OBJECT: @@ -2188,7 +2231,8 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu break; case T_CLASS: case T_MODULE: - iv_list = RCLASS_FIELDS(itr_data->obj); break; default: iv_list = itr_data->fields_tbl->as.shape.fields; @@ -2280,7 +2324,7 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, }; if (rb_shape_obj_too_complex_p(obj)) { - rb_st_foreach(RCLASS_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data); } else { iterate_over_shapes_with_callback(shape, func, &itr_data); @@ -2701,7 +2745,7 @@ autoload_data(VALUE mod, ID id) // If we are called with a non-origin ICLASS, fetch the autoload data from // the original module. if (RB_TYPE_P(mod, T_ICLASS)) { - if (FL_TEST_RAW(mod, RICLASS_IS_ORIGIN)) { return 0; } else { @@ -2729,6 +2773,10 @@ struct autoload_const { // The shared "autoload_data" if multiple constants are defined from the same feature. VALUE autoload_data_value; // The module we are loading a constant into. VALUE module; @@ -2866,6 +2914,70 @@ get_autoload_data(VALUE autoload_const_value, struct autoload_const **autoload_c return autoload_data; } void rb_autoload(VALUE module, ID name, const char *feature) { @@ -2883,6 +2995,7 @@ struct autoload_arguments { VALUE module; ID name; VALUE feature; }; static VALUE @@ -2952,6 +3065,7 @@ autoload_synchronized(VALUE _arguments) { struct autoload_const *autoload_const; VALUE autoload_const_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const); autoload_const->module = arguments->module; autoload_const->name = arguments->name; autoload_const->value = Qundef; @@ -2968,6 +3082,9 @@ autoload_synchronized(VALUE _arguments) void rb_autoload_str(VALUE module, ID name, VALUE feature) { if (!rb_is_const_id(name)) { rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"", QUOTE_ID(name)); } @@ -2981,6 +3098,7 @@ rb_autoload_str(VALUE module, ID name, VALUE feature) .module = module, .name = name, .feature = feature, }; VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments); @@ -3241,22 +3359,82 @@ autoload_apply_constants(VALUE _arguments) return Qtrue; } static VALUE autoload_feature_require(VALUE _arguments) { struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments; struct autoload_const *autoload_const = arguments->autoload_const; // We save this for later use in autoload_apply_constants: arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type); - VALUE result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature); if (RTEST(result)) { return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments); } - return result; } @@ -3580,6 +3758,8 @@ rb_mod_remove_const(VALUE mod, VALUE name) return rb_const_remove(mod, id); } VALUE rb_const_remove(VALUE mod, ID id) { @@ -3589,7 +3769,7 @@ rb_const_remove(VALUE mod, ID id) rb_check_frozen(mod); ce = rb_const_lookup(mod, id); - if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod), id)) { if (rb_const_defined_at(mod, id)) { rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id)); } @@ -3607,7 +3787,11 @@ rb_const_remove(VALUE mod, ID id) val = Qnil; } - ruby_xfree(ce); return val; } @@ -3829,8 +4013,8 @@ set_namespace_path_i(ID id, VALUE v, void *payload) } set_namespace_path(value, build_const_path(parental_path, id)); - if (!RCLASS_EXT(value)->permanent_classpath) { - RCLASS_SET_CLASSPATH(value, 0, false); } return ID_TABLE_CONTINUE; @@ -3848,7 +4032,7 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path) RB_VM_LOCK_ENTER(); { - RCLASS_SET_CLASSPATH(named_namespace, namespace_path, true); if (const_table) { rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path); @@ -3884,9 +4068,10 @@ const_set(VALUE klass, ID id, VALUE val) RB_VM_LOCK_ENTER(); { - struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); if (!tbl) { - RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0); rb_clear_constant_cache_for_id(id); ce = ZALLOC(rb_const_entry_t); rb_id_table_insert(tbl, id, (VALUE)ce); @@ -4010,6 +4195,7 @@ const_tbl_update(struct autoload_const *ac, int autoload_force) setup_const_entry(ce, klass, val, visibility); } else { rb_clear_constant_cache_for_id(id); ce = ZALLOC(rb_const_entry_t); @@ -4172,7 +4358,7 @@ static int cvar_lookup_at(VALUE klass, ID id, st_data_t *v) { if (RB_TYPE_P(klass, T_ICLASS)) { - if (FL_TEST_RAW(klass, RICLASS_IS_ORIGIN)) { return 0; } else { @@ -4277,10 +4463,11 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) int result = rb_class_ivar_set(target, id, val); - struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(target); if (!rb_cvc_tbl) { - rb_cvc_tbl = RCLASS_CVC_TBL(target) = rb_id_table_create(2); } struct rb_cvar_class_tbl_entry *ent; @@ -4304,7 +4491,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) // cvar in this lookup. if (result == 0) { if (RB_TYPE_P(target, T_CLASS)) { - if (RCLASS_SUBCLASSES(target)) { rb_class_foreach_subclass(target, check_for_cvar_table, id); } } @@ -4538,13 +4725,13 @@ class_ivar_set_shape_fields(VALUE obj, void *_data) { RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj)); - return RCLASS_FIELDS(obj); } static void class_ivar_set_shape_resize_fields(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data) { - REALLOC_N(RCLASS_FIELDS(obj), VALUE, new_capa); } static void @@ -4564,7 +4751,7 @@ class_ivar_set_too_complex_table(VALUE obj, void *_data) { RUBY_ASSERT(rb_shape_obj_too_complex_p(obj)); - return RCLASS_FIELDS_HASH(obj); } int @@ -4574,6 +4761,8 @@ rb_class_ivar_set(VALUE obj, ID id, VALUE val) bool existing = false; rb_check_frozen(obj); RB_VM_LOCK_ENTER(); { existing = general_ivar_set(obj, id, val, NULL, @@ -4620,11 +4809,9 @@ rb_fields_tbl_copy(VALUE dst, VALUE src) rb_ivar_foreach(src, tbl_copy_i, dst); } -rb_const_entry_t * -rb_const_lookup(VALUE klass, ID id) { - struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); - if (tbl) { VALUE val; bool r; @@ -4638,3 +4825,9 @@ rb_const_lookup(VALUE klass, ID id) } return NULL; } |