1 /**********************************************************************
6 created at: Tue Apr 19 23:55:15 JST 1994
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
12 **********************************************************************/
14 #include "ruby/internal/config.h"
16 #include "ruby/internal/stdbool.h"
17 #include "ccan/list/list.h"
19 #include "debug_counter.h"
23 #include "internal/class.h"
24 #include "internal/compilers.h"
25 #include "internal/error.h"
26 #include "internal/eval.h"
27 #include "internal/hash.h"
28 #include "internal/object.h"
29 #include "internal/re.h"
30 #include "internal/symbol.h"
31 #include "internal/thread.h"
32 #include "internal/variable.h"
33 #include "ruby/encoding.h"
35 #include "ruby/util.h"
40 #include "ractor_core.h"
43 RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state
;
44 #define GET_GLOBAL_CVAR_STATE() (ruby_vm_global_cvar_state)
46 typedef void rb_gvar_compact_t(void *var
);
48 static struct rb_id_table
*rb_global_tbl
;
51 // This hash table maps file paths to loadable features. We use this to track
52 // autoload state until it's no longer needed.
53 // feature (file path) => struct autoload_data
54 static VALUE autoload_features
;
56 // This mutex is used to protect autoloading state. We use a global mutex which
57 // is held until a per-feature mutex can be created. This ensures there are no
58 // race conditions relating to autoload state.
59 static VALUE autoload_mutex
;
61 static void check_before_mod_set(VALUE
, ID
, VALUE
, const char *);
62 static void setup_const_entry(rb_const_entry_t
*, VALUE
, VALUE
, rb_const_flag_t
);
63 static VALUE
rb_const_search(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
);
64 static st_table
*generic_iv_tbl_
;
69 rb_global_tbl
= rb_id_table_create(0);
70 generic_iv_tbl_
= st_init_numtable();
71 autoload
= rb_intern_const("__autoload__");
73 autoload_mutex
= rb_mutex_new();
74 rb_obj_hide(autoload_mutex
);
75 rb_vm_register_global_object(autoload_mutex
);
77 autoload_features
= rb_ident_hash_new();
78 rb_obj_hide(autoload_features
);
79 rb_vm_register_global_object(autoload_features
);
83 rb_namespace_p(VALUE obj
)
85 if (RB_SPECIAL_CONST_P(obj
)) return false;
86 switch (RB_BUILTIN_TYPE(obj
)) {
87 case T_MODULE
: case T_CLASS
: return true;
94 * Returns +classpath+ of _klass_, if it is named, or +nil+ for
95 * anonymous +class+/+module+. A named +classpath+ may contain
96 * an anonymous component, but the last component is guaranteed
97 * to not be anonymous. <code>*permanent</code> is set to 1
98 * if +classpath+ has no anonymous components. There is no builtin
99 * Ruby level APIs that can change a permanent +classpath+.
102 classname(VALUE klass
, bool *permanent
)
106 VALUE classpath
= RCLASS_EXT(klass
)->classpath
;
107 if (classpath
== 0) return Qnil
;
109 *permanent
= RCLASS_EXT(klass
)->permanent_classpath
;
115 rb_mod_name0(VALUE klass
, bool *permanent
)
117 return classname(klass
, permanent
);
122 * mod.name -> string or nil
124 * Returns the name of the module <i>mod</i>. Returns +nil+ for anonymous modules.
128 rb_mod_name(VALUE mod
)
131 return classname(mod
, &permanent
);
134 // Similar to logic in rb_mod_const_get().
136 is_constant_path(VALUE name
)
138 const char *path
= RSTRING_PTR(name
);
139 const char *pend
= RSTRING_END(name
);
140 rb_encoding
*enc
= rb_enc_get(name
);
142 const char *p
= path
;
144 if (p
>= pend
|| !*p
) {
149 if (p
+ 2 <= pend
&& p
[0] == ':' && p
[1] == ':') {
153 const char *pbeg
= p
;
154 while (p
< pend
&& *p
!= ':') p
++;
156 if (pbeg
== p
) return false;
158 if (rb_enc_symname_type(pbeg
, p
- pbeg
, enc
, 0) != ID_CONST
) {
168 * mod.set_temporary_name(string) -> self
169 * mod.set_temporary_name(nil) -> self
171 * Sets the temporary name of the module. This name is reflected in
172 * introspection of the module and the values that are related to it, such
173 * as instances, constants, and methods.
175 * The name should be +nil+ or a non-empty string that is not a valid constant
176 * path (to avoid confusing between permanent and temporary names).
178 * The method can be useful to distinguish dynamically generated classes and
179 * modules without assigning them to constants.
181 * If the module is given a permanent name by assigning it to a constant,
182 * the temporary name is discarded. A temporary name can't be assigned to
183 * modules that have a permanent name.
185 * If the given name is +nil+, the module becomes anonymous again.
189 * m = Module.new # => #<Module:0x0000000102c68f38>
192 * m.set_temporary_name("fake_name") # => fake_name
193 * m.name #=> "fake_name"
195 * m.set_temporary_name(nil) # => #<Module:0x0000000102c68f38>
199 * c.set_temporary_name("MyClass(with description)")
201 * c.new # => #<MyClass(with description):0x0....>
204 * c::M.name #=> "MyClass(with description)::M"
206 * # Assigning to a constant replaces the name with a permanent one
210 * C::M.name #=> "C::M"
211 * c.new # => #<C:0x0....>
215 rb_mod_set_temporary_name(VALUE mod
, VALUE name
)
217 // We don't allow setting the name if the classpath is already permanent:
218 if (RCLASS_EXT(mod
)->permanent_classpath
) {
219 rb_raise(rb_eRuntimeError
, "can't change permanent name");
223 // Set the temporary classpath to NULL (anonymous):
224 RCLASS_SET_CLASSPATH(mod
, 0, FALSE
);
227 // Ensure the name is a string:
230 if (RSTRING_LEN(name
) == 0) {
231 rb_raise(rb_eArgError
, "empty class/module name");
234 if (is_constant_path(name
)) {
235 rb_raise(rb_eArgError
, "the temporary name must not be a constant path to avoid confusion");
238 // Set the temporary classpath to the given name:
239 RCLASS_SET_CLASSPATH(mod
, name
, FALSE
);
246 make_temporary_path(VALUE obj
, VALUE klass
)
251 path
= rb_sprintf("#<Class:%p>", (void*)obj
);
254 path
= rb_sprintf("#<Module:%p>", (void*)obj
);
257 path
= rb_sprintf("#<%"PRIsVALUE
":%p>", klass
, (void*)obj
);
264 typedef VALUE (*fallback_func
)(VALUE obj
, VALUE name
);
267 rb_tmp_class_path(VALUE klass
, bool *permanent
, fallback_func fallback
)
269 VALUE path
= classname(klass
, permanent
);
275 if (RB_TYPE_P(klass
, T_MODULE
)) {
276 if (rb_obj_class(klass
) == rb_cModule
) {
281 path
= rb_tmp_class_path(RBASIC(klass
)->klass
, &perm
, fallback
);
286 return fallback(klass
, path
);
290 rb_class_path(VALUE klass
)
293 VALUE path
= rb_tmp_class_path(klass
, &permanent
, make_temporary_path
);
294 if (!NIL_P(path
)) path
= rb_str_dup(path
);
299 rb_class_path_cached(VALUE klass
)
301 return rb_mod_name(klass
);
305 no_fallback(VALUE obj
, VALUE name
)
311 rb_search_class_path(VALUE klass
)
314 return rb_tmp_class_path(klass
, &permanent
, no_fallback
);
318 build_const_pathname(VALUE head
, VALUE tail
)
320 VALUE path
= rb_str_dup(head
);
321 rb_str_cat2(path
, "::");
322 rb_str_append(path
, tail
);
323 return rb_fstring(path
);
327 build_const_path(VALUE head
, ID tail
)
329 return build_const_pathname(head
, rb_id2str(tail
));
333 rb_set_class_path_string(VALUE klass
, VALUE under
, VALUE name
)
335 bool permanent
= true;
338 if (under
== rb_cObject
) {
339 str
= rb_str_new_frozen(name
);
342 str
= rb_tmp_class_path(under
, &permanent
, make_temporary_path
);
343 str
= build_const_pathname(str
, name
);
346 RCLASS_SET_CLASSPATH(klass
, str
, permanent
);
350 rb_set_class_path(VALUE klass
, VALUE under
, const char *name
)
352 VALUE str
= rb_str_new2(name
);
354 rb_set_class_path_string(klass
, under
, str
);
358 rb_path_to_class(VALUE pathname
)
360 rb_encoding
*enc
= rb_enc_get(pathname
);
361 const char *pbeg
, *pend
, *p
, *path
= RSTRING_PTR(pathname
);
363 VALUE c
= rb_cObject
;
365 if (!rb_enc_asciicompat(enc
)) {
366 rb_raise(rb_eArgError
, "invalid class path encoding (non ASCII)");
369 pend
= path
+ RSTRING_LEN(pathname
);
370 if (path
== pend
|| path
[0] == '#') {
371 rb_raise(rb_eArgError
, "can't retrieve anonymous class %"PRIsVALUE
,
375 while (p
< pend
&& *p
!= ':') p
++;
376 id
= rb_check_id_cstr(pbeg
, p
-pbeg
, enc
);
377 if (p
< pend
&& p
[0] == ':') {
378 if ((size_t)(pend
- p
) < 2 || p
[1] != ':') goto undefined_class
;
383 goto undefined_class
;
385 c
= rb_const_search(c
, id
, TRUE
, FALSE
, FALSE
);
386 if (UNDEF_P(c
)) goto undefined_class
;
387 if (!rb_namespace_p(c
)) {
388 rb_raise(rb_eTypeError
, "%"PRIsVALUE
" does not refer to class/module",
392 RB_GC_GUARD(pathname
);
397 rb_raise(rb_eArgError
, "undefined class/module % "PRIsVALUE
,
398 rb_str_subseq(pathname
, 0, p
-path
));
399 UNREACHABLE_RETURN(Qundef
);
403 rb_path2class(const char *path
)
405 return rb_path_to_class(rb_str_new_cstr(path
));
409 rb_class_name(VALUE klass
)
411 return rb_class_path(rb_class_real(klass
));
415 rb_class2name(VALUE klass
)
418 VALUE path
= rb_tmp_class_path(rb_class_real(klass
), &permanent
, make_temporary_path
);
419 if (NIL_P(path
)) return NULL
;
420 return RSTRING_PTR(path
);
424 rb_obj_classname(VALUE obj
)
426 return rb_class2name(CLASS_OF(obj
));
431 void (*func
)(VALUE arg
, VALUE val
);
433 struct trace_var
*next
;
436 struct rb_global_variable
{
440 rb_gvar_getter_t
*getter
;
441 rb_gvar_setter_t
*setter
;
442 rb_gvar_marker_t
*marker
;
443 rb_gvar_compact_t
*compactor
;
444 struct trace_var
*trace
;
447 struct rb_global_entry
{
448 struct rb_global_variable
*var
;
453 static enum rb_id_table_iterator_result
454 free_global_entry_i(ID key
, VALUE val
, void *arg
)
456 struct rb_global_entry
*entry
= (struct rb_global_entry
*)val
;
457 if (entry
->var
->counter
== 1) {
458 ruby_xfree(entry
->var
);
461 entry
->var
->counter
--;
464 return ID_TABLE_DELETE
;
468 rb_free_rb_global_tbl(void)
470 rb_id_table_foreach(rb_global_tbl
, free_global_entry_i
, 0);
471 rb_id_table_free(rb_global_tbl
);
475 rb_free_generic_iv_tbl_(void)
477 st_free_table(generic_iv_tbl_
);
480 static struct rb_global_entry
*
481 rb_find_global_entry(ID id
)
483 struct rb_global_entry
*entry
;
486 if (!rb_id_table_lookup(rb_global_tbl
, id
, &data
)) {
490 entry
= (struct rb_global_entry
*)data
;
491 RUBY_ASSERT(entry
!= NULL
);
494 if (UNLIKELY(!rb_ractor_main_p()) && (!entry
|| !entry
->ractor_local
)) {
495 rb_raise(rb_eRactorIsolationError
, "can not access global variables %s from non-main Ractors", rb_id2name(id
));
502 rb_gvar_ractor_local(const char *name
)
504 struct rb_global_entry
*entry
= rb_find_global_entry(rb_intern(name
));
505 entry
->ractor_local
= true;
509 rb_gvar_undef_compactor(void *var
)
513 static struct rb_global_entry
*
514 rb_global_entry(ID id
)
516 struct rb_global_entry
*entry
= rb_find_global_entry(id
);
518 struct rb_global_variable
*var
;
519 entry
= ALLOC(struct rb_global_entry
);
520 var
= ALLOC(struct rb_global_variable
);
523 entry
->ractor_local
= false;
526 var
->getter
= rb_gvar_undef_getter
;
527 var
->setter
= rb_gvar_undef_setter
;
528 var
->marker
= rb_gvar_undef_marker
;
529 var
->compactor
= rb_gvar_undef_compactor
;
531 var
->block_trace
= 0;
533 rb_id_table_insert(rb_global_tbl
, id
, (VALUE
)entry
);
539 rb_gvar_undef_getter(ID id
, VALUE
*_
)
541 rb_warning("global variable '%"PRIsVALUE
"' not initialized", QUOTE_ID(id
));
547 rb_gvar_val_compactor(void *_var
)
549 struct rb_global_variable
*var
= (struct rb_global_variable
*)_var
;
551 VALUE obj
= (VALUE
)var
->data
;
554 VALUE
new = rb_gc_location(obj
);
556 var
->data
= (void*)new;
562 rb_gvar_undef_setter(VALUE val
, ID id
, VALUE
*_
)
564 struct rb_global_variable
*var
= rb_global_entry(id
)->var
;
565 var
->getter
= rb_gvar_val_getter
;
566 var
->setter
= rb_gvar_val_setter
;
567 var
->marker
= rb_gvar_val_marker
;
568 var
->compactor
= rb_gvar_val_compactor
;
570 var
->data
= (void*)val
;
574 rb_gvar_undef_marker(VALUE
*var
)
579 rb_gvar_val_getter(ID id
, VALUE
*data
)
585 rb_gvar_val_setter(VALUE val
, ID id
, VALUE
*_
)
587 struct rb_global_variable
*var
= rb_global_entry(id
)->var
;
588 var
->data
= (void*)val
;
592 rb_gvar_val_marker(VALUE
*var
)
594 VALUE data
= (VALUE
)var
;
595 if (data
) rb_gc_mark_movable(data
);
599 rb_gvar_var_getter(ID id
, VALUE
*var
)
601 if (!var
) return Qnil
;
606 rb_gvar_var_setter(VALUE val
, ID id
, VALUE
*data
)
612 rb_gvar_var_marker(VALUE
*var
)
614 if (var
) rb_gc_mark_maybe(*var
);
618 rb_gvar_readonly_setter(VALUE v
, ID id
, VALUE
*_
)
620 rb_name_error(id
, "%"PRIsVALUE
" is a read-only variable", QUOTE_ID(id
));
623 static enum rb_id_table_iterator_result
624 mark_global_entry(VALUE v
, void *ignored
)
626 struct rb_global_entry
*entry
= (struct rb_global_entry
*)v
;
627 struct trace_var
*trace
;
628 struct rb_global_variable
*var
= entry
->var
;
630 (*var
->marker
)(var
->data
);
633 if (trace
->data
) rb_gc_mark_maybe(trace
->data
);
636 return ID_TABLE_CONTINUE
;
639 #define gc_mark_table(task) \
640 if (rb_global_tbl) { rb_id_table_foreach_values(rb_global_tbl, task##_global_entry, 0); }
643 rb_gc_mark_global_tbl(void)
648 static enum rb_id_table_iterator_result
649 update_global_entry(VALUE v
, void *ignored
)
651 struct rb_global_entry
*entry
= (struct rb_global_entry
*)v
;
652 struct rb_global_variable
*var
= entry
->var
;
654 (*var
->compactor
)(var
);
655 return ID_TABLE_CONTINUE
;
659 rb_gc_update_global_tbl(void)
661 gc_mark_table(update
);
665 global_id(const char *name
)
669 if (name
[0] == '$') id
= rb_intern(name
);
671 size_t len
= strlen(name
);
673 char *buf
= ALLOCV_N(char, vbuf
, len
+1);
675 memcpy(buf
+1, name
, len
);
676 id
= rb_intern2(buf
, len
+1);
683 find_global_id(const char *name
)
686 size_t len
= strlen(name
);
688 if (name
[0] == '$') {
689 id
= rb_check_id_cstr(name
, len
, NULL
);
693 char *buf
= ALLOCV_N(char, vbuf
, len
+1);
695 memcpy(buf
+1, name
, len
);
696 id
= rb_check_id_cstr(buf
, len
+1, NULL
);
704 rb_define_hooked_variable(
707 rb_gvar_getter_t
*getter
,
708 rb_gvar_setter_t
*setter
)
710 volatile VALUE tmp
= var
? *var
: Qnil
;
711 ID id
= global_id(name
);
712 struct rb_global_variable
*gvar
= rb_global_entry(id
)->var
;
714 gvar
->data
= (void*)var
;
715 gvar
->getter
= getter
? (rb_gvar_getter_t
*)getter
: rb_gvar_var_getter
;
716 gvar
->setter
= setter
? (rb_gvar_setter_t
*)setter
: rb_gvar_var_setter
;
717 gvar
->marker
= rb_gvar_var_marker
;
723 rb_define_variable(const char *name
, VALUE
*var
)
725 rb_define_hooked_variable(name
, var
, 0, 0);
729 rb_define_readonly_variable(const char *name
, const VALUE
*var
)
731 rb_define_hooked_variable(name
, (VALUE
*)var
, 0, rb_gvar_readonly_setter
);
735 rb_define_virtual_variable(
737 rb_gvar_getter_t
*getter
,
738 rb_gvar_setter_t
*setter
)
740 if (!getter
) getter
= rb_gvar_val_getter
;
741 if (!setter
) setter
= rb_gvar_readonly_setter
;
742 rb_define_hooked_variable(name
, 0, getter
, setter
);
746 rb_trace_eval(VALUE cmd
, VALUE val
)
748 rb_eval_cmd_kw(cmd
, rb_ary_new3(1, val
), RB_NO_KEYWORDS
);
752 rb_f_trace_var(int argc
, const VALUE
*argv
)
755 struct rb_global_entry
*entry
;
756 struct trace_var
*trace
;
758 if (rb_scan_args(argc
, argv
, "11", &var
, &cmd
) == 1) {
759 cmd
= rb_block_proc();
762 return rb_f_untrace_var(argc
, argv
);
764 entry
= rb_global_entry(rb_to_id(var
));
765 trace
= ALLOC(struct trace_var
);
766 trace
->next
= entry
->var
->trace
;
767 trace
->func
= rb_trace_eval
;
770 entry
->var
->trace
= trace
;
776 remove_trace(struct rb_global_variable
*var
)
778 struct trace_var
*trace
= var
->trace
;
780 struct trace_var
*next
;
784 while (trace
->next
) {
787 trace
->next
= next
->next
;
798 rb_f_untrace_var(int argc
, const VALUE
*argv
)
802 struct rb_global_entry
*entry
;
803 struct trace_var
*trace
;
805 rb_scan_args(argc
, argv
, "11", &var
, &cmd
);
806 id
= rb_check_id(&var
);
808 rb_name_error_str(var
, "undefined global variable %"PRIsVALUE
"", QUOTE(var
));
810 if ((entry
= rb_find_global_entry(id
)) == NULL
) {
811 rb_name_error(id
, "undefined global variable %"PRIsVALUE
"", QUOTE_ID(id
));
814 trace
= entry
->var
->trace
;
816 VALUE ary
= rb_ary_new();
819 struct trace_var
*next
= trace
->next
;
820 rb_ary_push(ary
, (VALUE
)trace
->data
);
825 if (!entry
->var
->block_trace
) remove_trace(entry
->var
);
830 if (trace
->data
== cmd
) {
832 if (!entry
->var
->block_trace
) remove_trace(entry
->var
);
833 return rb_ary_new3(1, cmd
);
842 struct trace_var
*trace
;
849 struct trace_data
*data
= (void *)v
;
850 struct trace_var
*trace
= data
->trace
;
853 (*trace
->func
)(trace
->data
, data
->val
);
863 struct rb_global_variable
*var
= (void *)v
;
864 var
->block_trace
= 0;
866 return Qnil
; /* not reached */
870 rb_gvar_set_entry(struct rb_global_entry
*entry
, VALUE val
)
872 struct trace_data trace
;
873 struct rb_global_variable
*var
= entry
->var
;
875 (*var
->setter
)(val
, entry
->id
, var
->data
);
877 if (var
->trace
&& !var
->block_trace
) {
878 var
->block_trace
= 1;
879 trace
.trace
= var
->trace
;
881 rb_ensure(trace_ev
, (VALUE
)&trace
, trace_en
, (VALUE
)var
);
887 rb_gvar_set(ID id
, VALUE val
)
889 struct rb_global_entry
*entry
;
890 entry
= rb_global_entry(id
);
892 return rb_gvar_set_entry(entry
, val
);
896 rb_gv_set(const char *name
, VALUE val
)
898 return rb_gvar_set(global_id(name
), val
);
904 struct rb_global_entry
*entry
= rb_global_entry(id
);
905 struct rb_global_variable
*var
= entry
->var
;
906 return (*var
->getter
)(entry
->id
, var
->data
);
910 rb_gv_get(const char *name
)
912 ID id
= find_global_id(name
);
915 rb_warning("global variable '%s' not initialized", name
);
919 return rb_gvar_get(id
);
923 rb_gvar_defined(ID id
)
925 struct rb_global_entry
*entry
= rb_global_entry(id
);
926 return RBOOL(entry
->var
->getter
!= rb_gvar_undef_getter
);
930 rb_gvar_getter_function_of(ID id
)
932 const struct rb_global_entry
*entry
= rb_global_entry(id
);
933 return entry
->var
->getter
;
937 rb_gvar_setter_function_of(ID id
)
939 const struct rb_global_entry
*entry
= rb_global_entry(id
);
940 return entry
->var
->setter
;
943 static enum rb_id_table_iterator_result
944 gvar_i(ID key
, VALUE val
, void *a
)
946 VALUE ary
= (VALUE
)a
;
947 rb_ary_push(ary
, ID2SYM(key
));
948 return ID_TABLE_CONTINUE
;
952 rb_f_global_variables(void)
954 VALUE ary
= rb_ary_new();
955 VALUE sym
, backref
= rb_backref_get();
957 if (!rb_ractor_main_p()) {
958 rb_raise(rb_eRactorIsolationError
, "can not access global variables from non-main Ractors");
961 rb_id_table_foreach(rb_global_tbl
, gvar_i
, (void *)ary
);
962 if (!NIL_P(backref
)) {
964 int i
, nmatch
= rb_match_count(backref
);
966 for (i
= 1; i
<= nmatch
; ++i
) {
967 if (!RTEST(rb_reg_nth_defined(i
, backref
))) continue;
969 /* probably reused, make static ID */
970 buf
[1] = (char)(i
+ '0');
971 sym
= ID2SYM(rb_intern2(buf
, 2));
975 sym
= rb_str_intern(rb_sprintf("$%d", i
));
977 rb_ary_push(ary
, sym
);
984 rb_alias_variable(ID name1
, ID name2
)
986 struct rb_global_entry
*entry1
, *entry2
;
988 struct rb_id_table
*gtbl
= rb_global_tbl
;
990 if (!rb_ractor_main_p()) {
991 rb_raise(rb_eRactorIsolationError
, "can not access global variables from non-main Ractors");
994 entry2
= rb_global_entry(name2
);
995 if (!rb_id_table_lookup(gtbl
, name1
, &data1
)) {
996 entry1
= ALLOC(struct rb_global_entry
);
998 rb_id_table_insert(gtbl
, name1
, (VALUE
)entry1
);
1000 else if ((entry1
= (struct rb_global_entry
*)data1
)->var
!= entry2
->var
) {
1001 struct rb_global_variable
*var
= entry1
->var
;
1002 if (var
->block_trace
) {
1003 rb_raise(rb_eRuntimeError
, "can't alias in tracer");
1006 if (var
->counter
== 0) {
1007 struct trace_var
*trace
= var
->trace
;
1009 struct trace_var
*next
= trace
->next
;
1019 entry2
->var
->counter
++;
1020 entry1
->var
= entry2
->var
;
1024 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(ID id
)
1026 if (UNLIKELY(!rb_ractor_main_p())) {
1027 if (rb_is_instance_id(id
)) { // check only normal ivars
1028 rb_raise(rb_eRactorIsolationError
, "can not set instance variables of classes/modules by non-main Ractors");
1033 #define CVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR() \
1034 if (UNLIKELY(!rb_ractor_main_p())) { \
1035 rb_raise(rb_eRactorIsolationError, "can not access class variables from non-main Ractors"); \
1038 static inline struct st_table
*
1039 generic_ivtbl(VALUE obj
, ID id
, bool force_check_ractor
)
1041 ASSERT_vm_locking();
1043 if ((force_check_ractor
|| LIKELY(rb_is_instance_id(id
)) /* not internal ID */ ) &&
1044 !RB_OBJ_FROZEN_RAW(obj
) &&
1045 UNLIKELY(!rb_ractor_main_p()) &&
1046 UNLIKELY(rb_ractor_shareable_p(obj
))) {
1048 rb_raise(rb_eRactorIsolationError
, "can not access instance variables of shareable objects from non-main Ractors");
1050 return generic_iv_tbl_
;
1053 static inline struct st_table
*
1054 generic_ivtbl_no_ractor_check(VALUE obj
)
1056 return generic_ivtbl(obj
, 0, false);
1060 rb_gen_ivtbl_get(VALUE obj
, ID id
, struct gen_ivtbl
**ivtbl
)
1062 RUBY_ASSERT(!RB_TYPE_P(obj
, T_ICLASS
));
1069 if (st_lookup(generic_ivtbl(obj
, id
, false), (st_data_t
)obj
, &data
)) {
1070 *ivtbl
= (struct gen_ivtbl
*)data
;
1080 rb_ivar_generic_ivtbl_lookup(VALUE obj
, struct gen_ivtbl
**ivtbl
)
1082 return rb_gen_ivtbl_get(obj
, 0, ivtbl
);
1086 gen_ivtbl_bytes(size_t n
)
1088 return offsetof(struct gen_ivtbl
, as
.shape
.ivptr
) + n
* sizeof(VALUE
);
1091 static struct gen_ivtbl
*
1092 gen_ivtbl_resize(struct gen_ivtbl
*old
, uint32_t n
)
1096 uint32_t len
= old
? old
->as
.shape
.numiv
: 0;
1097 struct gen_ivtbl
*ivtbl
= xrealloc(old
, gen_ivtbl_bytes(n
));
1099 ivtbl
->as
.shape
.numiv
= n
;
1100 for (; len
< n
; len
++) {
1101 ivtbl
->as
.shape
.ivptr
[len
] = Qundef
;
1108 rb_mark_generic_ivar(VALUE obj
)
1110 struct gen_ivtbl
*ivtbl
;
1112 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1113 if (rb_shape_obj_too_complex(obj
)) {
1114 rb_mark_tbl_no_pin(ivtbl
->as
.complex.table
);
1117 for (uint32_t i
= 0; i
< ivtbl
->as
.shape
.numiv
; i
++) {
1118 rb_gc_mark_movable(ivtbl
->as
.shape
.ivptr
[i
]);
1125 rb_ref_update_generic_ivar(VALUE obj
)
1127 struct gen_ivtbl
*ivtbl
;
1129 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1130 if (rb_shape_obj_too_complex(obj
)) {
1131 rb_gc_ref_update_table_values_only(ivtbl
->as
.complex.table
);
1134 for (uint32_t i
= 0; i
< ivtbl
->as
.shape
.numiv
; i
++) {
1135 ivtbl
->as
.shape
.ivptr
[i
] = rb_gc_location(ivtbl
->as
.shape
.ivptr
[i
]);
1142 rb_mv_generic_ivar(VALUE rsrc
, VALUE dst
)
1144 st_data_t key
= (st_data_t
)rsrc
;
1147 if (st_delete(generic_ivtbl_no_ractor_check(rsrc
), &key
, &ivtbl
))
1148 st_insert(generic_ivtbl_no_ractor_check(dst
), (st_data_t
)dst
, ivtbl
);
1152 rb_free_generic_ivar(VALUE obj
)
1154 st_data_t key
= (st_data_t
)obj
, value
;
1156 bool too_complex
= rb_shape_obj_too_complex(obj
);
1158 if (st_delete(generic_ivtbl_no_ractor_check(obj
), &key
, &value
)) {
1159 struct gen_ivtbl
*ivtbl
= (struct gen_ivtbl
*)value
;
1161 if (UNLIKELY(too_complex
)) {
1162 st_free_table(ivtbl
->as
.complex.table
);
1170 rb_generic_ivar_memsize(VALUE obj
)
1172 struct gen_ivtbl
*ivtbl
;
1174 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1175 if (rb_shape_obj_too_complex(obj
)) {
1176 return sizeof(struct gen_ivtbl
) + st_memsize(ivtbl
->as
.complex.table
);
1179 return gen_ivtbl_bytes(ivtbl
->as
.shape
.numiv
);
1185 #if !SHAPE_IN_BASIC_FLAGS
1187 rb_generic_shape_id(VALUE obj
)
1189 struct gen_ivtbl
*ivtbl
= 0;
1190 shape_id_t shape_id
= 0;
1194 st_table
* global_iv_table
= generic_ivtbl(obj
, 0, false);
1196 if (global_iv_table
&& st_lookup(global_iv_table
, obj
, (st_data_t
*)&ivtbl
)) {
1197 shape_id
= ivtbl
->shape_id
;
1199 else if (OBJ_FROZEN(obj
)) {
1200 shape_id
= SPECIAL_CONST_SHAPE_ID
;
1210 gen_ivtbl_count(VALUE obj
, const struct gen_ivtbl
*ivtbl
)
1215 if (rb_shape_obj_too_complex(obj
)) {
1216 n
= st_table_size(ivtbl
->as
.complex.table
);
1219 for (i
= 0; i
< ivtbl
->as
.shape
.numiv
; i
++) {
1220 if (!UNDEF_P(ivtbl
->as
.shape
.ivptr
[i
])) {
1230 rb_ivar_lookup(VALUE obj
, ID id
, VALUE undef
)
1232 if (SPECIAL_CONST_P(obj
)) return undef
;
1234 shape_id_t shape_id
;
1238 #if SHAPE_IN_BASIC_FLAGS
1239 shape_id
= RBASIC_SHAPE_ID(obj
);
1242 switch (BUILTIN_TYPE(obj
)) {
1251 #if !SHAPE_IN_BASIC_FLAGS
1252 shape_id
= RCLASS_SHAPE_ID(obj
);
1255 if (rb_shape_obj_too_complex(obj
)) {
1256 st_table
* iv_table
= RCLASS_IV_HASH(obj
);
1257 if (rb_st_lookup(iv_table
, (st_data_t
)id
, (st_data_t
*)&val
)) {
1265 attr_index_t index
= 0;
1266 shape
= rb_shape_get_shape_by_id(shape_id
);
1267 found
= rb_shape_get_iv_index(shape
, id
, &index
);
1270 ivar_list
= RCLASS_IVPTR(obj
);
1271 RUBY_ASSERT(ivar_list
);
1273 val
= ivar_list
[index
];
1283 rb_is_instance_id(id
) &&
1284 UNLIKELY(!rb_ractor_main_p()) &&
1285 !rb_ractor_shareable_p(val
)) {
1286 rb_raise(rb_eRactorIsolationError
,
1287 "can not get unshareable values from instance variables of classes/modules from non-main Ractors");
1293 #if !SHAPE_IN_BASIC_FLAGS
1294 shape_id
= ROBJECT_SHAPE_ID(obj
);
1296 if (rb_shape_obj_too_complex(obj
)) {
1297 st_table
* iv_table
= ROBJECT_IV_HASH(obj
);
1299 if (rb_st_lookup(iv_table
, (st_data_t
)id
, (st_data_t
*)&val
)) {
1307 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1308 ivar_list
= ROBJECT_IVPTR(obj
);
1312 if (FL_TEST_RAW(obj
, FL_EXIVAR
)) {
1313 struct gen_ivtbl
*ivtbl
;
1314 rb_gen_ivtbl_get(obj
, id
, &ivtbl
);
1316 if (rb_shape_obj_too_complex(obj
)) {
1318 if (rb_st_lookup(ivtbl
->as
.complex.table
, (st_data_t
)id
, (st_data_t
*)&val
)) {
1326 #if !SHAPE_IN_BASIC_FLAGS
1327 shape_id
= ivtbl
->shape_id
;
1329 ivar_list
= ivtbl
->as
.shape
.ivptr
;
1337 attr_index_t index
= 0;
1338 shape
= rb_shape_get_shape_by_id(shape_id
);
1339 if (rb_shape_get_iv_index(shape
, id
, &index
)) {
1340 return ivar_list
[index
];
1347 rb_ivar_get(VALUE obj
, ID id
)
1349 VALUE iv
= rb_ivar_lookup(obj
, id
, Qnil
);
1350 RB_DEBUG_COUNTER_INC(ivar_get_base
);
1355 rb_attr_get(VALUE obj
, ID id
)
1357 return rb_ivar_lookup(obj
, id
, Qnil
);
1361 rb_ivar_delete(VALUE obj
, ID id
, VALUE undef
)
1363 rb_check_frozen(obj
);
1366 rb_shape_t
*shape
= rb_shape_get_shape(obj
);
1368 if (BUILTIN_TYPE(obj
) == T_CLASS
|| BUILTIN_TYPE(obj
) == T_MODULE
) {
1369 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(id
);
1372 if (!rb_shape_transition_shape_remove_ivar(obj
, id
, shape
, &val
)) {
1373 if (!rb_shape_obj_too_complex(obj
)) {
1374 rb_evict_ivars_to_hash(obj
);
1377 st_table
*table
= NULL
;
1378 switch (BUILTIN_TYPE(obj
)) {
1381 table
= RCLASS_IV_HASH(obj
);
1385 table
= ROBJECT_IV_HASH(obj
);
1389 struct gen_ivtbl
*ivtbl
;
1390 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1391 table
= ivtbl
->as
.complex.table
;
1398 if (!st_delete(table
, (st_data_t
*)&id
, (st_data_t
*)&val
)) {
1408 rb_attr_delete(VALUE obj
, ID id
)
1410 return rb_ivar_delete(obj
, id
, Qnil
);
1414 rb_obj_convert_to_too_complex(VALUE obj
, st_table
*table
)
1416 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1418 VALUE
*old_ivptr
= NULL
;
1420 switch (BUILTIN_TYPE(obj
)) {
1422 if (!(RBASIC(obj
)->flags
& ROBJECT_EMBED
)) {
1423 old_ivptr
= ROBJECT_IVPTR(obj
);
1425 rb_shape_set_shape_id(obj
, OBJ_TOO_COMPLEX_SHAPE_ID
);
1426 ROBJECT_SET_IV_HASH(obj
, table
);
1430 old_ivptr
= RCLASS_IVPTR(obj
);
1431 rb_shape_set_shape_id(obj
, OBJ_TOO_COMPLEX_SHAPE_ID
);
1432 RCLASS_SET_IV_HASH(obj
, table
);
1437 struct st_table
*gen_ivs
= generic_ivtbl_no_ractor_check(obj
);
1439 struct gen_ivtbl
*old_ivtbl
= NULL
;
1440 st_lookup(gen_ivs
, (st_data_t
)obj
, (st_data_t
*)&old_ivtbl
);
1443 /* We need to modify old_ivtbl to have the too complex shape
1444 * and hold the table because the xmalloc could trigger a GC
1445 * compaction. We want the table to be updated rather than
1446 * the original ivptr. */
1447 #if SHAPE_IN_BASIC_FLAGS
1448 rb_shape_set_shape_id(obj
, OBJ_TOO_COMPLEX_SHAPE_ID
);
1450 old_ivtbl
->shape_id
= OBJ_TOO_COMPLEX_SHAPE_ID
;
1452 old_ivtbl
->as
.complex.table
= table
;
1453 old_ivptr
= (VALUE
*)old_ivtbl
;
1456 struct gen_ivtbl
*ivtbl
= xmalloc(sizeof(struct gen_ivtbl
));
1457 ivtbl
->as
.complex.table
= table
;
1458 st_insert(gen_ivs
, (st_data_t
)obj
, (st_data_t
)ivtbl
);
1459 #if SHAPE_IN_BASIC_FLAGS
1460 rb_shape_set_shape_id(obj
, OBJ_TOO_COMPLEX_SHAPE_ID
);
1462 ivtbl
->shape_id
= OBJ_TOO_COMPLEX_SHAPE_ID
;
1472 rb_evict_ivars_to_hash(VALUE obj
)
1474 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1476 st_table
*table
= st_init_numtable_with_size(rb_ivar_count(obj
));
1478 // Evacuate all previous values from shape into id_table
1479 rb_obj_copy_ivs_to_hash_table(obj
, table
);
1480 rb_obj_convert_to_too_complex(obj
, table
);
1482 RUBY_ASSERT(rb_shape_obj_too_complex(obj
));
1485 struct general_ivar_set_result
{
1490 static struct general_ivar_set_result
1491 general_ivar_set(VALUE obj
, ID id
, VALUE val
, void *data
,
1492 VALUE
*(*shape_ivptr_func
)(VALUE
, void *),
1493 void (*shape_resize_ivptr_func
)(VALUE
, attr_index_t
, attr_index_t
, void *),
1494 void (*set_shape_func
)(VALUE
, rb_shape_t
*, void *),
1495 void (*transition_too_complex_func
)(VALUE
, void *),
1496 st_table
*(*too_complex_table_func
)(VALUE
, void *))
1498 struct general_ivar_set_result result
= {
1503 rb_shape_t
*current_shape
= rb_shape_get_shape(obj
);
1505 if (UNLIKELY(current_shape
->type
== SHAPE_OBJ_TOO_COMPLEX
)) {
1510 if (!rb_shape_get_iv_index(current_shape
, id
, &index
)) {
1511 result
.existing
= false;
1513 index
= current_shape
->next_iv_index
;
1514 if (index
>= MAX_IVARS
) {
1515 rb_raise(rb_eArgError
, "too many instance variables");
1518 rb_shape_t
*next_shape
= rb_shape_get_next(current_shape
, obj
, id
);
1519 if (UNLIKELY(next_shape
->type
== SHAPE_OBJ_TOO_COMPLEX
)) {
1520 transition_too_complex_func(obj
, data
);
1523 else if (UNLIKELY(next_shape
->capacity
!= current_shape
->capacity
)) {
1524 RUBY_ASSERT(next_shape
->capacity
> current_shape
->capacity
);
1525 shape_resize_ivptr_func(obj
, current_shape
->capacity
, next_shape
->capacity
, data
);
1528 RUBY_ASSERT(next_shape
->type
== SHAPE_IVAR
);
1529 RUBY_ASSERT(index
== (next_shape
->next_iv_index
- 1));
1530 set_shape_func(obj
, next_shape
, data
);
1533 VALUE
*table
= shape_ivptr_func(obj
, data
);
1534 RB_OBJ_WRITE(obj
, &table
[index
], val
);
1536 result
.index
= index
;
1541 RUBY_ASSERT(rb_shape_obj_too_complex(obj
));
1543 st_table
*table
= too_complex_table_func(obj
, data
);
1544 result
.existing
= st_insert(table
, (st_data_t
)id
, (st_data_t
)val
);
1546 RB_OBJ_WRITTEN(obj
, Qundef
, val
);
1551 struct gen_ivar_lookup_ensure_size
{
1554 struct gen_ivtbl
*ivtbl
;
1560 generic_ivar_lookup_ensure_size(st_data_t
*k
, st_data_t
*v
, st_data_t u
, int existing
)
1562 ASSERT_vm_locking();
1564 struct gen_ivar_lookup_ensure_size
*ivar_lookup
= (struct gen_ivar_lookup_ensure_size
*)u
;
1565 struct gen_ivtbl
*ivtbl
= existing
? (struct gen_ivtbl
*)*v
: NULL
;
1567 if (!existing
|| ivar_lookup
->resize
) {
1569 RUBY_ASSERT(ivar_lookup
->shape
->type
== SHAPE_IVAR
);
1570 RUBY_ASSERT(rb_shape_get_shape_by_id(ivar_lookup
->shape
->parent_id
)->capacity
< ivar_lookup
->shape
->capacity
);
1573 FL_SET_RAW((VALUE
)*k
, FL_EXIVAR
);
1576 ivtbl
= gen_ivtbl_resize(ivtbl
, ivar_lookup
->shape
->capacity
);
1577 *v
= (st_data_t
)ivtbl
;
1580 RUBY_ASSERT(FL_TEST((VALUE
)*k
, FL_EXIVAR
));
1582 ivar_lookup
->ivtbl
= ivtbl
;
1583 if (ivar_lookup
->shape
) {
1584 #if SHAPE_IN_BASIC_FLAGS
1585 rb_shape_set_shape(ivar_lookup
->obj
, ivar_lookup
->shape
);
1587 ivtbl
->shape_id
= rb_shape_id(ivar_lookup
->shape
);
1595 generic_ivar_set_shape_ivptr(VALUE obj
, void *data
)
1597 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1599 struct gen_ivar_lookup_ensure_size
*ivar_lookup
= data
;
1603 st_update(generic_ivtbl(obj
, ivar_lookup
->id
, false), (st_data_t
)obj
, generic_ivar_lookup_ensure_size
, (st_data_t
)ivar_lookup
);
1607 FL_SET_RAW(obj
, FL_EXIVAR
);
1609 return ivar_lookup
->ivtbl
->as
.shape
.ivptr
;
1613 generic_ivar_set_shape_resize_ivptr(VALUE obj
, attr_index_t _old_capa
, attr_index_t new_capa
, void *data
)
1615 struct gen_ivar_lookup_ensure_size
*ivar_lookup
= data
;
1617 ivar_lookup
->resize
= true;
1621 generic_ivar_set_set_shape(VALUE obj
, rb_shape_t
*shape
, void *data
)
1623 struct gen_ivar_lookup_ensure_size
*ivar_lookup
= data
;
1625 ivar_lookup
->shape
= shape
;
1629 generic_ivar_set_transition_too_complex(VALUE obj
, void *_data
)
1631 rb_evict_ivars_to_hash(obj
);
1632 FL_SET_RAW(obj
, FL_EXIVAR
);
1636 generic_ivar_set_too_complex_table(VALUE obj
, void *data
)
1638 struct gen_ivar_lookup_ensure_size
*ivar_lookup
= data
;
1640 struct gen_ivtbl
*ivtbl
;
1641 if (!rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1642 ivtbl
= xmalloc(sizeof(struct gen_ivtbl
));
1643 #if !SHAPE_IN_BASIC_FLAGS
1644 ivtbl
->shape_id
= SHAPE_OBJ_TOO_COMPLEX
;
1646 ivtbl
->as
.complex.table
= st_init_numtable_with_size(1);
1650 st_insert(generic_ivtbl(obj
, ivar_lookup
->id
, false), (st_data_t
)obj
, (st_data_t
)ivtbl
);
1654 FL_SET_RAW(obj
, FL_EXIVAR
);
1657 RUBY_ASSERT(rb_shape_obj_too_complex(obj
));
1659 return ivtbl
->as
.complex.table
;
1663 generic_ivar_set(VALUE obj
, ID id
, VALUE val
)
1665 struct gen_ivar_lookup_ensure_size ivar_lookup
= {
1672 general_ivar_set(obj
, id
, val
, &ivar_lookup
,
1673 generic_ivar_set_shape_ivptr
,
1674 generic_ivar_set_shape_resize_ivptr
,
1675 generic_ivar_set_set_shape
,
1676 generic_ivar_set_transition_too_complex
,
1677 generic_ivar_set_too_complex_table
);
1681 rb_ensure_iv_list_size(VALUE obj
, uint32_t current_capacity
, uint32_t new_capacity
)
1683 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1685 if (RBASIC(obj
)->flags
& ROBJECT_EMBED
) {
1686 VALUE
*ptr
= ROBJECT_IVPTR(obj
);
1687 VALUE
*newptr
= ALLOC_N(VALUE
, new_capacity
);
1688 MEMCPY(newptr
, ptr
, VALUE
, current_capacity
);
1689 RB_FL_UNSET_RAW(obj
, ROBJECT_EMBED
);
1690 ROBJECT(obj
)->as
.heap
.ivptr
= newptr
;
1693 REALLOC_N(ROBJECT(obj
)->as
.heap
.ivptr
, VALUE
, new_capacity
);
1698 rb_obj_copy_ivs_to_hash_table_i(ID key
, VALUE val
, st_data_t arg
)
1700 RUBY_ASSERT(!st_lookup((st_table
*)arg
, (st_data_t
)key
, NULL
));
1702 st_add_direct((st_table
*)arg
, (st_data_t
)key
, (st_data_t
)val
);
1707 rb_obj_copy_ivs_to_hash_table(VALUE obj
, st_table
*table
)
1709 rb_ivar_foreach(obj
, rb_obj_copy_ivs_to_hash_table_i
, (st_data_t
)table
);
1713 obj_ivar_set_shape_ivptr(VALUE obj
, void *_data
)
1715 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
1717 return ROBJECT_IVPTR(obj
);
1721 obj_ivar_set_shape_resize_ivptr(VALUE obj
, attr_index_t old_capa
, attr_index_t new_capa
, void *_data
)
1723 rb_ensure_iv_list_size(obj
, old_capa
, new_capa
);
1727 obj_ivar_set_set_shape(VALUE obj
, rb_shape_t
*shape
, void *_data
)
1729 rb_shape_set_shape(obj
, shape
);
1733 obj_ivar_set_transition_too_complex(VALUE obj
, void *_data
)
1735 rb_evict_ivars_to_hash(obj
);
1739 obj_ivar_set_too_complex_table(VALUE obj
, void *_data
)
1741 RUBY_ASSERT(rb_shape_obj_too_complex(obj
));
1743 return ROBJECT_IV_HASH(obj
);
1747 rb_obj_ivar_set(VALUE obj
, ID id
, VALUE val
)
1749 return general_ivar_set(obj
, id
, val
, NULL
,
1750 obj_ivar_set_shape_ivptr
,
1751 obj_ivar_set_shape_resize_ivptr
,
1752 obj_ivar_set_set_shape
,
1753 obj_ivar_set_transition_too_complex
,
1754 obj_ivar_set_too_complex_table
).index
;
1757 /* Set the instance variable +val+ on object +obj+ at ivar name +id+.
1758 * This function only works with T_OBJECT objects, so make sure
1759 * +obj+ is of type T_OBJECT before using this function.
1762 rb_vm_set_ivar_id(VALUE obj
, ID id
, VALUE val
)
1764 rb_check_frozen_internal(obj
);
1765 rb_obj_ivar_set(obj
, id
, val
);
1770 rb_shape_set_shape_id(VALUE obj
, shape_id_t shape_id
)
1772 if (rb_shape_get_shape_id(obj
) == shape_id
) {
1776 #if SHAPE_IN_BASIC_FLAGS
1777 RBASIC_SET_SHAPE_ID(obj
, shape_id
);
1779 switch (BUILTIN_TYPE(obj
)) {
1781 ROBJECT_SET_SHAPE_ID(obj
, shape_id
);
1785 RCLASS_SET_SHAPE_ID(obj
, shape_id
);
1788 if (shape_id
!= SPECIAL_CONST_SHAPE_ID
) {
1789 struct gen_ivtbl
*ivtbl
= 0;
1792 st_table
* global_iv_table
= generic_ivtbl(obj
, 0, false);
1794 if (st_lookup(global_iv_table
, obj
, (st_data_t
*)&ivtbl
)) {
1795 ivtbl
->shape_id
= shape_id
;
1798 rb_bug("Expected shape_id entry in global iv table");
1810 * Prevents further modifications to the given object. ::rb_eFrozenError shall
1811 * be raised if modification is attempted.
1813 * @param[out] x Object in question.
1815 void rb_obj_freeze_inline(VALUE x
)
1817 if (RB_FL_ABLE(x
)) {
1818 RB_FL_SET_RAW(x
, RUBY_FL_FREEZE
);
1819 if (TYPE(x
) == T_STRING
) {
1820 RB_FL_UNSET_RAW(x
, FL_USER3
); // STR_CHILLED
1823 rb_shape_t
* next_shape
= rb_shape_transition_shape_frozen(x
);
1825 // If we're transitioning from "not complex" to "too complex"
1826 // then evict ivars. This can happen if we run out of shapes
1827 if (!rb_shape_obj_too_complex(x
) && next_shape
->type
== SHAPE_OBJ_TOO_COMPLEX
) {
1828 rb_evict_ivars_to_hash(x
);
1830 rb_shape_set_shape(x
, next_shape
);
1832 if (RBASIC_CLASS(x
)) {
1833 rb_freeze_singleton_class(x
);
1839 ivar_set(VALUE obj
, ID id
, VALUE val
)
1841 RB_DEBUG_COUNTER_INC(ivar_set_base
);
1843 switch (BUILTIN_TYPE(obj
)) {
1846 rb_obj_ivar_set(obj
, id
, val
);
1851 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(id
);
1852 rb_class_ivar_set(obj
, id
, val
);
1856 generic_ivar_set(obj
, id
, val
);
1862 rb_ivar_set(VALUE obj
, ID id
, VALUE val
)
1864 rb_check_frozen(obj
);
1865 ivar_set(obj
, id
, val
);
1870 rb_ivar_set_internal(VALUE obj
, ID id
, VALUE val
)
1872 // should be internal instance variable name (no @ prefix)
1873 VM_ASSERT(!rb_is_instance_id(id
));
1875 ivar_set(obj
, id
, val
);
1879 rb_ivar_defined(VALUE obj
, ID id
)
1883 if (SPECIAL_CONST_P(obj
)) return Qfalse
;
1884 if (rb_shape_obj_too_complex(obj
)) {
1886 st_table
*table
= NULL
;
1887 switch (BUILTIN_TYPE(obj
)) {
1890 table
= (st_table
*)RCLASS_IVPTR(obj
);
1894 table
= ROBJECT_IV_HASH(obj
);
1898 struct gen_ivtbl
*ivtbl
;
1899 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
1900 table
= ivtbl
->as
.complex.table
;
1906 if (!table
|| !rb_st_lookup(table
, id
, &idx
)) {
1913 return RBOOL(rb_shape_get_iv_index(rb_shape_get_shape(obj
), id
, &index
));
1917 typedef int rb_ivar_foreach_callback_func(ID key
, VALUE val
, st_data_t arg
);
1918 st_data_t
rb_st_nth_key(st_table
*tab
, st_index_t index
);
1920 struct iv_itr_data
{
1922 struct gen_ivtbl
* ivtbl
;
1924 rb_ivar_foreach_callback_func
*func
;
1928 * Returns a flag to stop iterating depending on the result of +callback+.
1931 iterate_over_shapes_with_callback(rb_shape_t
*shape
, rb_ivar_foreach_callback_func
*callback
, struct iv_itr_data
* itr_data
)
1933 switch ((enum shape_type
)shape
->type
) {
1935 case SHAPE_T_OBJECT
:
1939 if (iterate_over_shapes_with_callback(rb_shape_get_parent(shape
), callback
, itr_data
))
1942 switch (BUILTIN_TYPE(itr_data
->obj
)) {
1944 RUBY_ASSERT(!rb_shape_obj_too_complex(itr_data
->obj
));
1945 iv_list
= ROBJECT_IVPTR(itr_data
->obj
);
1949 iv_list
= RCLASS_IVPTR(itr_data
->obj
);
1952 iv_list
= itr_data
->ivtbl
->as
.shape
.ivptr
;
1955 VALUE val
= iv_list
[shape
->next_iv_index
- 1];
1956 if (!UNDEF_P(val
)) {
1957 switch (callback(shape
->edge_name
, val
, itr_data
->arg
)) {
1964 rb_bug("unreachable");
1969 return iterate_over_shapes_with_callback(rb_shape_get_parent(shape
), callback
, itr_data
);
1970 case SHAPE_OBJ_TOO_COMPLEX
:
1972 rb_bug("Unreachable");
1977 each_hash_iv(st_data_t id
, st_data_t val
, st_data_t data
)
1979 struct iv_itr_data
* itr_data
= (struct iv_itr_data
*)data
;
1980 rb_ivar_foreach_callback_func
*callback
= itr_data
->func
;
1981 return callback((ID
)id
, (VALUE
)val
, itr_data
->arg
);
1985 obj_ivar_each(VALUE obj
, rb_ivar_foreach_callback_func
*func
, st_data_t arg
)
1987 rb_shape_t
* shape
= rb_shape_get_shape(obj
);
1988 struct iv_itr_data itr_data
;
1991 itr_data
.func
= func
;
1992 if (rb_shape_obj_too_complex(obj
)) {
1993 rb_st_foreach(ROBJECT_IV_HASH(obj
), each_hash_iv
, (st_data_t
)&itr_data
);
1996 iterate_over_shapes_with_callback(shape
, func
, &itr_data
);
2001 gen_ivar_each(VALUE obj
, rb_ivar_foreach_callback_func
*func
, st_data_t arg
)
2003 rb_shape_t
*shape
= rb_shape_get_shape(obj
);
2004 struct gen_ivtbl
*ivtbl
;
2005 if (!rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) return;
2007 struct iv_itr_data itr_data
;
2009 itr_data
.ivtbl
= ivtbl
;
2011 itr_data
.func
= func
;
2012 if (rb_shape_obj_too_complex(obj
)) {
2013 rb_st_foreach(ivtbl
->as
.complex.table
, each_hash_iv
, (st_data_t
)&itr_data
);
2016 iterate_over_shapes_with_callback(shape
, func
, &itr_data
);
2021 class_ivar_each(VALUE obj
, rb_ivar_foreach_callback_func
*func
, st_data_t arg
)
2023 RUBY_ASSERT(RB_TYPE_P(obj
, T_CLASS
) || RB_TYPE_P(obj
, T_MODULE
));
2025 rb_shape_t
* shape
= rb_shape_get_shape(obj
);
2026 struct iv_itr_data itr_data
;
2029 itr_data
.func
= func
;
2030 if (rb_shape_obj_too_complex(obj
)) {
2031 rb_st_foreach(RCLASS_IV_HASH(obj
), each_hash_iv
, (st_data_t
)&itr_data
);
2034 iterate_over_shapes_with_callback(shape
, func
, &itr_data
);
2039 rb_copy_generic_ivar(VALUE clone
, VALUE obj
)
2041 struct gen_ivtbl
*obj_ivtbl
;
2042 struct gen_ivtbl
*new_ivtbl
;
2044 rb_check_frozen(clone
);
2046 if (!FL_TEST(obj
, FL_EXIVAR
)) {
2050 if (rb_gen_ivtbl_get(obj
, 0, &obj_ivtbl
)) {
2051 if (gen_ivtbl_count(obj
, obj_ivtbl
) == 0)
2054 FL_SET(clone
, FL_EXIVAR
);
2056 if (rb_shape_obj_too_complex(obj
)) {
2057 new_ivtbl
= xmalloc(sizeof(struct gen_ivtbl
));
2058 #if !SHAPE_IN_BASIC_FLAGS
2059 new_ivtbl
->shape_id
= SHAPE_OBJ_TOO_COMPLEX
;
2061 new_ivtbl
->as
.complex.table
= st_copy(obj_ivtbl
->as
.complex.table
);
2064 new_ivtbl
= gen_ivtbl_resize(0, obj_ivtbl
->as
.shape
.numiv
);
2066 for (uint32_t i
=0; i
<obj_ivtbl
->as
.shape
.numiv
; i
++) {
2067 RB_OBJ_WRITE(clone
, &new_ivtbl
->as
.shape
.ivptr
[i
], obj_ivtbl
->as
.shape
.ivptr
[i
]);
2072 * c.ivtbl may change in gen_ivar_copy due to realloc,
2077 generic_ivtbl_no_ractor_check(clone
);
2078 st_insert(generic_ivtbl_no_ractor_check(obj
), (st_data_t
)clone
, (st_data_t
)new_ivtbl
);
2082 rb_shape_t
* obj_shape
= rb_shape_get_shape(obj
);
2083 if (rb_shape_frozen_shape_p(obj_shape
)) {
2084 rb_shape_set_shape_id(clone
, obj_shape
->parent_id
);
2087 rb_shape_set_shape(clone
, obj_shape
);
2093 if (FL_TEST(clone
, FL_EXIVAR
)) {
2094 rb_free_generic_ivar(clone
);
2095 FL_UNSET(clone
, FL_EXIVAR
);
2100 rb_replace_generic_ivar(VALUE clone
, VALUE obj
)
2102 RUBY_ASSERT(FL_TEST(obj
, FL_EXIVAR
));
2106 st_data_t ivtbl
, obj_data
= (st_data_t
)obj
;
2107 if (st_lookup(generic_iv_tbl_
, (st_data_t
)obj
, &ivtbl
)) {
2108 st_insert(generic_iv_tbl_
, (st_data_t
)clone
, ivtbl
);
2109 st_delete(generic_iv_tbl_
, &obj_data
, NULL
);
2112 rb_bug("unreachable");
2117 FL_SET(clone
, FL_EXIVAR
);
2121 rb_ivar_foreach(VALUE obj
, rb_ivar_foreach_callback_func
*func
, st_data_t arg
)
2123 if (SPECIAL_CONST_P(obj
)) return;
2124 switch (BUILTIN_TYPE(obj
)) {
2126 obj_ivar_each(obj
, func
, arg
);
2130 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(0);
2133 class_ivar_each(obj
, func
, arg
);
2138 if (FL_TEST(obj
, FL_EXIVAR
)) {
2139 gen_ivar_each(obj
, func
, arg
);
2146 rb_ivar_count(VALUE obj
)
2148 if (SPECIAL_CONST_P(obj
)) return 0;
2150 switch (BUILTIN_TYPE(obj
)) {
2152 return ROBJECT_IV_COUNT(obj
);
2155 return RCLASS_IV_COUNT(obj
);
2157 if (FL_TEST(obj
, FL_EXIVAR
)) {
2158 struct gen_ivtbl
*ivtbl
;
2160 if (rb_gen_ivtbl_get(obj
, 0, &ivtbl
)) {
2161 return gen_ivtbl_count(obj
, ivtbl
);
2170 ivar_i(ID key
, VALUE v
, st_data_t a
)
2172 VALUE ary
= (VALUE
)a
;
2174 if (rb_is_instance_id(key
)) {
2175 rb_ary_push(ary
, ID2SYM(key
));
2182 * obj.instance_variables -> array
2184 * Returns an array of instance variable names for the receiver. Note
2185 * that simply defining an accessor does not create the corresponding
2186 * instance variable.
2194 * Fred.new.instance_variables #=> [:@iv]
2198 rb_obj_instance_variables(VALUE obj
)
2203 rb_ivar_foreach(obj
, ivar_i
, ary
);
2207 #define rb_is_constant_id rb_is_const_id
2208 #define rb_is_constant_name rb_is_const_name
2209 #define id_for_var(obj, name, part, type) \
2210 id_for_var_message(obj, name, type, "'%1$s' is not allowed as "#part" "#type" variable name")
2211 #define id_for_var_message(obj, name, type, message) \
2212 check_id_type(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
2214 check_id_type(VALUE obj
, VALUE
*pname
,
2215 int (*valid_id_p
)(ID
), int (*valid_name_p
)(VALUE
),
2216 const char *message
, size_t message_len
)
2218 ID id
= rb_check_id(pname
);
2219 VALUE name
= *pname
;
2221 if (id
? !valid_id_p(id
) : !valid_name_p(name
)) {
2222 rb_name_err_raise_str(rb_fstring_new(message
, message_len
),
2230 * obj.remove_instance_variable(symbol) -> obj
2231 * obj.remove_instance_variable(string) -> obj
2233 * Removes the named instance variable from <i>obj</i>, returning that
2234 * variable's value. The name can be passed as a symbol or as a string.
2242 * remove_instance_variable(:@var)
2252 rb_obj_remove_instance_variable(VALUE obj
, VALUE name
)
2254 const ID id
= id_for_var(obj
, name
, an
, instance
);
2256 // Frozen check comes here because it's expected that we raise a
2257 // NameError (from the id_for_var check) before we raise a FrozenError
2258 rb_check_frozen(obj
);
2261 VALUE val
= rb_ivar_delete(obj
, id
, Qundef
);
2263 if (!UNDEF_P(val
)) return val
;
2266 rb_name_err_raise("instance variable %1$s not defined",
2268 UNREACHABLE_RETURN(Qnil
);
2271 NORETURN(static void uninitialized_constant(VALUE
, VALUE
));
2273 uninitialized_constant(VALUE klass
, VALUE name
)
2275 if (klass
&& rb_class_real(klass
) != rb_cObject
)
2276 rb_name_err_raise("uninitialized constant %2$s::%1$s",
2279 rb_name_err_raise("uninitialized constant %1$s",
2284 rb_const_missing(VALUE klass
, VALUE name
)
2286 VALUE value
= rb_funcallv(klass
, idConst_missing
, 1, &name
);
2287 rb_vm_inc_const_missing_count();
2294 * mod.const_missing(sym) -> obj
2296 * Invoked when a reference is made to an undefined constant in
2297 * <i>mod</i>. It is passed a symbol for the undefined constant, and
2298 * returns a value to be used for that constant. For example, consider:
2300 * def Foo.const_missing(name)
2301 * name # return the constant name as Symbol
2304 * Foo::UNDEFINED_CONST #=> :UNDEFINED_CONST: symbol returned
2306 * As the example above shows, +const_missing+ is not required to create the
2307 * missing constant in <i>mod</i>, though that is often a side-effect. The
2308 * caller gets its return value when triggered. If the constant is also defined,
2309 * further lookups won't hit +const_missing+ and will return the value stored in
2310 * the constant as usual. Otherwise, +const_missing+ will be invoked again.
2312 * In the next example, when a reference is made to an undefined constant,
2313 * +const_missing+ attempts to load a file whose path is the lowercase version
2314 * of the constant name (thus class <code>Fred</code> is assumed to be in file
2315 * <code>fred.rb</code>). If defined as a side-effect of loading the file, the
2316 * method returns the value stored in the constant. This implements an autoload
2317 * feature similar to Kernel#autoload and Module#autoload, though it differs in
2320 * def Object.const_missing(name)
2321 * @looked_for ||= {}
2322 * str_name = name.to_s
2323 * raise "Constant not found: #{name}" if @looked_for[str_name]
2324 * @looked_for[str_name] = 1
2325 * file = str_name.downcase
2327 * const_get(name, false)
2333 rb_mod_const_missing(VALUE klass
, VALUE name
)
2335 rb_execution_context_t
*ec
= GET_EC();
2336 VALUE ref
= ec
->private_const_reference
;
2337 rb_vm_pop_cfunc_frame();
2339 ec
->private_const_reference
= 0;
2340 rb_name_err_raise("private constant %2$s::%1$s referenced", ref
, name
);
2342 uninitialized_constant(klass
, name
);
2344 UNREACHABLE_RETURN(Qnil
);
2348 autoload_table_mark(void *ptr
)
2350 rb_mark_tbl_no_pin((st_table
*)ptr
);
2354 autoload_table_free(void *ptr
)
2356 st_free_table((st_table
*)ptr
);
2360 autoload_table_memsize(const void *ptr
)
2362 const st_table
*tbl
= ptr
;
2363 return st_memsize(tbl
);
2367 autoload_table_compact(void *ptr
)
2369 rb_gc_update_tbl_refs((st_table
*)ptr
);
2372 static const rb_data_type_t autoload_table_type
= {
2374 {autoload_table_mark
, autoload_table_free
, autoload_table_memsize
, autoload_table_compact
,},
2375 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
| RUBY_TYPED_WB_PROTECTED
2378 #define check_autoload_table(av) \
2379 (struct st_table *)rb_check_typeddata((av), &autoload_table_type)
2382 autoload_data(VALUE mod
, ID id
)
2384 struct st_table
*tbl
;
2387 // If we are called with a non-origin ICLASS, fetch the autoload data from
2388 // the original module.
2389 if (RB_TYPE_P(mod
, T_ICLASS
)) {
2390 if (FL_TEST_RAW(mod
, RICLASS_IS_ORIGIN
)) {
2394 mod
= RBASIC(mod
)->klass
;
2398 RUBY_ASSERT(RB_TYPE_P(mod
, T_CLASS
) || RB_TYPE_P(mod
, T_MODULE
));
2400 // Look up the instance variable table for `autoload`, then index into that table with the given constant name `id`.
2402 VALUE tbl_value
= rb_ivar_lookup(mod
, autoload
, Qfalse
);
2403 if (!RTEST(tbl_value
) || !(tbl
= check_autoload_table(tbl_value
)) || !st_lookup(tbl
, (st_data_t
)id
, &val
)) {
2410 // Every autoload constant has exactly one instance of autoload_const, stored in `autoload_features`. Since multiple autoload constants can refer to the same file, every `autoload_const` refers to a de-duplicated `autoload_data`.
2411 struct autoload_const
{
2412 // The linked list node of all constants which are loaded by the related autoload feature.
2413 struct ccan_list_node cnode
; /* <=> autoload_data.constants */
2415 // The shared "autoload_data" if multiple constants are defined from the same feature.
2416 VALUE autoload_data_value
;
2418 // The module we are loading a constant into.
2421 // The name of the constant we are loading.
2424 // The value of the constant (after it's loaded).
2427 // The constant entry flags which need to be re-applied after autoloading the feature.
2428 rb_const_flag_t flag
;
2430 // The source file and line number that defined this constant (different from feature path).
2435 // Each `autoload_data` uniquely represents a specific feature which can be loaded, and a list of constants which it is able to define. We use a mutex to coordinate multiple threads trying to load the same feature.
2436 struct autoload_data
{
2437 // The feature path to require to load this constant.
2440 // The mutex which is protecting autoloading this feature.
2443 // The process fork serial number since the autoload mutex will become invalid on fork.
2444 rb_serial_t fork_gen
;
2446 // The linked list of all constants that are going to be loaded by this autoload.
2447 struct ccan_list_head constants
; /* <=> autoload_const.cnode */
2451 autoload_data_compact(void *ptr
)
2453 struct autoload_data
*p
= ptr
;
2455 p
->feature
= rb_gc_location(p
->feature
);
2456 p
->mutex
= rb_gc_location(p
->mutex
);
2460 autoload_data_mark(void *ptr
)
2462 struct autoload_data
*p
= ptr
;
2464 rb_gc_mark_movable(p
->feature
);
2465 rb_gc_mark_movable(p
->mutex
);
2469 autoload_data_free(void *ptr
)
2471 struct autoload_data
*p
= ptr
;
2473 struct autoload_const
*autoload_const
, *next
;
2474 ccan_list_for_each_safe(&p
->constants
, autoload_const
, next
, cnode
) {
2475 ccan_list_del_init(&autoload_const
->cnode
);
2482 autoload_data_memsize(const void *ptr
)
2484 return sizeof(struct autoload_data
);
2487 static const rb_data_type_t autoload_data_type
= {
2489 {autoload_data_mark
, autoload_data_free
, autoload_data_memsize
, autoload_data_compact
},
2490 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
| RUBY_TYPED_WB_PROTECTED
2494 autoload_const_compact(void *ptr
)
2496 struct autoload_const
*ac
= ptr
;
2498 ac
->module
= rb_gc_location(ac
->module
);
2499 ac
->autoload_data_value
= rb_gc_location(ac
->autoload_data_value
);
2500 ac
->value
= rb_gc_location(ac
->value
);
2501 ac
->file
= rb_gc_location(ac
->file
);
2505 autoload_const_mark(void *ptr
)
2507 struct autoload_const
*ac
= ptr
;
2509 rb_gc_mark_movable(ac
->module
);
2510 rb_gc_mark_movable(ac
->autoload_data_value
);
2511 rb_gc_mark_movable(ac
->value
);
2512 rb_gc_mark_movable(ac
->file
);
2516 autoload_const_memsize(const void *ptr
)
2518 return sizeof(struct autoload_const
);
2522 autoload_const_free(void *ptr
)
2524 struct autoload_const
*autoload_const
= ptr
;
2526 ccan_list_del(&autoload_const
->cnode
);
2530 static const rb_data_type_t autoload_const_type
= {
2532 {autoload_const_mark
, autoload_const_free
, autoload_const_memsize
, autoload_const_compact
,},
2533 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
2536 static struct autoload_data
*
2537 get_autoload_data(VALUE autoload_const_value
, struct autoload_const
**autoload_const_pointer
)
2539 struct autoload_const
*autoload_const
= rb_check_typeddata(autoload_const_value
, &autoload_const_type
);
2541 VALUE autoload_data_value
= autoload_const
->autoload_data_value
;
2542 struct autoload_data
*autoload_data
= rb_check_typeddata(autoload_data_value
, &autoload_data_type
);
2544 /* do not reach across stack for ->state after forking: */
2545 if (autoload_data
&& autoload_data
->fork_gen
!= GET_VM()->fork_gen
) {
2546 RB_OBJ_WRITE(autoload_data_value
, &autoload_data
->mutex
, Qnil
);
2547 autoload_data
->fork_gen
= 0;
2550 if (autoload_const_pointer
) *autoload_const_pointer
= autoload_const
;
2552 return autoload_data
;
2556 rb_autoload(VALUE module
, ID name
, const char *feature
)
2558 if (!feature
|| !*feature
) {
2559 rb_raise(rb_eArgError
, "empty feature name");
2562 rb_autoload_str(module
, name
, rb_fstring_cstr(feature
));
2565 static void const_set(VALUE klass
, ID id
, VALUE val
);
2566 static void const_added(VALUE klass
, ID const_name
);
2568 struct autoload_arguments
{
2575 autoload_feature_lookup_or_create(VALUE feature
, struct autoload_data
**autoload_data_pointer
)
2577 RUBY_ASSERT_MUTEX_OWNED(autoload_mutex
);
2578 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2580 VALUE autoload_data_value
= rb_hash_aref(autoload_features
, feature
);
2581 struct autoload_data
*autoload_data
;
2583 if (NIL_P(autoload_data_value
)) {
2584 autoload_data_value
= TypedData_Make_Struct(0, struct autoload_data
, &autoload_data_type
, autoload_data
);
2585 RB_OBJ_WRITE(autoload_data_value
, &autoload_data
->feature
, feature
);
2586 RB_OBJ_WRITE(autoload_data_value
, &autoload_data
->mutex
, Qnil
);
2587 ccan_list_head_init(&autoload_data
->constants
);
2589 if (autoload_data_pointer
) *autoload_data_pointer
= autoload_data
;
2591 rb_hash_aset(autoload_features
, feature
, autoload_data_value
);
2593 else if (autoload_data_pointer
) {
2594 *autoload_data_pointer
= rb_check_typeddata(autoload_data_value
, &autoload_data_type
);
2597 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2598 return autoload_data_value
;
2602 autoload_table_lookup_or_create(VALUE module
)
2604 VALUE autoload_table_value
= rb_ivar_lookup(module
, autoload
, Qfalse
);
2605 if (RTEST(autoload_table_value
)) {
2606 return autoload_table_value
;
2609 autoload_table_value
= TypedData_Wrap_Struct(0, &autoload_table_type
, NULL
);
2610 rb_class_ivar_set(module
, autoload
, autoload_table_value
);
2611 RTYPEDDATA_DATA(autoload_table_value
) = st_init_numtable();
2612 return autoload_table_value
;
2617 autoload_synchronized(VALUE _arguments
)
2619 struct autoload_arguments
*arguments
= (struct autoload_arguments
*)_arguments
;
2621 rb_const_entry_t
*constant_entry
= rb_const_lookup(arguments
->module
, arguments
->name
);
2622 if (constant_entry
&& !UNDEF_P(constant_entry
->value
)) {
2626 // Reset any state associated with any previous constant:
2627 const_set(arguments
->module
, arguments
->name
, Qundef
);
2629 VALUE autoload_table_value
= autoload_table_lookup_or_create(arguments
->module
);
2630 struct st_table
*autoload_table
= check_autoload_table(autoload_table_value
);
2632 // Ensure the string is uniqued since we use an identity lookup:
2633 VALUE feature
= rb_fstring(arguments
->feature
);
2635 struct autoload_data
*autoload_data
;
2636 VALUE autoload_data_value
= autoload_feature_lookup_or_create(feature
, &autoload_data
);
2639 struct autoload_const
*autoload_const
;
2640 VALUE autoload_const_value
= TypedData_Make_Struct(0, struct autoload_const
, &autoload_const_type
, autoload_const
);
2641 autoload_const
->module
= arguments
->module
;
2642 autoload_const
->name
= arguments
->name
;
2643 autoload_const
->value
= Qundef
;
2644 autoload_const
->flag
= CONST_PUBLIC
;
2645 autoload_const
->autoload_data_value
= autoload_data_value
;
2646 ccan_list_add_tail(&autoload_data
->constants
, &autoload_const
->cnode
);
2647 st_insert(autoload_table
, (st_data_t
)arguments
->name
, (st_data_t
)autoload_const_value
);
2648 RB_OBJ_WRITTEN(autoload_table_value
, Qundef
, autoload_const_value
);
2655 rb_autoload_str(VALUE module
, ID name
, VALUE feature
)
2657 if (!rb_is_const_id(name
)) {
2658 rb_raise(rb_eNameError
, "autoload must be constant name: %"PRIsVALUE
"", QUOTE_ID(name
));
2661 Check_Type(feature
, T_STRING
);
2662 if (!RSTRING_LEN(feature
)) {
2663 rb_raise(rb_eArgError
, "empty feature name");
2666 struct autoload_arguments arguments
= {
2672 VALUE result
= rb_mutex_synchronize(autoload_mutex
, autoload_synchronized
, (VALUE
)&arguments
);
2674 if (result
== Qtrue
) {
2675 const_added(module
, name
);
2680 autoload_delete(VALUE module
, ID name
)
2682 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2684 st_data_t load
= 0, key
= name
;
2686 RUBY_ASSERT(RB_TYPE_P(module
, T_CLASS
) || RB_TYPE_P(module
, T_MODULE
));
2688 VALUE table_value
= rb_ivar_lookup(module
, autoload
, Qfalse
);
2689 if (RTEST(table_value
)) {
2690 struct st_table
*table
= check_autoload_table(table_value
);
2692 st_delete(table
, &key
, &load
);
2693 RB_OBJ_WRITTEN(table_value
, load
, Qundef
);
2695 /* Qfalse can indicate already deleted */
2696 if (load
!= Qfalse
) {
2697 struct autoload_const
*autoload_const
;
2698 struct autoload_data
*autoload_data
= get_autoload_data((VALUE
)load
, &autoload_const
);
2700 VM_ASSERT(autoload_data
);
2701 VM_ASSERT(!ccan_list_empty(&autoload_data
->constants
));
2704 * we must delete here to avoid "already initialized" warnings
2705 * with parallel autoload. Using list_del_init here so list_del
2706 * works in autoload_const_free
2708 ccan_list_del_init(&autoload_const
->cnode
);
2710 if (ccan_list_empty(&autoload_data
->constants
)) {
2711 rb_hash_delete(autoload_features
, autoload_data
->feature
);
2714 // If the autoload table is empty, we can delete it.
2715 if (table
->num_entries
== 0) {
2716 rb_attr_delete(module
, autoload
);
2721 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2725 autoload_by_someone_else(struct autoload_data
*ele
)
2727 return ele
->mutex
!= Qnil
&& !rb_mutex_owned_p(ele
->mutex
);
2731 check_autoload_required(VALUE mod
, ID id
, const char **loadingpath
)
2733 VALUE autoload_const_value
= autoload_data(mod
, id
);
2734 struct autoload_data
*autoload_data
;
2735 const char *loading
;
2737 if (!autoload_const_value
|| !(autoload_data
= get_autoload_data(autoload_const_value
, 0))) {
2741 VALUE feature
= autoload_data
->feature
;
2744 * if somebody else is autoloading, we MUST wait for them, since
2745 * rb_provide_feature can provide a feature before autoload_const_set
2746 * completes. We must wait until autoload_const_set finishes in
2749 if (autoload_by_someone_else(autoload_data
)) {
2750 return autoload_const_value
;
2753 loading
= RSTRING_PTR(feature
);
2755 if (!rb_feature_provided(loading
, &loading
)) {
2756 return autoload_const_value
;
2759 if (loadingpath
&& loading
) {
2760 *loadingpath
= loading
;
2761 return autoload_const_value
;
2767 static struct autoload_const
*autoloading_const_entry(VALUE mod
, ID id
);
2770 rb_autoloading_value(VALUE mod
, ID id
, VALUE
* value
, rb_const_flag_t
*flag
)
2772 struct autoload_const
*ac
= autoloading_const_entry(mod
, id
);
2773 if (!ac
) return FALSE
;
2787 autoload_by_current(struct autoload_data
*ele
)
2789 return ele
->mutex
!= Qnil
&& rb_mutex_owned_p(ele
->mutex
);
2792 // If there is an autoloading constant and it has been set by the current
2793 // execution context, return it. This allows threads which are loading code to
2794 // refer to their own autoloaded constants.
2795 struct autoload_const
*
2796 autoloading_const_entry(VALUE mod
, ID id
)
2798 VALUE load
= autoload_data(mod
, id
);
2799 struct autoload_data
*ele
;
2800 struct autoload_const
*ac
;
2802 // Find the autoloading state:
2803 if (!load
|| !(ele
= get_autoload_data(load
, &ac
))) {
2804 // Couldn't be found:
2808 // Check if it's being loaded by the current thread/fiber:
2809 if (autoload_by_current(ele
)) {
2810 if (!UNDEF_P(ac
->value
)) {
2819 autoload_defined_p(VALUE mod
, ID id
)
2821 rb_const_entry_t
*ce
= rb_const_lookup(mod
, id
);
2823 // If there is no constant or the constant is not undefined (special marker for autoloading):
2824 if (!ce
|| !UNDEF_P(ce
->value
)) {
2825 // We are not autoloading:
2829 // Otherwise check if there is an autoload in flight right now:
2830 return !rb_autoloading_value(mod
, id
, NULL
, NULL
);
2833 static void const_tbl_update(struct autoload_const
*, int);
2835 struct autoload_load_arguments
{
2842 // The specific constant which triggered the autoload code to fire:
2843 struct autoload_const
*autoload_const
;
2845 // The parent autoload data which is shared between multiple constants:
2846 struct autoload_data
*autoload_data
;
2850 autoload_const_set(struct autoload_const
*ac
)
2852 check_before_mod_set(ac
->module
, ac
->name
, ac
->value
, "constant");
2856 const_tbl_update(ac
, true);
2860 return 0; /* ignored */
2864 autoload_load_needed(VALUE _arguments
)
2866 struct autoload_load_arguments
*arguments
= (struct autoload_load_arguments
*)_arguments
;
2868 const char *loading
= 0, *src
;
2870 if (!autoload_defined_p(arguments
->module
, arguments
->name
)) {
2874 VALUE autoload_const_value
= check_autoload_required(arguments
->module
, arguments
->name
, &loading
);
2875 if (!autoload_const_value
) {
2879 src
= rb_sourcefile();
2880 if (src
&& loading
&& strcmp(src
, loading
) == 0) {
2884 struct autoload_const
*autoload_const
;
2885 struct autoload_data
*autoload_data
;
2886 if (!(autoload_data
= get_autoload_data(autoload_const_value
, &autoload_const
))) {
2890 if (NIL_P(autoload_data
->mutex
)) {
2891 RB_OBJ_WRITE(autoload_const
->autoload_data_value
, &autoload_data
->mutex
, rb_mutex_new());
2892 autoload_data
->fork_gen
= GET_VM()->fork_gen
;
2894 else if (rb_mutex_owned_p(autoload_data
->mutex
)) {
2898 arguments
->mutex
= autoload_data
->mutex
;
2899 arguments
->autoload_const
= autoload_const
;
2901 return autoload_const_value
;
2905 autoload_apply_constants(VALUE _arguments
)
2907 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2909 struct autoload_load_arguments
*arguments
= (struct autoload_load_arguments
*)_arguments
;
2911 struct autoload_const
*autoload_const
= 0; // for ccan_container_off_var()
2912 struct autoload_const
*next
;
2914 // We use safe iteration here because `autoload_const_set` will eventually invoke
2915 // `autoload_delete` which will remove the constant from the linked list. In theory, once
2916 // the `autoload_data->constants` linked list is empty, we can remove it.
2918 // Iterate over all constants and assign them:
2919 ccan_list_for_each_safe(&arguments
->autoload_data
->constants
, autoload_const
, next
, cnode
) {
2920 if (!UNDEF_P(autoload_const
->value
)) {
2921 autoload_const_set(autoload_const
);
2925 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2931 autoload_feature_require(VALUE _arguments
)
2933 struct autoload_load_arguments
*arguments
= (struct autoload_load_arguments
*)_arguments
;
2935 struct autoload_const
*autoload_const
= arguments
->autoload_const
;
2937 // We save this for later use in autoload_apply_constants:
2938 arguments
->autoload_data
= rb_check_typeddata(autoload_const
->autoload_data_value
, &autoload_data_type
);
2940 VALUE result
= rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments
->autoload_data
->feature
);
2942 if (RTEST(result
)) {
2943 return rb_mutex_synchronize(autoload_mutex
, autoload_apply_constants
, _arguments
);
2950 autoload_try_load(VALUE _arguments
)
2952 struct autoload_load_arguments
*arguments
= (struct autoload_load_arguments
*)_arguments
;
2954 VALUE result
= autoload_feature_require(_arguments
);
2956 // After we loaded the feature, if the constant is not defined, we remove it completely:
2957 rb_const_entry_t
*ce
= rb_const_lookup(arguments
->module
, arguments
->name
);
2959 if (!ce
|| UNDEF_P(ce
->value
)) {
2962 rb_const_remove(arguments
->module
, arguments
->name
);
2964 if (arguments
->module
== rb_cObject
) {
2966 "Expected %"PRIsVALUE
" to define %"PRIsVALUE
" but it didn't",
2967 arguments
->autoload_data
->feature
,
2968 ID2SYM(arguments
->name
)
2973 "Expected %"PRIsVALUE
" to define %"PRIsVALUE
"::%"PRIsVALUE
" but it didn't",
2974 arguments
->autoload_data
->feature
,
2976 ID2SYM(arguments
->name
)
2981 // Otherwise, it was loaded, copy the flags from the autoload constant:
2982 ce
->flag
|= arguments
->flag
;
2989 rb_autoload_load(VALUE module
, ID name
)
2991 rb_const_entry_t
*ce
= rb_const_lookup(module
, name
);
2993 // We bail out as early as possible without any synchronisation:
2994 if (!ce
|| !UNDEF_P(ce
->value
)) {
2998 // At this point, we assume there might be autoloading, so fail if it's ractor:
2999 if (UNLIKELY(!rb_ractor_main_p())) {
3000 rb_raise(rb_eRactorUnsafeError
, "require by autoload on non-main Ractor is not supported (%s)", rb_id2name(name
));
3003 // This state is stored on the stack and is used during the autoload process.
3004 struct autoload_load_arguments arguments
= {.module
= module
, .name
= name
, .mutex
= Qnil
};
3006 // Figure out whether we can autoload the named constant:
3007 VALUE autoload_const_value
= rb_mutex_synchronize(autoload_mutex
, autoload_load_needed
, (VALUE
)&arguments
);
3009 // This confirms whether autoloading is required or not:
3010 if (autoload_const_value
== Qfalse
) return autoload_const_value
;
3012 arguments
.flag
= ce
->flag
& (CONST_DEPRECATED
| CONST_VISIBILITY_MASK
);
3014 // Only one thread will enter here at a time:
3015 VALUE result
= rb_mutex_synchronize(arguments
.mutex
, autoload_try_load
, (VALUE
)&arguments
);
3017 // If you don't guard this value, it's possible for the autoload constant to
3018 // be freed by another thread which loads multiple constants, one of which
3019 // resolves to the constant this thread is trying to load, so proteect this
3020 // so that it is not freed until we are done with it in `autoload_try_load`:
3021 RB_GC_GUARD(autoload_const_value
);
3027 rb_autoload_p(VALUE mod
, ID id
)
3029 return rb_autoload_at_p(mod
, id
, TRUE
);
3033 rb_autoload_at_p(VALUE mod
, ID id
, int recur
)
3036 struct autoload_data
*ele
;
3038 while (!autoload_defined_p(mod
, id
)) {
3039 if (!recur
) return Qnil
;
3040 mod
= RCLASS_SUPER(mod
);
3041 if (!mod
) return Qnil
;
3043 load
= check_autoload_required(mod
, id
, 0);
3044 if (!load
) return Qnil
;
3045 return (ele
= get_autoload_data(load
, 0)) ? ele
->feature
: Qnil
;
3049 rb_const_warn_if_deprecated(const rb_const_entry_t
*ce
, VALUE klass
, ID id
)
3051 if (RB_CONST_DEPRECATED_P(ce
) &&
3052 rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED
)) {
3053 if (klass
== rb_cObject
) {
3054 rb_category_warn(RB_WARN_CATEGORY_DEPRECATED
, "constant ::%"PRIsVALUE
" is deprecated", QUOTE_ID(id
));
3057 rb_category_warn(RB_WARN_CATEGORY_DEPRECATED
, "constant %"PRIsVALUE
"::%"PRIsVALUE
" is deprecated",
3058 rb_class_name(klass
), QUOTE_ID(id
));
3064 rb_const_get_0(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3066 VALUE c
= rb_const_search(klass
, id
, exclude
, recurse
, visibility
);
3068 if (UNLIKELY(!rb_ractor_main_p())) {
3069 if (!rb_ractor_shareable_p(c
)) {
3070 rb_raise(rb_eRactorIsolationError
, "can not access non-shareable objects in constant %"PRIsVALUE
"::%s by non-main Ractor.", rb_class_path(klass
), rb_id2name(id
));
3075 return rb_const_missing(klass
, ID2SYM(id
));
3079 rb_const_search_from(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3081 VALUE value
, current
;
3082 bool first_iteration
= true;
3084 for (current
= klass
;
3086 current
= RCLASS_SUPER(current
), first_iteration
= false) {
3089 rb_const_entry_t
*ce
;
3091 if (!first_iteration
&& RCLASS_ORIGIN(current
) != current
) {
3092 // This item in the super chain has an origin iclass
3093 // that comes later in the chain. Skip this item so
3094 // prepended modules take precedence.
3098 // Do lookup in original class or module in case we are at an origin
3099 // iclass in the chain.
3101 if (BUILTIN_TYPE(tmp
) == T_ICLASS
) tmp
= RBASIC(tmp
)->klass
;
3103 // Do the lookup. Loop in case of autoload.
3104 while ((ce
= rb_const_lookup(tmp
, id
))) {
3105 if (visibility
&& RB_CONST_PRIVATE_P(ce
)) {
3106 GET_EC()->private_const_reference
= tmp
;
3109 rb_const_warn_if_deprecated(ce
, tmp
, id
);
3111 if (UNDEF_P(value
)) {
3112 struct autoload_const
*ac
;
3113 if (am
== tmp
) break;
3115 ac
= autoloading_const_entry(tmp
, id
);
3116 if (ac
) return ac
->value
;
3117 rb_autoload_load(tmp
, id
);
3120 if (exclude
&& tmp
== rb_cObject
) {
3125 if (!recurse
) break;
3129 GET_EC()->private_const_reference
= 0;
3134 rb_const_search(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3138 if (klass
== rb_cObject
) exclude
= FALSE
;
3139 value
= rb_const_search_from(klass
, id
, exclude
, recurse
, visibility
);
3140 if (!UNDEF_P(value
)) return value
;
3141 if (exclude
) return value
;
3142 if (BUILTIN_TYPE(klass
) != T_MODULE
) return value
;
3143 /* search global const too, if klass is a module */
3144 return rb_const_search_from(rb_cObject
, id
, FALSE
, recurse
, visibility
);
3148 rb_const_get_from(VALUE klass
, ID id
)
3150 return rb_const_get_0(klass
, id
, TRUE
, TRUE
, FALSE
);
3154 rb_const_get(VALUE klass
, ID id
)
3156 return rb_const_get_0(klass
, id
, FALSE
, TRUE
, FALSE
);
3160 rb_const_get_at(VALUE klass
, ID id
)
3162 return rb_const_get_0(klass
, id
, TRUE
, FALSE
, FALSE
);
3166 rb_public_const_get_from(VALUE klass
, ID id
)
3168 return rb_const_get_0(klass
, id
, TRUE
, TRUE
, TRUE
);
3172 rb_public_const_get_at(VALUE klass
, ID id
)
3174 return rb_const_get_0(klass
, id
, TRUE
, FALSE
, TRUE
);
3177 NORETURN(static void undefined_constant(VALUE mod
, VALUE name
));
3179 undefined_constant(VALUE mod
, VALUE name
)
3181 rb_name_err_raise("constant %2$s::%1$s not defined",
3186 rb_const_location_from(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3188 while (RTEST(klass
)) {
3189 rb_const_entry_t
*ce
;
3191 while ((ce
= rb_const_lookup(klass
, id
))) {
3192 if (visibility
&& RB_CONST_PRIVATE_P(ce
)) {
3195 if (exclude
&& klass
== rb_cObject
) {
3199 if (UNDEF_P(ce
->value
)) { // autoload
3200 VALUE autoload_const_value
= autoload_data(klass
, id
);
3201 if (RTEST(autoload_const_value
)) {
3202 struct autoload_const
*autoload_const
;
3203 struct autoload_data
*autoload_data
= get_autoload_data(autoload_const_value
, &autoload_const
);
3205 if (!UNDEF_P(autoload_const
->value
) && RTEST(rb_mutex_owned_p(autoload_data
->mutex
))) {
3206 return rb_assoc_new(autoload_const
->file
, INT2NUM(autoload_const
->line
));
3211 if (NIL_P(ce
->file
)) return rb_ary_new();
3212 return rb_assoc_new(ce
->file
, INT2NUM(ce
->line
));
3214 if (!recurse
) break;
3215 klass
= RCLASS_SUPER(klass
);
3223 rb_const_location(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3227 if (klass
== rb_cObject
) exclude
= FALSE
;
3228 loc
= rb_const_location_from(klass
, id
, exclude
, recurse
, visibility
);
3229 if (!NIL_P(loc
)) return loc
;
3230 if (exclude
) return loc
;
3231 if (BUILTIN_TYPE(klass
) != T_MODULE
) return loc
;
3232 /* search global const too, if klass is a module */
3233 return rb_const_location_from(rb_cObject
, id
, FALSE
, recurse
, visibility
);
3237 rb_const_source_location(VALUE klass
, ID id
)
3239 return rb_const_location(klass
, id
, FALSE
, TRUE
, FALSE
);
3243 rb_const_source_location_at(VALUE klass
, ID id
)
3245 return rb_const_location(klass
, id
, TRUE
, FALSE
, FALSE
);
3250 * remove_const(sym) -> obj
3252 * Removes the definition of the given constant, returning that
3253 * constant's previous value. If that constant referred to
3254 * a module, this will not change that module's name and can lead
3259 rb_mod_remove_const(VALUE mod
, VALUE name
)
3261 const ID id
= id_for_var(mod
, name
, a
, constant
);
3264 undefined_constant(mod
, name
);
3266 return rb_const_remove(mod
, id
);
3270 rb_const_remove(VALUE mod
, ID id
)
3273 rb_const_entry_t
*ce
;
3275 rb_check_frozen(mod
);
3277 ce
= rb_const_lookup(mod
, id
);
3278 if (!ce
|| !rb_id_table_delete(RCLASS_CONST_TBL(mod
), id
)) {
3279 if (rb_const_defined_at(mod
, id
)) {
3280 rb_name_err_raise("cannot remove %2$s::%1$s", mod
, ID2SYM(id
));
3283 undefined_constant(mod
, ID2SYM(id
));
3286 rb_clear_constant_cache_for_id(id
);
3291 autoload_delete(mod
, id
);
3301 cv_i_update(st_data_t
*k
, st_data_t
*v
, st_data_t a
, int existing
)
3303 if (existing
) return ST_STOP
;
3308 static enum rb_id_table_iterator_result
3309 sv_i(ID key
, VALUE v
, void *a
)
3311 rb_const_entry_t
*ce
= (rb_const_entry_t
*)v
;
3314 if (rb_is_const_id(key
)) {
3315 st_update(tbl
, (st_data_t
)key
, cv_i_update
, (st_data_t
)ce
);
3317 return ID_TABLE_CONTINUE
;
3320 static enum rb_id_table_iterator_result
3321 rb_local_constants_i(ID const_name
, VALUE const_value
, void *ary
)
3323 if (rb_is_const_id(const_name
) && !RB_CONST_PRIVATE_P((rb_const_entry_t
*)const_value
)) {
3324 rb_ary_push((VALUE
)ary
, ID2SYM(const_name
));
3326 return ID_TABLE_CONTINUE
;
3330 rb_local_constants(VALUE mod
)
3332 struct rb_id_table
*tbl
= RCLASS_CONST_TBL(mod
);
3335 if (!tbl
) return rb_ary_new2(0);
3339 ary
= rb_ary_new2(rb_id_table_size(tbl
));
3340 rb_id_table_foreach(tbl
, rb_local_constants_i
, (void *)ary
);
3348 rb_mod_const_at(VALUE mod
, void *data
)
3350 st_table
*tbl
= data
;
3352 tbl
= st_init_numtable();
3354 if (RCLASS_CONST_TBL(mod
)) {
3357 rb_id_table_foreach(RCLASS_CONST_TBL(mod
), sv_i
, tbl
);
3365 rb_mod_const_of(VALUE mod
, void *data
)
3369 data
= rb_mod_const_at(tmp
, data
);
3370 tmp
= RCLASS_SUPER(tmp
);
3372 if (tmp
== rb_cObject
&& mod
!= rb_cObject
) break;
3378 list_i(st_data_t key
, st_data_t value
, VALUE ary
)
3381 rb_const_entry_t
*ce
= (rb_const_entry_t
*)value
;
3382 if (RB_CONST_PUBLIC_P(ce
)) rb_ary_push(ary
, ID2SYM(sym
));
3387 rb_const_list(void *data
)
3389 st_table
*tbl
= data
;
3392 if (!tbl
) return rb_ary_new2(0);
3393 ary
= rb_ary_new2(tbl
->num_entries
);
3394 st_foreach_safe(tbl
, list_i
, ary
);
3402 * mod.constants(inherit=true) -> array
3404 * Returns an array of the names of the constants accessible in
3405 * <i>mod</i>. This includes the names of constants in any included
3406 * modules (example at start of section), unless the <i>inherit</i>
3407 * parameter is set to <code>false</code>.
3409 * The implementation makes no guarantees about the order in which the
3410 * constants are yielded.
3412 * IO.constants.include?(:SYNC) #=> true
3413 * IO.constants(false).include?(:SYNC) #=> false
3415 * Also see Module#const_defined?.
3419 rb_mod_constants(int argc
, const VALUE
*argv
, VALUE mod
)
3421 bool inherit
= true;
3423 if (rb_check_arity(argc
, 0, 1)) inherit
= RTEST(argv
[0]);
3426 return rb_const_list(rb_mod_const_of(mod
, 0));
3429 return rb_local_constants(mod
);
3434 rb_const_defined_0(VALUE klass
, ID id
, int exclude
, int recurse
, int visibility
)
3438 rb_const_entry_t
*ce
;
3443 if ((ce
= rb_const_lookup(tmp
, id
))) {
3444 if (visibility
&& RB_CONST_PRIVATE_P(ce
)) {
3447 if (UNDEF_P(ce
->value
) && !check_autoload_required(tmp
, id
, 0) &&
3448 !rb_autoloading_value(tmp
, id
, NULL
, NULL
))
3451 if (exclude
&& tmp
== rb_cObject
&& klass
!= rb_cObject
) {
3457 if (!recurse
) break;
3458 tmp
= RCLASS_SUPER(tmp
);
3460 if (!exclude
&& !mod_retry
&& BUILTIN_TYPE(klass
) == T_MODULE
) {
3469 rb_const_defined_from(VALUE klass
, ID id
)
3471 return rb_const_defined_0(klass
, id
, TRUE
, TRUE
, FALSE
);
3475 rb_const_defined(VALUE klass
, ID id
)
3477 return rb_const_defined_0(klass
, id
, FALSE
, TRUE
, FALSE
);
3481 rb_const_defined_at(VALUE klass
, ID id
)
3483 return rb_const_defined_0(klass
, id
, TRUE
, FALSE
, FALSE
);
3487 rb_public_const_defined_from(VALUE klass
, ID id
)
3489 return rb_const_defined_0(klass
, id
, TRUE
, TRUE
, TRUE
);
3493 check_before_mod_set(VALUE klass
, ID id
, VALUE val
, const char *dest
)
3495 rb_check_frozen(klass
);
3498 static void set_namespace_path(VALUE named_namespace
, VALUE name
);
3500 static enum rb_id_table_iterator_result
3501 set_namespace_path_i(ID id
, VALUE v
, void *payload
)
3503 rb_const_entry_t
*ce
= (rb_const_entry_t
*)v
;
3504 VALUE value
= ce
->value
;
3505 VALUE parental_path
= *((VALUE
*) payload
);
3506 if (!rb_is_const_id(id
) || !rb_namespace_p(value
)) {
3507 return ID_TABLE_CONTINUE
;
3510 bool has_permanent_classpath
;
3511 classname(value
, &has_permanent_classpath
);
3512 if (has_permanent_classpath
) {
3513 return ID_TABLE_CONTINUE
;
3515 set_namespace_path(value
, build_const_path(parental_path
, id
));
3517 if (!RCLASS_EXT(value
)->permanent_classpath
) {
3518 RCLASS_SET_CLASSPATH(value
, 0, false);
3521 return ID_TABLE_CONTINUE
;
3525 * Assign permanent classpaths to all namespaces that are directly or indirectly
3526 * nested under +named_namespace+. +named_namespace+ must have a permanent
3530 set_namespace_path(VALUE named_namespace
, VALUE namespace_path
)
3532 struct rb_id_table
*const_table
= RCLASS_CONST_TBL(named_namespace
);
3536 RCLASS_SET_CLASSPATH(named_namespace
, namespace_path
, true);
3539 rb_id_table_foreach(const_table
, set_namespace_path_i
, &namespace_path
);
3546 const_added(VALUE klass
, ID const_name
)
3548 if (GET_VM()->running
) {
3549 VALUE name
= ID2SYM(const_name
);
3550 rb_funcallv(klass
, idConst_added
, 1, &name
);
3555 const_set(VALUE klass
, ID id
, VALUE val
)
3557 rb_const_entry_t
*ce
;
3560 rb_raise(rb_eTypeError
, "no class/module to define constant %"PRIsVALUE
"",
3564 if (!rb_ractor_main_p() && !rb_ractor_shareable_p(val
)) {
3565 rb_raise(rb_eRactorIsolationError
, "can not set constants with non-shareable objects by non-main Ractors");
3568 check_before_mod_set(klass
, id
, val
, "constant");
3572 struct rb_id_table
*tbl
= RCLASS_CONST_TBL(klass
);
3574 RCLASS_CONST_TBL(klass
) = tbl
= rb_id_table_create(0);
3575 rb_clear_constant_cache_for_id(id
);
3576 ce
= ZALLOC(rb_const_entry_t
);
3577 rb_id_table_insert(tbl
, id
, (VALUE
)ce
);
3578 setup_const_entry(ce
, klass
, val
, CONST_PUBLIC
);
3581 struct autoload_const ac
= {
3582 .module
= klass
, .name
= id
,
3583 .value
= val
, .flag
= CONST_PUBLIC
,
3584 /* fill the rest with 0 */
3586 ac
.file
= rb_source_location(&ac
.line
);
3587 const_tbl_update(&ac
, false);
3593 * Resolve and cache class name immediately to resolve ambiguity
3594 * and avoid order-dependency on const_tbl
3596 if (rb_cObject
&& rb_namespace_p(val
)) {
3597 bool val_path_permanent
;
3598 VALUE val_path
= classname(val
, &val_path_permanent
);
3599 if (NIL_P(val_path
) || !val_path_permanent
) {
3600 if (klass
== rb_cObject
) {
3601 set_namespace_path(val
, rb_id2str(id
));
3604 bool parental_path_permanent
;
3605 VALUE parental_path
= classname(klass
, &parental_path_permanent
);
3606 if (NIL_P(parental_path
)) {
3608 parental_path
= rb_tmp_class_path(klass
, &throwaway
, make_temporary_path
);
3610 if (parental_path_permanent
&& !val_path_permanent
) {
3611 set_namespace_path(val
, build_const_path(parental_path
, id
));
3613 else if (!parental_path_permanent
&& NIL_P(val_path
)) {
3614 RCLASS_SET_CLASSPATH(val
, build_const_path(parental_path
, id
), false);
3622 rb_const_set(VALUE klass
, ID id
, VALUE val
)
3624 const_set(klass
, id
, val
);
3625 const_added(klass
, id
);
3628 static struct autoload_data
*
3629 autoload_data_for_named_constant(VALUE module
, ID name
, struct autoload_const
**autoload_const_pointer
)
3631 VALUE autoload_data_value
= autoload_data(module
, name
);
3632 if (!autoload_data_value
) return 0;
3634 struct autoload_data
*autoload_data
= get_autoload_data(autoload_data_value
, autoload_const_pointer
);
3635 if (!autoload_data
) return 0;
3637 /* for autoloading thread, keep the defined value to autoloading storage */
3638 if (autoload_by_current(autoload_data
)) {
3639 return autoload_data
;
3646 const_tbl_update(struct autoload_const
*ac
, int autoload_force
)
3649 VALUE klass
= ac
->module
;
3650 VALUE val
= ac
->value
;
3652 struct rb_id_table
*tbl
= RCLASS_CONST_TBL(klass
);
3653 rb_const_flag_t visibility
= ac
->flag
;
3654 rb_const_entry_t
*ce
;
3656 if (rb_id_table_lookup(tbl
, id
, &value
)) {
3657 ce
= (rb_const_entry_t
*)value
;
3658 if (UNDEF_P(ce
->value
)) {
3659 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
3660 VALUE file
= ac
->file
;
3661 int line
= ac
->line
;
3662 struct autoload_data
*ele
= autoload_data_for_named_constant(klass
, id
, &ac
);
3664 if (!autoload_force
&& ele
) {
3665 rb_clear_constant_cache_for_id(id
);
3667 ac
->value
= val
; /* autoload_data is non-WB-protected */
3668 ac
->file
= rb_source_location(&ac
->line
);
3671 /* otherwise autoloaded constant, allow to override */
3672 autoload_delete(klass
, id
);
3673 ce
->flag
= visibility
;
3674 RB_OBJ_WRITE(klass
, &ce
->value
, val
);
3675 RB_OBJ_WRITE(klass
, &ce
->file
, file
);
3678 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
3682 VALUE name
= QUOTE_ID(id
);
3683 visibility
= ce
->flag
;
3684 if (klass
== rb_cObject
)
3685 rb_warn("already initialized constant %"PRIsVALUE
"", name
);
3687 rb_warn("already initialized constant %"PRIsVALUE
"::%"PRIsVALUE
"",
3688 rb_class_name(klass
), name
);
3689 if (!NIL_P(ce
->file
) && ce
->line
) {
3690 rb_compile_warn(RSTRING_PTR(ce
->file
), ce
->line
,
3691 "previous definition of %"PRIsVALUE
" was here", name
);
3694 rb_clear_constant_cache_for_id(id
);
3695 setup_const_entry(ce
, klass
, val
, visibility
);
3698 rb_clear_constant_cache_for_id(id
);
3700 ce
= ZALLOC(rb_const_entry_t
);
3701 rb_id_table_insert(tbl
, id
, (VALUE
)ce
);
3702 setup_const_entry(ce
, klass
, val
, visibility
);
3707 setup_const_entry(rb_const_entry_t
*ce
, VALUE klass
, VALUE val
,
3708 rb_const_flag_t visibility
)
3710 ce
->flag
= visibility
;
3711 RB_OBJ_WRITE(klass
, &ce
->value
, val
);
3712 RB_OBJ_WRITE(klass
, &ce
->file
, rb_source_location(&ce
->line
));
3716 rb_define_const(VALUE klass
, const char *name
, VALUE val
)
3718 ID id
= rb_intern(name
);
3720 if (!rb_is_const_id(id
)) {
3721 rb_warn("rb_define_const: invalid name '%s' for constant", name
);
3723 if (!RB_SPECIAL_CONST_P(val
)) {
3724 rb_vm_register_global_object(val
);
3726 rb_const_set(klass
, id
, val
);
3730 rb_define_global_const(const char *name
, VALUE val
)
3732 rb_define_const(rb_cObject
, name
, val
);
3736 set_const_visibility(VALUE mod
, int argc
, const VALUE
*argv
,
3737 rb_const_flag_t flag
, rb_const_flag_t mask
)
3740 rb_const_entry_t
*ce
;
3743 rb_class_modify_check(mod
);
3745 rb_warning("%"PRIsVALUE
" with no argument is just ignored",
3746 QUOTE_ID(rb_frame_callee()));
3750 for (i
= 0; i
< argc
; i
++) {
3751 struct autoload_const
*ac
;
3752 VALUE val
= argv
[i
];
3753 id
= rb_check_id(&val
);
3755 undefined_constant(mod
, val
);
3757 if ((ce
= rb_const_lookup(mod
, id
))) {
3760 if (UNDEF_P(ce
->value
)) {
3761 struct autoload_data
*ele
;
3763 ele
= autoload_data_for_named_constant(mod
, id
, &ac
);
3769 rb_clear_constant_cache_for_id(id
);
3772 undefined_constant(mod
, ID2SYM(id
));
3778 rb_deprecate_constant(VALUE mod
, const char *name
)
3780 rb_const_entry_t
*ce
;
3782 long len
= strlen(name
);
3784 rb_class_modify_check(mod
);
3785 if (!(id
= rb_check_id_cstr(name
, len
, NULL
))) {
3786 undefined_constant(mod
, rb_fstring_new(name
, len
));
3788 if (!(ce
= rb_const_lookup(mod
, id
))) {
3789 undefined_constant(mod
, ID2SYM(id
));
3791 ce
->flag
|= CONST_DEPRECATED
;
3796 * mod.private_constant(symbol, ...) => mod
3798 * Makes a list of existing constants private.
3802 rb_mod_private_constant(int argc
, const VALUE
*argv
, VALUE obj
)
3804 set_const_visibility(obj
, argc
, argv
, CONST_PRIVATE
, CONST_VISIBILITY_MASK
);
3810 * mod.public_constant(symbol, ...) => mod
3812 * Makes a list of existing constants public.
3816 rb_mod_public_constant(int argc
, const VALUE
*argv
, VALUE obj
)
3818 set_const_visibility(obj
, argc
, argv
, CONST_PUBLIC
, CONST_VISIBILITY_MASK
);
3824 * mod.deprecate_constant(symbol, ...) => mod
3826 * Makes a list of existing constants deprecated. Attempt
3827 * to refer to them will produce a warning.
3830 * NotFound = Exception.new
3831 * NOT_FOUND = NotFound # previous version of the library used this name
3833 * deprecate_constant :NOT_FOUND
3837 * # warning: constant HTTP::NOT_FOUND is deprecated
3842 rb_mod_deprecate_constant(int argc
, const VALUE
*argv
, VALUE obj
)
3844 set_const_visibility(obj
, argc
, argv
, CONST_DEPRECATED
, CONST_DEPRECATED
);
3849 original_module(VALUE c
)
3851 if (RB_TYPE_P(c
, T_ICLASS
))
3852 return RBASIC(c
)->klass
;
3857 cvar_lookup_at(VALUE klass
, ID id
, st_data_t
*v
)
3859 if (RB_TYPE_P(klass
, T_ICLASS
)) {
3860 if (FL_TEST_RAW(klass
, RICLASS_IS_ORIGIN
)) {
3864 // check the original module
3865 klass
= RBASIC(klass
)->klass
;
3869 VALUE n
= rb_ivar_lookup(klass
, id
, Qundef
);
3870 if (UNDEF_P(n
)) return 0;
3877 cvar_front_klass(VALUE klass
)
3879 if (RCLASS_SINGLETON_P(klass
)) {
3880 VALUE obj
= RCLASS_ATTACHED_OBJECT(klass
);
3881 if (rb_namespace_p(obj
)) {
3885 return RCLASS_SUPER(klass
);
3889 cvar_overtaken(VALUE front
, VALUE target
, ID id
)
3891 if (front
&& target
!= front
) {
3892 if (original_module(front
) != original_module(target
)) {
3893 rb_raise(rb_eRuntimeError
,
3894 "class variable % "PRIsVALUE
" of %"PRIsVALUE
" is overtaken by %"PRIsVALUE
"",
3895 ID2SYM(id
), rb_class_name(original_module(front
)),
3896 rb_class_name(original_module(target
)));
3898 if (BUILTIN_TYPE(front
) == T_CLASS
) {
3899 rb_ivar_delete(front
, id
, Qundef
);
3904 #define CVAR_FOREACH_ANCESTORS(klass, v, r) \
3905 for (klass = cvar_front_klass(klass); klass; klass = RCLASS_SUPER(klass)) { \
3906 if (cvar_lookup_at(klass, id, (v))) { \
3911 #define CVAR_LOOKUP(v,r) do {\
3912 CVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(); \
3913 if (cvar_lookup_at(klass, id, (v))) {r;}\
3914 CVAR_FOREACH_ANCESTORS(klass, v, r);\
3918 find_cvar(VALUE klass
, VALUE
* front
, VALUE
* target
, ID id
)
3932 check_for_cvar_table(VALUE subclass
, VALUE key
)
3934 // Must not check ivar on ICLASS
3935 if (!RB_TYPE_P(subclass
, T_ICLASS
) && RTEST(rb_ivar_defined(subclass
, key
))) {
3936 RB_DEBUG_COUNTER_INC(cvar_class_invalidate
);
3937 ruby_vm_global_cvar_state
++;
3941 rb_class_foreach_subclass(subclass
, check_for_cvar_table
, key
);
3945 rb_cvar_set(VALUE klass
, ID id
, VALUE val
)
3947 VALUE tmp
, front
= 0, target
= 0;
3950 CVAR_LOOKUP(0, {if (!front
) front
= klass
; target
= klass
;});
3952 cvar_overtaken(front
, target
, id
);
3958 if (RB_TYPE_P(target
, T_ICLASS
)) {
3959 target
= RBASIC(target
)->klass
;
3961 check_before_mod_set(target
, id
, val
, "class variable");
3963 int result
= rb_class_ivar_set(target
, id
, val
);
3965 struct rb_id_table
*rb_cvc_tbl
= RCLASS_CVC_TBL(target
);
3968 rb_cvc_tbl
= RCLASS_CVC_TBL(target
) = rb_id_table_create(2);
3971 struct rb_cvar_class_tbl_entry
*ent
;
3974 if (!rb_id_table_lookup(rb_cvc_tbl
, id
, &ent_data
)) {
3975 ent
= ALLOC(struct rb_cvar_class_tbl_entry
);
3976 ent
->class_value
= target
;
3977 ent
->global_cvar_state
= GET_GLOBAL_CVAR_STATE();
3979 rb_id_table_insert(rb_cvc_tbl
, id
, (VALUE
)ent
);
3980 RB_DEBUG_COUNTER_INC(cvar_inline_miss
);
3983 ent
= (void *)ent_data
;
3984 ent
->global_cvar_state
= GET_GLOBAL_CVAR_STATE();
3987 // Break the cvar cache if this is a new class variable
3988 // and target is a module or a subclass with the same
3989 // cvar in this lookup.
3991 if (RB_TYPE_P(target
, T_CLASS
)) {
3992 if (RCLASS_SUBCLASSES(target
)) {
3993 rb_class_foreach_subclass(target
, check_for_cvar_table
, id
);
4000 rb_cvar_find(VALUE klass
, ID id
, VALUE
*front
)
4005 value
= find_cvar(klass
, front
, &target
, id
);
4007 rb_name_err_raise("uninitialized class variable %1$s in %2$s",
4010 cvar_overtaken(*front
, target
, id
);
4011 return (VALUE
)value
;
4015 rb_cvar_get(VALUE klass
, ID id
)
4018 return rb_cvar_find(klass
, id
, &front
);
4022 rb_cvar_defined(VALUE klass
, ID id
)
4024 if (!klass
) return Qfalse
;
4025 CVAR_LOOKUP(0,return Qtrue
);
4030 cv_intern(VALUE klass
, const char *name
)
4032 ID id
= rb_intern(name
);
4033 if (!rb_is_class_id(id
)) {
4034 rb_name_err_raise("wrong class variable name %1$s",
4035 klass
, rb_str_new_cstr(name
));
4041 rb_cv_set(VALUE klass
, const char *name
, VALUE val
)
4043 ID id
= cv_intern(klass
, name
);
4044 rb_cvar_set(klass
, id
, val
);
4048 rb_cv_get(VALUE klass
, const char *name
)
4050 ID id
= cv_intern(klass
, name
);
4051 return rb_cvar_get(klass
, id
);
4055 rb_define_class_variable(VALUE klass
, const char *name
, VALUE val
)
4057 rb_cv_set(klass
, name
, val
);
4061 cv_i(ID key
, VALUE v
, st_data_t a
)
4063 st_table
*tbl
= (st_table
*)a
;
4065 if (rb_is_class_id(key
)) {
4066 st_update(tbl
, (st_data_t
)key
, cv_i_update
, 0);
4072 mod_cvar_at(VALUE mod
, void *data
)
4074 st_table
*tbl
= data
;
4076 tbl
= st_init_numtable();
4078 mod
= original_module(mod
);
4080 rb_ivar_foreach(mod
, cv_i
, (st_data_t
)tbl
);
4085 mod_cvar_of(VALUE mod
, void *data
)
4088 if (RCLASS_SINGLETON_P(mod
)) {
4089 if (rb_namespace_p(RCLASS_ATTACHED_OBJECT(mod
))) {
4090 data
= mod_cvar_at(tmp
, data
);
4091 tmp
= cvar_front_klass(tmp
);
4095 data
= mod_cvar_at(tmp
, data
);
4096 tmp
= RCLASS_SUPER(tmp
);
4103 cv_list_i(st_data_t key
, st_data_t value
, VALUE ary
)
4106 rb_ary_push(ary
, ID2SYM(sym
));
4111 cvar_list(void *data
)
4113 st_table
*tbl
= data
;
4116 if (!tbl
) return rb_ary_new2(0);
4117 ary
= rb_ary_new2(tbl
->num_entries
);
4118 st_foreach_safe(tbl
, cv_list_i
, ary
);
4126 * mod.class_variables(inherit=true) -> array
4128 * Returns an array of the names of class variables in <i>mod</i>.
4129 * This includes the names of class variables in any included
4130 * modules, unless the <i>inherit</i> parameter is set to
4131 * <code>false</code>.
4139 * One.class_variables #=> [:@@var1]
4140 * Two.class_variables #=> [:@@var2, :@@var1]
4141 * Two.class_variables(false) #=> [:@@var2]
4145 rb_mod_class_variables(int argc
, const VALUE
*argv
, VALUE mod
)
4147 bool inherit
= true;
4150 if (rb_check_arity(argc
, 0, 1)) inherit
= RTEST(argv
[0]);
4152 tbl
= mod_cvar_of(mod
, 0);
4155 tbl
= mod_cvar_at(mod
, 0);
4157 return cvar_list(tbl
);
4162 * remove_class_variable(sym) -> obj
4164 * Removes the named class variable from the receiver, returning that
4169 * puts remove_class_variable(:@@var)
4173 * <em>produces:</em>
4180 rb_mod_remove_cvar(VALUE mod
, VALUE name
)
4182 const ID id
= id_for_var_message(mod
, name
, class, "wrong class variable name %1$s");
4188 rb_check_frozen(mod
);
4189 val
= rb_ivar_delete(mod
, id
, Qundef
);
4190 if (!UNDEF_P(val
)) {
4193 if (rb_cvar_defined(mod
, id
)) {
4194 rb_name_err_raise("cannot remove %1$s for %2$s", mod
, ID2SYM(id
));
4197 rb_name_err_raise("class variable %1$s not defined for %2$s",
4199 UNREACHABLE_RETURN(Qundef
);
4203 rb_iv_get(VALUE obj
, const char *name
)
4205 ID id
= rb_check_id_cstr(name
, strlen(name
), rb_usascii_encoding());
4210 return rb_ivar_get(obj
, id
);
4214 rb_iv_set(VALUE obj
, const char *name
, VALUE val
)
4216 ID id
= rb_intern(name
);
4218 return rb_ivar_set(obj
, id
, val
);
4222 class_ivar_set_shape_ivptr(VALUE obj
, void *_data
)
4224 RUBY_ASSERT(!rb_shape_obj_too_complex(obj
));
4226 return RCLASS_IVPTR(obj
);
4230 class_ivar_set_shape_resize_ivptr(VALUE obj
, attr_index_t _old_capa
, attr_index_t new_capa
, void *_data
)
4232 REALLOC_N(RCLASS_IVPTR(obj
), VALUE
, new_capa
);
4236 class_ivar_set_set_shape(VALUE obj
, rb_shape_t
*shape
, void *_data
)
4238 rb_shape_set_shape(obj
, shape
);
4242 class_ivar_set_transition_too_complex(VALUE obj
, void *_data
)
4244 rb_evict_ivars_to_hash(obj
);
4248 class_ivar_set_too_complex_table(VALUE obj
, void *_data
)
4250 RUBY_ASSERT(rb_shape_obj_too_complex(obj
));
4252 return RCLASS_IV_HASH(obj
);
4256 rb_class_ivar_set(VALUE obj
, ID id
, VALUE val
)
4258 RUBY_ASSERT(RB_TYPE_P(obj
, T_CLASS
) || RB_TYPE_P(obj
, T_MODULE
));
4259 bool existing
= false;
4260 rb_check_frozen(obj
);
4264 existing
= general_ivar_set(obj
, id
, val
, NULL
,
4265 class_ivar_set_shape_ivptr
,
4266 class_ivar_set_shape_resize_ivptr
,
4267 class_ivar_set_set_shape
,
4268 class_ivar_set_transition_too_complex
,
4269 class_ivar_set_too_complex_table
).existing
;
4277 tbl_copy_i(ID key
, VALUE val
, st_data_t dest
)
4279 rb_class_ivar_set((VALUE
)dest
, key
, val
);
4285 rb_iv_tbl_copy(VALUE dst
, VALUE src
)
4287 RUBY_ASSERT(rb_type(dst
) == rb_type(src
));
4288 RUBY_ASSERT(RB_TYPE_P(dst
, T_CLASS
) || RB_TYPE_P(dst
, T_MODULE
));
4290 RUBY_ASSERT(rb_shape_get_shape(dst
)->type
== SHAPE_ROOT
);
4291 RUBY_ASSERT(!RCLASS_IVPTR(dst
));
4293 rb_ivar_foreach(src
, tbl_copy_i
, dst
);
4297 rb_const_lookup(VALUE klass
, ID id
)
4299 struct rb_id_table
*tbl
= RCLASS_CONST_TBL(klass
);
4306 r
= rb_id_table_lookup(tbl
, id
, &val
);
4310 if (r
) return (rb_const_entry_t
*)val
;