14 #include "ruby/internal/config.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"
40 #include "ractor_core.h"
44 #define GET_GLOBAL_CVAR_STATE() (ruby_vm_global_cvar_state)
46 typedef void rb_gvar_compact_t(
void *var);
54 static VALUE autoload_features;
59 static VALUE autoload_mutex;
61 static void check_before_mod_set(
VALUE,
ID,
VALUE,
const char *);
63 static VALUE rb_const_search(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility);
69 rb_global_tbl = rb_id_table_create(0);
70 generic_iv_tbl_ = st_init_numtable();
75 rb_vm_register_global_object(autoload_mutex);
77 autoload_features = rb_ident_hash_new();
79 rb_vm_register_global_object(autoload_features);
83 rb_namespace_p(
VALUE obj)
104 classname(
VALUE klass,
bool *permanent)
108 VALUE classpath = RCLASS_EXT(klass)->classpath;
109 if (classpath == 0)
return Qnil;
111 *permanent = RCLASS_EXT(klass)->permanent_classpath;
117 rb_mod_name0(
VALUE klass,
bool *permanent)
119 return classname(klass, permanent);
134 return classname(mod, &permanent);
139 is_constant_path(
VALUE name)
145 const char *p = path;
147 if (p >= pend || !*p) {
152 if (p + 2 <= pend && p[0] ==
':' && p[1] ==
':') {
156 const char *pbeg = p;
157 while (p < pend && *p !=
':') p++;
159 if (pbeg == p)
return false;
161 if (rb_enc_symname_type(pbeg, p - pbeg, enc, 0) != ID_CONST) {
218 rb_mod_set_temporary_name(
VALUE mod,
VALUE name)
221 if (RCLASS_EXT(mod)->permanent_classpath) {
227 RCLASS_SET_CLASSPATH(mod, 0, FALSE);
237 if (is_constant_path(name)) {
242 RCLASS_SET_CLASSPATH(mod, name, FALSE);
257 path =
rb_sprintf(
"#<Module:%p>", (
void*)obj);
260 path =
rb_sprintf(
"#<%"PRIsVALUE
":%p>", klass, (
void*)obj);
270 rb_tmp_class_path(
VALUE klass,
bool *permanent, fallback_func fallback)
272 VALUE path = classname(klass, permanent);
284 path = rb_tmp_class_path(
RBASIC(klass)->klass, &perm, fallback);
289 return fallback(klass, path);
296 VALUE path = rb_tmp_class_path(klass, &permanent, make_temporary_path);
314 rb_search_class_path(
VALUE klass)
317 return rb_tmp_class_path(klass, &permanent, no_fallback);
326 return rb_fstring(path);
330 build_const_path(
VALUE head,
ID tail)
332 return build_const_pathname(head,
rb_id2str(tail));
338 bool permanent =
true;
341 if (under == rb_cObject) {
345 str = rb_tmp_class_path(under, &permanent, make_temporary_path);
346 str = build_const_pathname(str, name);
349 RCLASS_SET_CLASSPATH(klass, str, permanent);
364 const char *pbeg, *pend, *p, *path =
RSTRING_PTR(pathname);
366 VALUE c = rb_cObject;
373 if (path == pend || path[0] ==
'#') {
378 while (p < pend && *p !=
':') p++;
380 if (p < pend && p[0] ==
':') {
381 if ((
size_t)(pend - p) < 2 || p[1] !=
':')
goto undefined_class;
386 goto undefined_class;
388 c = rb_const_search(c,
id, TRUE, FALSE, FALSE);
389 if (UNDEF_P(c))
goto undefined_class;
390 if (!rb_namespace_p(c)) {
421 VALUE path = rb_tmp_class_path(
rb_class_real(klass), &permanent, make_temporary_path);
422 if (
NIL_P(path))
return NULL;
446 rb_gvar_compact_t *compactor;
470 static enum rb_id_table_iterator_result
471 free_global_entry_i(
VALUE val,
void *arg)
474 entry->var->counter--;
475 if (entry->var->counter == 0) {
476 free_global_variable(entry->var);
479 return ID_TABLE_DELETE;
483 rb_free_rb_global_tbl(
void)
485 rb_id_table_foreach_values(rb_global_tbl, free_global_entry_i, 0);
486 rb_id_table_free(rb_global_tbl);
490 rb_free_generic_iv_tbl_(
void)
492 st_free_table(generic_iv_tbl_);
496 rb_find_global_entry(
ID id)
501 if (!rb_id_table_lookup(rb_global_tbl,
id, &data)) {
509 if (UNLIKELY(!rb_ractor_main_p()) && (!entry || !entry->ractor_local)) {
510 rb_raise(rb_eRactorIsolationError,
"can not access global variables %s from non-main Ractors",
rb_id2name(
id));
517 rb_gvar_ractor_local(
const char *name)
520 entry->ractor_local =
true;
524 rb_gvar_undef_compactor(
void *var)
538 entry->ractor_local =
false;
544 var->compactor = rb_gvar_undef_compactor;
546 var->block_trace = 0;
548 rb_id_table_insert(rb_global_tbl,
id, (
VALUE)entry);
556 rb_warning(
"global variable '%"PRIsVALUE
"' not initialized", QUOTE_ID(
id));
562 rb_gvar_val_compactor(
void *_var)
571 var->data = (
void*)
new;
583 var->compactor = rb_gvar_val_compactor;
585 var->data = (
void*)val;
603 var->data = (
void*)val;
616 if (!var)
return Qnil;
635 rb_name_error(
id,
"%"PRIsVALUE
" is a read-only variable", QUOTE_ID(
id));
638 static enum rb_id_table_iterator_result
639 mark_global_entry(
VALUE v,
void *ignored)
645 (*var->marker)(var->data);
651 return ID_TABLE_CONTINUE;
654 #define gc_mark_table(task) \
655 if (rb_global_tbl) { rb_id_table_foreach_values(rb_global_tbl, task##_global_entry, 0); }
658 rb_gc_mark_global_tbl(
void)
663 static enum rb_id_table_iterator_result
664 update_global_entry(
VALUE v,
void *ignored)
669 (*var->compactor)(var);
670 return ID_TABLE_CONTINUE;
674 rb_gc_update_global_tbl(
void)
676 gc_mark_table(update);
680 global_id(
const char *name)
684 if (name[0] ==
'$')
id =
rb_intern(name);
686 size_t len = strlen(name);
690 memcpy(buf+1, name,
len);
698 find_global_id(
const char *name)
701 size_t len = strlen(name);
703 if (name[0] ==
'$') {
710 memcpy(buf+1, name,
len);
726 ID id = global_id(name);
729 gvar->data = (
void*)var;
781 trace->next = entry->var->trace;
782 trace->func = rb_trace_eval;
785 entry->var->trace = trace;
799 while (trace->next) {
802 trace->next = next->next;
825 if ((entry = rb_find_global_entry(
id)) == NULL) {
826 rb_name_error(
id,
"undefined global variable %"PRIsVALUE
"", QUOTE_ID(
id));
829 trace = entry->var->trace;
840 if (!entry->var->block_trace) remove_trace(entry->var);
845 if (trace->data == cmd) {
847 if (!entry->var->block_trace) remove_trace(entry->var);
868 (*trace->func)(trace->data, data->val);
879 var->block_trace = 0;
890 (*var->setter)(val, entry->id, var->data);
892 if (var->trace && !var->block_trace) {
893 var->block_trace = 1;
894 trace.trace = var->trace;
907 return rb_gvar_set_entry(entry, val);
913 return rb_gvar_set(global_id(name), val);
921 return (*var->getter)(entry->id, var->data);
927 ID id = find_global_id(name);
930 rb_warning(
"global variable '%s' not initialized", name);
934 return rb_gvar_get(
id);
938 rb_gvar_defined(
ID id)
945 rb_gvar_getter_function_of(
ID id)
948 return entry->var->getter;
952 rb_gvar_setter_function_of(
ID id)
955 return entry->var->setter;
958 static enum rb_id_table_iterator_result
959 gvar_i(
ID key,
VALUE val,
void *a)
963 return ID_TABLE_CONTINUE;
972 if (!rb_ractor_main_p()) {
973 rb_raise(rb_eRactorIsolationError,
"can not access global variables from non-main Ractors");
976 rb_id_table_foreach(rb_global_tbl, gvar_i, (
void *)ary);
977 if (!
NIL_P(backref)) {
979 int i, nmatch = rb_match_count(backref);
981 for (i = 1; i <= nmatch; ++i) {
985 buf[1] = (char)(i +
'0');
1005 if (!rb_ractor_main_p()) {
1006 rb_raise(rb_eRactorIsolationError,
"can not access global variables from non-main Ractors");
1010 if (!rb_id_table_lookup(gtbl, name1, &data1)) {
1013 rb_id_table_insert(gtbl, name1, (
VALUE)entry1);
1015 else if ((entry1 = (
struct rb_global_entry *)data1)->var != entry2->var) {
1017 if (var->block_trace) {
1021 if (var->counter == 0) {
1022 free_global_variable(var);
1028 entry2->var->counter++;
1029 entry1->var = entry2->var;
1033 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(
ID id)
1035 if (UNLIKELY(!rb_ractor_main_p())) {
1037 rb_raise(rb_eRactorIsolationError,
"can not set instance variables of classes/modules by non-main Ractors");
1042 #define CVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR() \
1043 if (UNLIKELY(!rb_ractor_main_p())) { \
1044 rb_raise(rb_eRactorIsolationError, "can not access class variables from non-main Ractors"); \
1048 generic_ivtbl(
VALUE obj,
ID id,
bool force_check_ractor)
1050 ASSERT_vm_locking();
1054 UNLIKELY(!rb_ractor_main_p()) &&
1057 rb_raise(rb_eRactorIsolationError,
"can not access instance variables of shareable objects from non-main Ractors");
1059 return generic_iv_tbl_;
1063 generic_ivtbl_no_ractor_check(
VALUE obj)
1065 return generic_ivtbl(obj, 0,
false);
1069 rb_generic_ivtbl_get(
void)
1071 return generic_iv_tbl_;
1084 if (st_lookup(generic_ivtbl(obj,
id,
false), (st_data_t)obj, &data)) {
1095 rb_ivar_generic_ivtbl_lookup(
VALUE obj,
struct gen_ivtbl **ivtbl)
1097 return rb_gen_ivtbl_get(obj, 0, ivtbl);
1101 gen_ivtbl_bytes(
size_t n)
1103 return offsetof(
struct gen_ivtbl, as.shape.ivptr) + n *
sizeof(
VALUE);
1107 gen_ivtbl_resize(
struct gen_ivtbl *old, uint32_t n)
1111 uint32_t
len = old ? old->as.shape.numiv : 0;
1114 ivtbl->as.shape.numiv = n;
1123 rb_mark_generic_ivar(
VALUE obj)
1126 if (st_lookup(generic_ivtbl_no_ractor_check(obj), (st_data_t)obj, &data)) {
1128 if (rb_shape_obj_too_complex(obj)) {
1132 for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) {
1140 rb_ref_update_generic_ivar(
VALUE obj)
1144 if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
1145 if (rb_shape_obj_too_complex(obj)) {
1146 rb_gc_ref_update_table_values_only(ivtbl->as.complex.table);
1149 for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) {
1150 ivtbl->as.shape.ivptr[i] =
rb_gc_location(ivtbl->as.shape.ivptr[i]);
1159 st_data_t key = (st_data_t)rsrc;
1162 if (st_delete(generic_ivtbl_no_ractor_check(rsrc), &key, &ivtbl))
1163 st_insert(generic_ivtbl_no_ractor_check(dst), (st_data_t)dst, ivtbl);
1169 st_data_t key = (st_data_t)obj, value;
1171 bool too_complex = rb_shape_obj_too_complex(obj);
1173 if (st_delete(generic_ivtbl_no_ractor_check(obj), &key, &value)) {
1176 if (UNLIKELY(too_complex)) {
1177 st_free_table(ivtbl->as.complex.table);
1185 rb_generic_ivar_memsize(
VALUE obj)
1189 if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
1190 if (rb_shape_obj_too_complex(obj)) {
1191 return sizeof(
struct gen_ivtbl) + st_memsize(ivtbl->as.complex.table);
1194 return gen_ivtbl_bytes(ivtbl->as.shape.numiv);
1200 #if !SHAPE_IN_BASIC_FLAGS
1202 rb_generic_shape_id(
VALUE obj)
1205 shape_id_t shape_id = 0;
1209 st_table* global_iv_table = generic_ivtbl(obj, 0,
false);
1211 if (global_iv_table && st_lookup(global_iv_table, obj, (st_data_t *)&ivtbl)) {
1212 shape_id = ivtbl->shape_id;
1215 shape_id = SPECIAL_CONST_SHAPE_ID;
1230 if (rb_shape_obj_too_complex(obj)) {
1231 n = st_table_size(ivtbl->as.complex.table);
1234 for (i = 0; i < ivtbl->as.shape.numiv; i++) {
1235 if (!UNDEF_P(ivtbl->as.shape.ivptr[i])) {
1249 shape_id_t shape_id;
1253 #if SHAPE_IN_BASIC_FLAGS
1254 shape_id = RBASIC_SHAPE_ID(obj);
1266 #if !SHAPE_IN_BASIC_FLAGS
1267 shape_id = RCLASS_SHAPE_ID(obj);
1270 if (rb_shape_obj_too_complex(obj)) {
1271 st_table * iv_table = RCLASS_IV_HASH(obj);
1272 if (rb_st_lookup(iv_table, (st_data_t)
id, (st_data_t *)&val)) {
1280 attr_index_t index = 0;
1281 shape = rb_shape_get_shape_by_id(shape_id);
1282 found = rb_shape_get_iv_index(shape,
id, &index);
1285 ivar_list = RCLASS_IVPTR(obj);
1288 val = ivar_list[index];
1299 UNLIKELY(!rb_ractor_main_p()) &&
1302 "can not get unshareable values from instance variables of classes/modules from non-main Ractors");
1308 #if !SHAPE_IN_BASIC_FLAGS
1309 shape_id = ROBJECT_SHAPE_ID(obj);
1311 if (rb_shape_obj_too_complex(obj)) {
1312 st_table * iv_table = ROBJECT_IV_HASH(obj);
1314 if (rb_st_lookup(iv_table, (st_data_t)
id, (st_data_t *)&val)) {
1329 rb_gen_ivtbl_get(obj,
id, &ivtbl);
1331 if (rb_shape_obj_too_complex(obj)) {
1333 if (rb_st_lookup(ivtbl->as.complex.table, (st_data_t)
id, (st_data_t *)&val)) {
1341 #if !SHAPE_IN_BASIC_FLAGS
1342 shape_id = ivtbl->shape_id;
1344 ivar_list = ivtbl->as.shape.ivptr;
1352 attr_index_t index = 0;
1353 shape = rb_shape_get_shape_by_id(shape_id);
1354 if (rb_shape_get_iv_index(shape,
id, &index)) {
1355 return ivar_list[index];
1364 VALUE iv = rb_ivar_lookup(obj,
id,
Qnil);
1365 RB_DEBUG_COUNTER_INC(ivar_get_base);
1372 return rb_ivar_lookup(obj,
id,
Qnil);
1378 rb_check_frozen(obj);
1384 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(
id);
1387 if (!rb_shape_transition_shape_remove_ivar(obj,
id, shape, &val)) {
1388 if (!rb_shape_obj_too_complex(obj)) {
1389 rb_evict_ivars_to_hash(obj);
1396 table = RCLASS_IV_HASH(obj);
1400 table = ROBJECT_IV_HASH(obj);
1405 if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
1406 table = ivtbl->as.complex.table;
1413 if (!st_delete(table, (st_data_t *)&
id, (st_data_t *)&val)) {
1423 rb_attr_delete(
VALUE obj,
ID id)
1425 return rb_ivar_delete(obj,
id,
Qnil);
1433 VALUE *old_ivptr = NULL;
1437 if (!(
RBASIC(obj)->flags & ROBJECT_EMBED)) {
1440 rb_shape_set_shape_id(obj, OBJ_TOO_COMPLEX_SHAPE_ID);
1441 ROBJECT_SET_IV_HASH(obj, table);
1445 old_ivptr = RCLASS_IVPTR(obj);
1446 rb_shape_set_shape_id(obj, OBJ_TOO_COMPLEX_SHAPE_ID);
1447 RCLASS_SET_IV_HASH(obj, table);
1452 struct st_table *gen_ivs = generic_ivtbl_no_ractor_check(obj);
1455 st_lookup(gen_ivs, (st_data_t)obj, (st_data_t *)&old_ivtbl);
1462 #if SHAPE_IN_BASIC_FLAGS
1463 rb_shape_set_shape_id(obj, OBJ_TOO_COMPLEX_SHAPE_ID);
1465 old_ivtbl->shape_id = OBJ_TOO_COMPLEX_SHAPE_ID;
1467 old_ivtbl->as.complex.table = table;
1468 old_ivptr = (
VALUE *)old_ivtbl;
1472 ivtbl->as.complex.table = table;
1473 st_insert(gen_ivs, (st_data_t)obj, (st_data_t)ivtbl);
1474 #if SHAPE_IN_BASIC_FLAGS
1475 rb_shape_set_shape_id(obj, OBJ_TOO_COMPLEX_SHAPE_ID);
1477 ivtbl->shape_id = OBJ_TOO_COMPLEX_SHAPE_ID;
1487 rb_evict_ivars_to_hash(
VALUE obj)
1494 rb_obj_copy_ivs_to_hash_table(obj, table);
1495 rb_obj_convert_to_too_complex(obj, table);
1506 general_ivar_set(
VALUE obj,
ID id,
VALUE val, void *data,
1508 void (*shape_resize_ivptr_func)(
VALUE, attr_index_t, attr_index_t,
void *),
1510 void (*transition_too_complex_func)(
VALUE,
void *),
1518 rb_shape_t *current_shape = rb_shape_get_shape(obj);
1520 if (UNLIKELY(current_shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
1525 if (!rb_shape_get_iv_index(current_shape,
id, &index)) {
1526 result.existing =
false;
1528 index = current_shape->next_iv_index;
1529 if (index >= MAX_IVARS) {
1533 rb_shape_t *next_shape = rb_shape_get_next(current_shape, obj,
id);
1534 if (UNLIKELY(next_shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
1535 transition_too_complex_func(obj, data);
1538 else if (UNLIKELY(next_shape->capacity != current_shape->capacity)) {
1539 RUBY_ASSERT(next_shape->capacity > current_shape->capacity);
1540 shape_resize_ivptr_func(obj, current_shape->capacity, next_shape->capacity, data);
1544 RUBY_ASSERT(index == (next_shape->next_iv_index - 1));
1545 set_shape_func(obj, next_shape, data);
1548 VALUE *table = shape_ivptr_func(obj, data);
1551 result.index = index;
1558 st_table *table = too_complex_table_func(obj, data);
1559 result.existing = st_insert(table, (st_data_t)
id, (st_data_t)val);
1575 generic_ivar_lookup_ensure_size(st_data_t *k, st_data_t *v, st_data_t u,
int existing)
1577 ASSERT_vm_locking();
1582 if (!existing || ivar_lookup->resize) {
1584 RUBY_ASSERT(ivar_lookup->shape->type == SHAPE_IVAR);
1585 RUBY_ASSERT(rb_shape_get_shape_by_id(ivar_lookup->shape->parent_id)->capacity < ivar_lookup->shape->capacity);
1591 ivtbl = gen_ivtbl_resize(ivtbl, ivar_lookup->shape->capacity);
1592 *v = (st_data_t)ivtbl;
1597 ivar_lookup->ivtbl = ivtbl;
1598 if (ivar_lookup->shape) {
1599 #if SHAPE_IN_BASIC_FLAGS
1600 rb_shape_set_shape(ivar_lookup->obj, ivar_lookup->shape);
1602 ivtbl->shape_id = rb_shape_id(ivar_lookup->shape);
1610 generic_ivar_set_shape_ivptr(
VALUE obj,
void *data)
1618 st_update(generic_ivtbl(obj, ivar_lookup->id,
false), (st_data_t)obj, generic_ivar_lookup_ensure_size, (st_data_t)ivar_lookup);
1624 return ivar_lookup->ivtbl->as.shape.ivptr;
1628 generic_ivar_set_shape_resize_ivptr(
VALUE obj, attr_index_t _old_capa, attr_index_t new_capa,
void *data)
1632 ivar_lookup->resize =
true;
1640 ivar_lookup->shape = shape;
1644 generic_ivar_set_transition_too_complex(
VALUE obj,
void *_data)
1646 rb_evict_ivars_to_hash(obj);
1651 generic_ivar_set_too_complex_table(
VALUE obj,
void *data)
1656 if (!rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
1658 #if !SHAPE_IN_BASIC_FLAGS
1659 ivtbl->shape_id = SHAPE_OBJ_TOO_COMPLEX;
1661 ivtbl->as.complex.table = st_init_numtable_with_size(1);
1665 st_insert(generic_ivtbl(obj, ivar_lookup->id,
false), (st_data_t)obj, (st_data_t)ivtbl);
1674 return ivtbl->as.complex.table;
1687 general_ivar_set(obj,
id, val, &ivar_lookup,
1688 generic_ivar_set_shape_ivptr,
1689 generic_ivar_set_shape_resize_ivptr,
1690 generic_ivar_set_set_shape,
1691 generic_ivar_set_transition_too_complex,
1692 generic_ivar_set_too_complex_table);
1696 rb_ensure_iv_list_size(
VALUE obj, uint32_t current_capacity, uint32_t new_capacity)
1700 if (
RBASIC(obj)->flags & ROBJECT_EMBED) {
1705 ROBJECT(obj)->as.heap.ivptr = newptr;
1713 rb_obj_copy_ivs_to_hash_table_i(
ID key,
VALUE val, st_data_t arg)
1717 st_add_direct((
st_table *)arg, (st_data_t)key, (st_data_t)val);
1724 rb_ivar_foreach(obj, rb_obj_copy_ivs_to_hash_table_i, (st_data_t)table);
1728 obj_ivar_set_shape_ivptr(
VALUE obj,
void *_data)
1736 obj_ivar_set_shape_resize_ivptr(
VALUE obj, attr_index_t old_capa, attr_index_t new_capa,
void *_data)
1738 rb_ensure_iv_list_size(obj, old_capa, new_capa);
1744 rb_shape_set_shape(obj, shape);
1748 obj_ivar_set_transition_too_complex(
VALUE obj,
void *_data)
1750 rb_evict_ivars_to_hash(obj);
1754 obj_ivar_set_too_complex_table(
VALUE obj,
void *_data)
1758 return ROBJECT_IV_HASH(obj);
1764 return general_ivar_set(obj,
id, val, NULL,
1765 obj_ivar_set_shape_ivptr,
1766 obj_ivar_set_shape_resize_ivptr,
1767 obj_ivar_set_set_shape,
1768 obj_ivar_set_transition_too_complex,
1769 obj_ivar_set_too_complex_table).index;
1779 rb_check_frozen(obj);
1780 rb_obj_ivar_set(obj,
id, val);
1785 rb_shape_set_shape_id(
VALUE obj, shape_id_t shape_id)
1787 if (rb_shape_get_shape_id(obj) == shape_id) {
1791 #if SHAPE_IN_BASIC_FLAGS
1792 RBASIC_SET_SHAPE_ID(obj, shape_id);
1796 ROBJECT_SET_SHAPE_ID(obj, shape_id);
1800 RCLASS_SET_SHAPE_ID(obj, shape_id);
1803 if (shape_id != SPECIAL_CONST_SHAPE_ID) {
1807 st_table* global_iv_table = generic_ivtbl(obj, 0,
false);
1809 if (st_lookup(global_iv_table, obj, (st_data_t *)&ivtbl)) {
1810 ivtbl->shape_id = shape_id;
1813 rb_bug(
"Expected shape_id entry in global iv table");
1832 rb_shape_t * next_shape = rb_shape_transition_shape_frozen(x);
1836 if (!rb_shape_obj_too_complex(x) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
1837 rb_evict_ivars_to_hash(x);
1839 rb_shape_set_shape(x, next_shape);
1850 RB_DEBUG_COUNTER_INC(ivar_set_base);
1855 rb_obj_ivar_set(obj,
id, val);
1860 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(
id);
1861 rb_class_ivar_set(obj,
id, val);
1865 generic_ivar_set(obj,
id, val);
1873 rb_check_frozen(obj);
1874 ivar_set(obj,
id, val);
1884 ivar_set(obj,
id, val);
1893 if (rb_shape_obj_too_complex(obj)) {
1899 table = (
st_table *)RCLASS_IVPTR(obj);
1903 table = ROBJECT_IV_HASH(obj);
1908 if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
1909 table = ivtbl->as.complex.table;
1915 if (!table || !rb_st_lookup(table,
id, &idx)) {
1922 return RBOOL(rb_shape_get_iv_index(rb_shape_get_shape(obj),
id, &index));
1926 typedef int rb_ivar_foreach_callback_func(
ID key,
VALUE val, st_data_t arg);
1927 st_data_t rb_st_nth_key(
st_table *tab, st_index_t index);
1933 rb_ivar_foreach_callback_func *func;
1940 iterate_over_shapes_with_callback(
rb_shape_t *shape, rb_ivar_foreach_callback_func *callback,
struct iv_itr_data * itr_data)
1942 switch ((
enum shape_type)shape->type) {
1944 case SHAPE_T_OBJECT:
1948 if (iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data))
1953 RUBY_ASSERT(!rb_shape_obj_too_complex(itr_data->obj));
1958 iv_list = RCLASS_IVPTR(itr_data->obj);
1961 iv_list = itr_data->ivtbl->as.shape.ivptr;
1964 VALUE val = iv_list[shape->next_iv_index - 1];
1965 if (!UNDEF_P(val)) {
1966 switch (callback(shape->edge_name, val, itr_data->arg)) {
1978 return iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data);
1979 case SHAPE_OBJ_TOO_COMPLEX:
1986 each_hash_iv(st_data_t
id, st_data_t val, st_data_t data)
1989 rb_ivar_foreach_callback_func *callback = itr_data->func;
1990 return callback((
ID)
id, (
VALUE)val, itr_data->arg);
1994 obj_ivar_each(
VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
2000 itr_data.func = func;
2001 if (rb_shape_obj_too_complex(obj)) {
2002 rb_st_foreach(ROBJECT_IV_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
2005 iterate_over_shapes_with_callback(shape, func, &itr_data);
2010 gen_ivar_each(
VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
2014 if (!rb_gen_ivtbl_get(obj, 0, &ivtbl))
return;
2018 itr_data.ivtbl = ivtbl;
2020 itr_data.func = func;
2021 if (rb_shape_obj_too_complex(obj)) {
2022 rb_st_foreach(ivtbl->as.complex.table, each_hash_iv, (st_data_t)&itr_data);
2025 iterate_over_shapes_with_callback(shape, func, &itr_data);
2030 class_ivar_each(
VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
2038 itr_data.func = func;
2039 if (rb_shape_obj_too_complex(obj)) {
2040 rb_st_foreach(RCLASS_IV_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
2043 iterate_over_shapes_with_callback(shape, func, &itr_data);
2053 rb_check_frozen(clone);
2059 if (rb_gen_ivtbl_get(obj, 0, &obj_ivtbl)) {
2060 if (gen_ivtbl_count(obj, obj_ivtbl) == 0)
2065 if (rb_shape_obj_too_complex(obj)) {
2067 #if !SHAPE_IN_BASIC_FLAGS
2068 new_ivtbl->shape_id = SHAPE_OBJ_TOO_COMPLEX;
2070 new_ivtbl->as.complex.table = st_copy(obj_ivtbl->as.complex.table);
2073 new_ivtbl = gen_ivtbl_resize(0, obj_ivtbl->as.shape.numiv);
2075 for (uint32_t i=0; i<obj_ivtbl->as.shape.numiv; i++) {
2076 RB_OBJ_WRITE(clone, &new_ivtbl->as.shape.ivptr[i], obj_ivtbl->as.shape.ivptr[i]);
2086 generic_ivtbl_no_ractor_check(clone);
2087 st_insert(generic_ivtbl_no_ractor_check(obj), (st_data_t)clone, (st_data_t)new_ivtbl);
2091 rb_shape_t * obj_shape = rb_shape_get_shape(obj);
2092 if (rb_shape_frozen_shape_p(obj_shape)) {
2093 rb_shape_set_shape_id(clone, obj_shape->parent_id);
2096 rb_shape_set_shape(clone, obj_shape);
2109 rb_replace_generic_ivar(
VALUE clone,
VALUE obj)
2115 st_data_t ivtbl, obj_data = (st_data_t)obj;
2116 if (st_lookup(generic_iv_tbl_, (st_data_t)obj, &ivtbl)) {
2117 st_insert(generic_iv_tbl_, (st_data_t)clone, ivtbl);
2118 st_delete(generic_iv_tbl_, &obj_data, NULL);
2135 obj_ivar_each(obj, func, arg);
2139 IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(0);
2142 class_ivar_each(obj, func, arg);
2148 gen_ivar_each(obj, func, arg);
2161 return ROBJECT_IV_COUNT(obj);
2164 return RCLASS_IV_COUNT(obj);
2169 if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
2170 return gen_ivtbl_count(obj, ivtbl);
2179 ivar_i(
ID key,
VALUE v, st_data_t a)
2216 #define rb_is_constant_id rb_is_const_id
2217 #define rb_is_constant_name rb_is_const_name
2218 #define id_for_var(obj, name, part, type) \
2219 id_for_var_message(obj, name, type, "'%1$s' is not allowed as "#part" "#type" variable name")
2220 #define id_for_var_message(obj, name, type, message) \
2221 check_id_type(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
2224 int (*valid_id_p)(
ID),
int (*valid_name_p)(
VALUE),
2225 const char *message,
size_t message_len)
2228 VALUE name = *pname;
2230 if (
id ? !valid_id_p(
id) : !valid_name_p(name)) {
2231 rb_name_err_raise_str(rb_fstring_new(message, message_len),
2263 const ID id = id_for_var(obj, name, an, instance);
2267 rb_check_frozen(obj);
2272 if (!UNDEF_P(val))
return val;
2275 rb_name_err_raise(
"instance variable %1$s not defined",
2280 NORETURN(
static void uninitialized_constant(
VALUE,
VALUE));
2282 uninitialized_constant(
VALUE klass,
VALUE name)
2285 rb_name_err_raise(
"uninitialized constant %2$s::%1$s",
2288 rb_name_err_raise(
"uninitialized constant %1$s",
2296 rb_vm_inc_const_missing_count();
2342 rb_mod_const_missing(
VALUE klass,
VALUE name)
2345 VALUE ref = ec->private_const_reference;
2346 rb_vm_pop_cfunc_frame();
2348 ec->private_const_reference = 0;
2349 rb_name_err_raise(
"private constant %2$s::%1$s referenced", ref, name);
2351 uninitialized_constant(klass, name);
2357 autoload_table_mark(
void *
ptr)
2363 autoload_table_free(
void *
ptr)
2369 autoload_table_memsize(
const void *
ptr)
2372 return st_memsize(tbl);
2376 autoload_table_compact(
void *
ptr)
2383 {autoload_table_mark, autoload_table_free, autoload_table_memsize, autoload_table_compact,},
2384 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
2387 #define check_autoload_table(av) \
2388 (struct st_table *)rb_check_typeddata((av), &autoload_table_type)
2403 mod =
RBASIC(mod)->klass;
2411 VALUE tbl_value = rb_ivar_lookup(mod, autoload,
Qfalse);
2412 if (!
RTEST(tbl_value) || !(tbl = check_autoload_table(tbl_value)) || !st_lookup(tbl, (st_data_t)
id, &val)) {
2422 struct ccan_list_node cnode;
2425 VALUE autoload_data_value;
2437 rb_const_flag_t flag;
2453 rb_serial_t fork_gen;
2456 struct ccan_list_head constants;
2460 autoload_data_compact(
void *
ptr)
2469 autoload_data_mark(
void *
ptr)
2478 autoload_data_free(
void *
ptr)
2483 ccan_list_for_each_safe(&p->constants,
autoload_const, next, cnode) {
2491 autoload_data_memsize(
const void *
ptr)
2498 {autoload_data_mark, autoload_data_free, autoload_data_memsize, autoload_data_compact},
2499 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
2503 autoload_const_compact(
void *
ptr)
2508 ac->autoload_data_value =
rb_gc_location(ac->autoload_data_value);
2514 autoload_const_mark(
void *
ptr)
2525 autoload_const_memsize(
const void *
ptr)
2531 autoload_const_free(
void *
ptr)
2541 {autoload_const_mark, autoload_const_free, autoload_const_memsize, autoload_const_compact,},
2542 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
2546 get_autoload_data(
VALUE autoload_const_value,
struct autoload_const **autoload_const_pointer)
2559 if (autoload_const_pointer) *autoload_const_pointer =
autoload_const;
2565 rb_autoload(
VALUE module,
ID name,
const char *feature)
2567 if (!feature || !*feature) {
2571 rb_autoload_str(module, name, rb_fstring_cstr(feature));
2575 static void const_added(
VALUE klass,
ID const_name);
2584 autoload_feature_lookup_or_create(
VALUE feature,
struct autoload_data **autoload_data_pointer)
2586 RUBY_ASSERT_MUTEX_OWNED(autoload_mutex);
2587 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2592 if (
NIL_P(autoload_data_value)) {
2598 if (autoload_data_pointer) *autoload_data_pointer =
autoload_data;
2600 rb_hash_aset(autoload_features, feature, autoload_data_value);
2602 else if (autoload_data_pointer) {
2603 *autoload_data_pointer =
rb_check_typeddata(autoload_data_value, &autoload_data_type);
2606 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2607 return autoload_data_value;
2611 autoload_table_lookup_or_create(
VALUE module)
2613 VALUE autoload_table_value = rb_ivar_lookup(module, autoload,
Qfalse);
2614 if (
RTEST(autoload_table_value)) {
2615 return autoload_table_value;
2619 rb_class_ivar_set(module, autoload, autoload_table_value);
2621 return autoload_table_value;
2626 autoload_synchronized(
VALUE _arguments)
2630 rb_const_entry_t *constant_entry = rb_const_lookup(arguments->module, arguments->name);
2631 if (constant_entry && !UNDEF_P(constant_entry->value)) {
2636 const_set(arguments->module, arguments->name,
Qundef);
2638 VALUE autoload_table_value = autoload_table_lookup_or_create(arguments->module);
2639 struct st_table *autoload_table = check_autoload_table(autoload_table_value);
2642 VALUE feature = rb_fstring(arguments->feature);
2645 VALUE autoload_data_value = autoload_feature_lookup_or_create(feature, &
autoload_data);
2656 st_insert(autoload_table, (st_data_t)arguments->name, (st_data_t)autoload_const_value);
2683 if (result ==
Qtrue) {
2684 const_added(module, name);
2689 autoload_delete(
VALUE module,
ID name)
2691 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2693 st_data_t load = 0, key = name;
2697 VALUE table_value = rb_ivar_lookup(module, autoload,
Qfalse);
2698 if (
RTEST(table_value)) {
2699 struct st_table *table = check_autoload_table(table_value);
2701 st_delete(table, &key, &load);
2724 if (table->num_entries == 0) {
2725 rb_attr_delete(module, autoload);
2730 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2736 return ele->mutex !=
Qnil && !rb_mutex_owned_p(ele->mutex);
2740 check_autoload_required(
VALUE mod,
ID id,
const char **loadingpath)
2744 const char *loading;
2746 if (!autoload_const_value || !(
autoload_data = get_autoload_data(autoload_const_value, 0))) {
2759 return autoload_const_value;
2765 return autoload_const_value;
2768 if (loadingpath && loading) {
2769 *loadingpath = loading;
2770 return autoload_const_value;
2779 rb_autoloading_value(
VALUE mod,
ID id,
VALUE* value, rb_const_flag_t *flag)
2782 if (!ac)
return FALSE;
2798 return ele->mutex !=
Qnil && rb_mutex_owned_p(ele->mutex);
2805 autoloading_const_entry(
VALUE mod,
ID id)
2812 if (!load || !(ele = get_autoload_data(load, &ac))) {
2818 if (autoload_by_current(ele)) {
2819 if (!UNDEF_P(ac->value)) {
2828 autoload_defined_p(
VALUE mod,
ID id)
2833 if (!ce || !UNDEF_P(ce->value)) {
2839 return !rb_autoloading_value(mod,
id, NULL, NULL);
2861 check_before_mod_set(ac->module, ac->name, ac->value,
"constant");
2865 const_tbl_update(ac,
true);
2873 autoload_load_needed(
VALUE _arguments)
2877 const char *loading = 0, *src;
2879 if (!autoload_defined_p(arguments->module, arguments->name)) {
2883 VALUE autoload_const_value = check_autoload_required(arguments->module, arguments->name, &loading);
2884 if (!autoload_const_value) {
2889 if (src && loading && strcmp(src, loading) == 0) {
2910 return autoload_const_value;
2914 autoload_apply_constants(
VALUE _arguments)
2916 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
2928 ccan_list_for_each_safe(&arguments->autoload_data->constants,
autoload_const, next, cnode) {
2934 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
2940 autoload_feature_require(
VALUE _arguments)
2951 if (
RTEST(result)) {
2959 autoload_try_load(
VALUE _arguments)
2963 VALUE result = autoload_feature_require(_arguments);
2966 rb_const_entry_t *ce = rb_const_lookup(arguments->module, arguments->name);
2968 if (!ce || UNDEF_P(ce->value)) {
2973 if (arguments->module == rb_cObject) {
2975 "Expected %"PRIsVALUE
" to define %"PRIsVALUE
" but it didn't",
2976 arguments->autoload_data->feature,
2982 "Expected %"PRIsVALUE
" to define %"PRIsVALUE
"::%"PRIsVALUE
" but it didn't",
2983 arguments->autoload_data->feature,
2991 ce->flag |= arguments->flag;
3003 if (!ce || !UNDEF_P(ce->value)) {
3008 if (UNLIKELY(!rb_ractor_main_p())) {
3009 return rb_ractor_autoload_load(module, name);
3019 if (autoload_const_value ==
Qfalse)
return autoload_const_value;
3021 arguments.flag = ce->flag & (CONST_DEPRECATED | CONST_VISIBILITY_MASK);
3038 return rb_autoload_at_p(mod,
id, TRUE);
3042 rb_autoload_at_p(
VALUE mod,
ID id,
int recur)
3047 while (!autoload_defined_p(mod,
id)) {
3048 if (!recur)
return Qnil;
3050 if (!mod)
return Qnil;
3052 load = check_autoload_required(mod,
id, 0);
3053 if (!load)
return Qnil;
3054 return (ele = get_autoload_data(load, 0)) ? ele->feature :
Qnil;
3060 if (RB_CONST_DEPRECATED_P(ce) &&
3062 if (klass == rb_cObject) {
3073 rb_const_get_0(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3075 VALUE c = rb_const_search(klass,
id, exclude, recurse, visibility);
3077 if (UNLIKELY(!rb_ractor_main_p())) {
3079 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));
3084 return rb_const_missing(klass,
ID2SYM(
id));
3088 rb_const_search_from(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3090 VALUE value, current;
3091 bool first_iteration =
true;
3093 for (current = klass;
3095 current =
RCLASS_SUPER(current), first_iteration =
false) {
3100 if (!first_iteration && RCLASS_ORIGIN(current) != current) {
3113 while ((ce = rb_const_lookup(tmp,
id))) {
3114 if (visibility && RB_CONST_PRIVATE_P(ce)) {
3115 GET_EC()->private_const_reference = tmp;
3118 rb_const_warn_if_deprecated(ce, tmp,
id);
3120 if (UNDEF_P(value)) {
3122 if (am == tmp)
break;
3124 ac = autoloading_const_entry(tmp,
id);
3125 if (ac)
return ac->value;
3129 if (exclude && tmp == rb_cObject) {
3134 if (!recurse)
break;
3138 GET_EC()->private_const_reference = 0;
3143 rb_const_search(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3147 if (klass == rb_cObject) exclude = FALSE;
3148 value = rb_const_search_from(klass,
id, exclude, recurse, visibility);
3149 if (!UNDEF_P(value))
return value;
3150 if (exclude)
return value;
3153 return rb_const_search_from(rb_cObject,
id, FALSE, recurse, visibility);
3159 return rb_const_get_0(klass,
id, TRUE, TRUE, FALSE);
3165 return rb_const_get_0(klass,
id, FALSE, TRUE, FALSE);
3171 return rb_const_get_0(klass,
id, TRUE, FALSE, FALSE);
3175 rb_public_const_get_from(
VALUE klass,
ID id)
3177 return rb_const_get_0(klass,
id, TRUE, TRUE, TRUE);
3181 rb_public_const_get_at(
VALUE klass,
ID id)
3183 return rb_const_get_0(klass,
id, TRUE, FALSE, TRUE);
3186 NORETURN(
static void undefined_constant(
VALUE mod,
VALUE name));
3190 rb_name_err_raise(
"constant %2$s::%1$s not defined",
3195 rb_const_location_from(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3197 while (
RTEST(klass)) {
3200 while ((ce = rb_const_lookup(klass,
id))) {
3201 if (visibility && RB_CONST_PRIVATE_P(ce)) {
3204 if (exclude && klass == rb_cObject) {
3208 if (UNDEF_P(ce->value)) {
3210 if (
RTEST(autoload_const_value)) {
3223 if (!recurse)
break;
3232 rb_const_location(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3236 if (klass == rb_cObject) exclude = FALSE;
3237 loc = rb_const_location_from(klass,
id, exclude, recurse, visibility);
3238 if (!
NIL_P(loc))
return loc;
3239 if (exclude)
return loc;
3242 return rb_const_location_from(rb_cObject,
id, FALSE, recurse, visibility);
3246 rb_const_source_location(
VALUE klass,
ID id)
3248 return rb_const_location(klass,
id, FALSE, TRUE, FALSE);
3252 rb_const_source_location_at(
VALUE klass,
ID id)
3254 return rb_const_location(klass,
id, TRUE, FALSE, FALSE);
3270 const ID id = id_for_var(mod, name, a, constant);
3273 undefined_constant(mod, name);
3284 rb_check_frozen(mod);
3286 ce = rb_const_lookup(mod,
id);
3287 if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod),
id)) {
3289 rb_name_err_raise(
"cannot remove %2$s::%1$s", mod,
ID2SYM(
id));
3292 undefined_constant(mod,
ID2SYM(
id));
3295 rb_const_warn_if_deprecated(ce, mod,
id);
3301 autoload_delete(mod,
id);
3311 cv_i_update(st_data_t *k, st_data_t *v, st_data_t a,
int existing)
3313 if (existing)
return ST_STOP;
3318 static enum rb_id_table_iterator_result
3319 sv_i(
ID key,
VALUE v,
void *a)
3325 st_update(tbl, (st_data_t)key, cv_i_update, (st_data_t)ce);
3327 return ID_TABLE_CONTINUE;
3330 static enum rb_id_table_iterator_result
3331 rb_local_constants_i(
ID const_name,
VALUE const_value,
void *ary)
3336 return ID_TABLE_CONTINUE;
3340 rb_local_constants(
VALUE mod)
3350 rb_id_table_foreach(tbl, rb_local_constants_i, (
void *)ary);
3362 tbl = st_init_numtable();
3364 if (RCLASS_CONST_TBL(mod)) {
3367 rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl);
3382 if (tmp == rb_cObject && mod != rb_cObject)
break;
3388 list_i(st_data_t key, st_data_t value,
VALUE ary)
3431 bool inherit =
true;
3439 return rb_local_constants(mod);
3444 rb_const_defined_0(
VALUE klass,
ID id,
int exclude,
int recurse,
int visibility)
3453 if ((ce = rb_const_lookup(tmp,
id))) {
3454 if (visibility && RB_CONST_PRIVATE_P(ce)) {
3457 if (UNDEF_P(ce->value) && !check_autoload_required(tmp,
id, 0) &&
3458 !rb_autoloading_value(tmp,
id, NULL, NULL))
3461 if (exclude && tmp == rb_cObject && klass != rb_cObject) {
3467 if (!recurse)
break;
3481 return rb_const_defined_0(klass,
id, TRUE, TRUE, FALSE);
3487 return rb_const_defined_0(klass,
id, FALSE, TRUE, FALSE);
3493 return rb_const_defined_0(klass,
id, TRUE, FALSE, FALSE);
3497 rb_public_const_defined_from(
VALUE klass,
ID id)
3499 return rb_const_defined_0(klass,
id, TRUE, TRUE, TRUE);
3503 check_before_mod_set(
VALUE klass,
ID id,
VALUE val,
const char *dest)
3505 rb_check_frozen(klass);
3508 static void set_namespace_path(
VALUE named_namespace,
VALUE name);
3510 static enum rb_id_table_iterator_result
3511 set_namespace_path_i(
ID id,
VALUE v,
void *payload)
3514 VALUE value = ce->value;
3517 return ID_TABLE_CONTINUE;
3520 bool has_permanent_classpath;
3521 classname(value, &has_permanent_classpath);
3522 if (has_permanent_classpath) {
3523 return ID_TABLE_CONTINUE;
3525 set_namespace_path(value, build_const_path(parental_path,
id));
3527 if (!RCLASS_EXT(value)->permanent_classpath) {
3528 RCLASS_SET_CLASSPATH(value, 0,
false);
3531 return ID_TABLE_CONTINUE;
3540 set_namespace_path(
VALUE named_namespace,
VALUE namespace_path)
3542 struct rb_id_table *const_table = RCLASS_CONST_TBL(named_namespace);
3546 RCLASS_SET_CLASSPATH(named_namespace, namespace_path,
true);
3549 rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
3556 const_added(
VALUE klass,
ID const_name)
3558 if (GET_VM()->running) {
3575 rb_raise(rb_eRactorIsolationError,
"can not set constants with non-shareable objects by non-main Ractors");
3578 check_before_mod_set(klass,
id, val,
"constant");
3582 struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
3584 RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
3587 rb_id_table_insert(tbl,
id, (
VALUE)ce);
3588 setup_const_entry(ce, klass, val, CONST_PUBLIC);
3592 .module = klass, .name = id,
3593 .value = val, .flag = CONST_PUBLIC,
3596 ac.file = rb_source_location(&ac.line);
3597 const_tbl_update(&ac,
false);
3606 if (rb_cObject && rb_namespace_p(val)) {
3607 bool val_path_permanent;
3608 VALUE val_path = classname(val, &val_path_permanent);
3609 if (
NIL_P(val_path) || !val_path_permanent) {
3610 if (klass == rb_cObject) {
3614 bool parental_path_permanent;
3615 VALUE parental_path = classname(klass, &parental_path_permanent);
3616 if (
NIL_P(parental_path)) {
3618 parental_path = rb_tmp_class_path(klass, &throwaway, make_temporary_path);
3620 if (parental_path_permanent && !val_path_permanent) {
3621 set_namespace_path(val, build_const_path(parental_path,
id));
3623 else if (!parental_path_permanent &&
NIL_P(val_path)) {
3624 RCLASS_SET_CLASSPATH(val, build_const_path(parental_path,
id),
false);
3634 const_set(klass,
id, val);
3635 const_added(klass,
id);
3639 autoload_data_for_named_constant(
VALUE module,
ID name,
struct autoload_const **autoload_const_pointer)
3642 if (!autoload_data_value)
return 0;
3659 VALUE klass = ac->module;
3660 VALUE val = ac->value;
3662 struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
3663 rb_const_flag_t visibility = ac->flag;
3666 if (rb_id_table_lookup(tbl,
id, &value)) {
3668 if (UNDEF_P(ce->value)) {
3669 RUBY_ASSERT_CRITICAL_SECTION_ENTER();
3670 VALUE file = ac->file;
3671 int line = ac->line;
3672 struct autoload_data *ele = autoload_data_for_named_constant(klass,
id, &ac);
3674 if (!autoload_force && ele) {
3678 ac->file = rb_source_location(&ac->line);
3682 autoload_delete(klass,
id);
3683 ce->flag = visibility;
3688 RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
3692 VALUE name = QUOTE_ID(
id);
3693 visibility = ce->flag;
3694 if (klass == rb_cObject)
3695 rb_warn(
"already initialized constant %"PRIsVALUE
"", name);
3697 rb_warn(
"already initialized constant %"PRIsVALUE
"::%"PRIsVALUE
"",
3699 if (!
NIL_P(ce->file) && ce->line) {
3701 "previous definition of %"PRIsVALUE
" was here", name);
3705 setup_const_entry(ce, klass, val, visibility);
3711 rb_id_table_insert(tbl,
id, (
VALUE)ce);
3712 setup_const_entry(ce, klass, val, visibility);
3718 rb_const_flag_t visibility)
3720 ce->flag = visibility;
3722 RB_OBJ_WRITE(klass, &ce->file, rb_source_location(&ce->line));
3731 rb_warn(
"rb_define_const: invalid name '%s' for constant", name);
3734 rb_vm_register_global_object(val);
3746 set_const_visibility(
VALUE mod,
int argc,
const VALUE *argv,
3747 rb_const_flag_t flag, rb_const_flag_t mask)
3755 rb_warning(
"%"PRIsVALUE
" with no argument is just ignored",
3760 for (i = 0; i < argc; i++) {
3762 VALUE val = argv[i];
3765 undefined_constant(mod, val);
3767 if ((ce = rb_const_lookup(mod,
id))) {
3770 if (UNDEF_P(ce->value)) {
3773 ele = autoload_data_for_named_constant(mod,
id, &ac);
3782 undefined_constant(mod,
ID2SYM(
id));
3792 long len = strlen(name);
3796 undefined_constant(mod, rb_fstring_new(name,
len));
3798 if (!(ce = rb_const_lookup(mod,
id))) {
3799 undefined_constant(mod,
ID2SYM(
id));
3801 ce->flag |= CONST_DEPRECATED;
3812 rb_mod_private_constant(
int argc,
const VALUE *argv,
VALUE obj)
3814 set_const_visibility(obj, argc, argv, CONST_PRIVATE, CONST_VISIBILITY_MASK);
3826 rb_mod_public_constant(
int argc,
const VALUE *argv,
VALUE obj)
3828 set_const_visibility(obj, argc, argv, CONST_PUBLIC, CONST_VISIBILITY_MASK);
3852 rb_mod_deprecate_constant(
int argc,
const VALUE *argv,
VALUE obj)
3854 set_const_visibility(obj, argc, argv, CONST_DEPRECATED, CONST_DEPRECATED);
3859 original_module(
VALUE c)
3867 cvar_lookup_at(
VALUE klass,
ID id, st_data_t *v)
3875 klass =
RBASIC(klass)->klass;
3880 if (UNDEF_P(n))
return 0;
3887 cvar_front_klass(
VALUE klass)
3889 if (RCLASS_SINGLETON_P(klass)) {
3890 VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
3891 if (rb_namespace_p(obj)) {
3901 if (front && target != front) {
3902 if (original_module(front) != original_module(target)) {
3904 "class variable % "PRIsVALUE
" of %"PRIsVALUE
" is overtaken by %"PRIsVALUE
"",
3909 rb_ivar_delete(front,
id,
Qundef);
3914 #define CVAR_FOREACH_ANCESTORS(klass, v, r) \
3915 for (klass = cvar_front_klass(klass); klass; klass = RCLASS_SUPER(klass)) { \
3916 if (cvar_lookup_at(klass, id, (v))) { \
3921 #define CVAR_LOOKUP(v,r) do {\
3922 CVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(); \
3923 if (cvar_lookup_at(klass, id, (v))) {r;}\
3924 CVAR_FOREACH_ANCESTORS(klass, v, r);\
3942 check_for_cvar_table(
VALUE subclass,
VALUE key)
3946 RB_DEBUG_COUNTER_INC(cvar_class_invalidate);
3947 ruby_vm_global_cvar_state++;
3951 rb_class_foreach_subclass(subclass, check_for_cvar_table, key);
3957 VALUE tmp, front = 0, target = 0;
3960 CVAR_LOOKUP(0, {
if (!front) front = klass; target = klass;});
3962 cvar_overtaken(front, target,
id);
3969 target =
RBASIC(target)->klass;
3971 check_before_mod_set(target,
id, val,
"class variable");
3973 int result = rb_class_ivar_set(target,
id, val);
3975 struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(target);
3978 rb_cvc_tbl = RCLASS_CVC_TBL(target) = rb_id_table_create(2);
3984 if (!rb_id_table_lookup(rb_cvc_tbl,
id, &ent_data)) {
3986 ent->class_value = target;
3987 ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
3989 rb_id_table_insert(rb_cvc_tbl,
id, (
VALUE)ent);
3990 RB_DEBUG_COUNTER_INC(cvar_inline_miss);
3993 ent = (
void *)ent_data;
3994 ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
4002 if (RCLASS_SUBCLASSES(target)) {
4003 rb_class_foreach_subclass(target, check_for_cvar_table,
id);
4015 value = find_cvar(klass, front, &target,
id);
4017 rb_name_err_raise(
"uninitialized class variable %1$s in %2$s",
4020 cvar_overtaken(*front, target,
id);
4021 return (
VALUE)value;
4034 if (!klass)
return Qfalse;
4035 CVAR_LOOKUP(0,
return Qtrue);
4040 cv_intern(
VALUE klass,
const char *name)
4044 rb_name_err_raise(
"wrong class variable name %1$s",
4053 ID id = cv_intern(klass, name);
4060 ID id = cv_intern(klass, name);
4071 cv_i(
ID key,
VALUE v, st_data_t a)
4076 st_update(tbl, (st_data_t)key, cv_i_update, 0);
4082 mod_cvar_at(
VALUE mod,
void *data)
4086 tbl = st_init_numtable();
4088 mod = original_module(mod);
4095 mod_cvar_of(
VALUE mod,
void *data)
4098 if (RCLASS_SINGLETON_P(mod)) {
4099 if (rb_namespace_p(RCLASS_ATTACHED_OBJECT(mod))) {
4100 data = mod_cvar_at(tmp, data);
4101 tmp = cvar_front_klass(tmp);
4105 data = mod_cvar_at(tmp, data);
4113 cv_list_i(st_data_t key, st_data_t value,
VALUE ary)
4121 cvar_list(
void *data)
4157 bool inherit =
true;
4162 tbl = mod_cvar_of(mod, 0);
4165 tbl = mod_cvar_at(mod, 0);
4167 return cvar_list(tbl);
4192 const ID id = id_for_var_message(mod, name,
class,
"wrong class variable name %1$s");
4198 rb_check_frozen(mod);
4199 val = rb_ivar_delete(mod,
id,
Qundef);
4200 if (!UNDEF_P(val)) {
4204 rb_name_err_raise(
"cannot remove %1$s for %2$s", mod,
ID2SYM(
id));
4207 rb_name_err_raise(
"class variable %1$s not defined for %2$s",
4232 class_ivar_set_shape_ivptr(
VALUE obj,
void *_data)
4236 return RCLASS_IVPTR(obj);
4240 class_ivar_set_shape_resize_ivptr(
VALUE obj, attr_index_t _old_capa, attr_index_t new_capa,
void *_data)
4248 rb_shape_set_shape(obj, shape);
4252 class_ivar_set_transition_too_complex(
VALUE obj,
void *_data)
4254 rb_evict_ivars_to_hash(obj);
4258 class_ivar_set_too_complex_table(
VALUE obj,
void *_data)
4262 return RCLASS_IV_HASH(obj);
4269 bool existing =
false;
4270 rb_check_frozen(obj);
4274 existing = general_ivar_set(obj,
id, val, NULL,
4275 class_ivar_set_shape_ivptr,
4276 class_ivar_set_shape_resize_ivptr,
4277 class_ivar_set_set_shape,
4278 class_ivar_set_transition_too_complex,
4279 class_ivar_set_too_complex_table).existing;
4287 tbl_copy_i(
ID key,
VALUE val, st_data_t dest)
4289 rb_class_ivar_set((
VALUE)dest, key, val);
4307 rb_const_lookup(
VALUE klass,
ID id)
4309 struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
4316 r = rb_id_table_lookup(tbl,
id, &val);
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define RUBY_EXTERN
Declaration of externally visible global variables.
static VALUE RB_OBJ_FROZEN_RAW(VALUE obj)
This is an implementation detail of RB_OBJ_FROZEN().
static bool RB_FL_ABLE(VALUE obj)
Checks if the object is flaggable.
static void RB_FL_SET_RAW(VALUE obj, VALUE flags)
This is an implementation detail of RB_FL_SET().
void rb_obj_freeze_inline(VALUE obj)
Prevents further modifications to the given object.
static void RB_FL_UNSET_RAW(VALUE obj, VALUE flags)
This is an implementation detail of RB_FL_UNSET().
@ RUBY_FL_FREEZE
This flag has something to do with data immutability.
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
void rb_freeze_singleton_class(VALUE x)
This is an implementation detail of RB_OBJ_FREEZE().
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
#define rb_str_new2
Old name of rb_str_new_cstr.
#define TYPE(_)
Old name of rb_type.
#define FL_EXIVAR
Old name of RUBY_FL_EXIVAR.
#define FL_USER3
Old name of RUBY_FL_USER3.
#define REALLOC_N
Old name of RB_REALLOC_N.
#define ALLOC
Old name of RB_ALLOC.
#define T_STRING
Old name of RUBY_T_STRING.
#define xfree
Old name of ruby_xfree.
#define Qundef
Old name of RUBY_Qundef.
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
#define xrealloc
Old name of ruby_xrealloc.
#define ID2SYM
Old name of RB_ID2SYM.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define ZALLOC
Old name of RB_ZALLOC.
#define CLASS_OF
Old name of rb_class_of.
#define xmalloc
Old name of ruby_xmalloc.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define ASSUME
Old name of RBIMPL_ASSUME.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
#define FL_SET
Old name of RB_FL_SET.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define FL_USER2
Old name of RUBY_FL_USER2.
#define Qtrue
Old name of RUBY_Qtrue.
#define INT2NUM
Old name of RB_INT2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define T_OBJECT
Old name of RUBY_T_OBJECT.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define FL_TEST
Old name of RB_FL_TEST.
#define FL_UNSET
Old name of RB_FL_UNSET.
#define rb_ary_new2
Old name of rb_ary_new_capa.
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Identical to rb_typeddata_is_kind_of(), except it raises exceptions instead of returning false.
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
void rb_raise(VALUE exc_class, const char *fmt,...)
Exception entry point.
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Identical to rb_compile_warning(), except it reports unless $VERBOSE is nil.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
void rb_name_error(ID id, const char *fmt,...)
Raises an instance of rb_eNameError.
VALUE rb_eTypeError
TypeError exception.
void rb_name_error_str(VALUE str, const char *fmt,...)
Identical to rb_name_error(), except it takes a VALUE instead of ID.
VALUE rb_eNameError
NameError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_eArgError
ArgumentError exception.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
void rb_warning(const char *fmt,...)
Issues a warning.
@ RB_WARN_CATEGORY_DEPRECATED
Warning is for deprecated features.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_cModule
Module class.
VALUE rb_class_real(VALUE klass)
Finds a "real" class.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
rb_encoding * rb_usascii_encoding(void)
Queries the encoding that represents US-ASCII.
static bool rb_enc_asciicompat(rb_encoding *enc)
Queries if the passed encoding is in some sense compatible with ASCII.
rb_encoding * rb_enc_get(VALUE obj)
Identical to rb_enc_get_index(), except the return type.
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
Identical to rb_check_id(), except it takes a pointer to a memory region instead of Ruby's string.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
void rb_mark_tbl_no_pin(struct st_table *tbl)
Identical to rb_mark_tbl(), except it marks objects using rb_gc_mark_movable().
void rb_gc_mark_movable(VALUE obj)
Maybe this is the only function provided for C extensions to control the pinning of objects,...
void rb_gc_mark_maybe(VALUE obj)
Identical to rb_gc_mark(), except it allows the passed value be a non-object.
VALUE rb_gc_location(VALUE obj)
Finds a new "location" of an object.
void rb_gc_update_tbl_refs(st_table *ptr)
Updates references inside of tables.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
ID rb_frame_callee(void)
Identical to rb_frame_this_func(), except it returns the named used to call the method.
#define st_foreach_safe
Just another name of rb_st_foreach_safe.
VALUE rb_hash_delete(VALUE hash, VALUE key)
Deletes the passed key from the passed hash table, if any.
VALUE rb_hash_aref(VALUE hash, VALUE key)
Queries the given key in the given hash table.
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Inserts or replaces ("upsert"s) the objects into the given hash table.
int rb_feature_provided(const char *feature, const char **loading)
Identical to rb_provided(), except it additionally returns the "canonical" name of the loaded feature...
VALUE rb_backref_get(void)
Queries the last match, or Regexp.last_match, or the $~.
int rb_is_instance_id(ID id)
Classifies the given ID, then sees if it is an instance variable.
int rb_is_const_id(ID id)
Classifies the given ID, then sees if it is a constant.
int rb_is_class_id(ID id)
Classifies the given ID, then sees if it is a class variable.
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
VALUE rb_reg_nth_defined(int n, VALUE md)
Identical to rb_reg_nth_match(), except it just returns Boolean.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_str_subseq(VALUE str, long beg, long len)
Identical to rb_str_substr(), except the numbers are interpreted as byte offsets instead of character...
VALUE rb_str_new_frozen(VALUE str)
Creates a frozen copy of the string, if necessary.
VALUE rb_str_cat2(VALUE, const char *)
Just another name of rb_str_cat_cstr.
VALUE rb_str_dup(VALUE str)
Duplicates a string.
VALUE rb_str_new_cstr(const char *ptr)
Identical to rb_str_new(), except it assumes the passed pointer is a pointer to a C string.
VALUE rb_str_intern(VALUE str)
Identical to rb_to_symbol(), except it assumes the receiver being an instance of RString.
VALUE rb_mutex_new(void)
Creates a mutex.
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
Obtains the lock, runs the passed function, and releases the lock when it completes.
VALUE rb_mod_remove_cvar(VALUE mod, VALUE name)
Resembles Module#remove_class_variable.
VALUE rb_obj_instance_variables(VALUE obj)
Resembles Object#instance_variables.
VALUE rb_f_untrace_var(int argc, const VALUE *argv)
Deletes the passed tracer from the passed global variable, or if omitted, deletes everything.
VALUE rb_const_get(VALUE space, ID name)
Identical to rb_const_defined(), except it returns the actual defined value.
VALUE rb_const_list(void *)
This is another mysterious API that comes with no documents at all.
VALUE rb_path2class(const char *path)
Resolves a Q::W::E::R-style path string to the actual class it points.
VALUE rb_autoload_p(VALUE space, ID name)
Queries if an autoload is defined at a point.
VALUE rb_attr_get(VALUE obj, ID name)
Identical to rb_ivar_get()
void rb_set_class_path(VALUE klass, VALUE space, const char *name)
Names a class.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
VALUE rb_mod_remove_const(VALUE space, VALUE name)
Resembles Module#remove_const.
VALUE rb_class_path_cached(VALUE mod)
Just another name of rb_mod_name.
VALUE rb_f_trace_var(int argc, const VALUE *argv)
Traces a global variable.
void * rb_mod_const_at(VALUE, void *)
This API is mysterious.
void rb_cvar_set(VALUE klass, ID name, VALUE val)
Assigns a value to a class variable.
VALUE rb_cvar_get(VALUE klass, ID name)
Obtains a value from a class variable.
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv)
Resembles Module#constants.
VALUE rb_cvar_find(VALUE klass, ID name, VALUE *front)
Identical to rb_cvar_get(), except it takes additional "front" pointer.
VALUE rb_path_to_class(VALUE path)
Identical to rb_path2class(), except it accepts the path as Ruby's string instead of C's.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
void rb_ivar_foreach(VALUE obj, int(*func)(ID name, VALUE val, st_data_t arg), st_data_t arg)
Iterates over an object's instance variables.
void rb_const_set(VALUE space, ID name, VALUE val)
Names a constant.
VALUE rb_autoload_load(VALUE space, ID name)
Kicks the autoload procedure as if it was "touched".
VALUE rb_mod_name(VALUE mod)
Queries the name of a module.
VALUE rb_class_name(VALUE obj)
Queries the name of the given object's class.
VALUE rb_const_get_at(VALUE space, ID name)
Identical to rb_const_defined_at(), except it returns the actual defined value.
void rb_set_class_path_string(VALUE klass, VALUE space, VALUE name)
Identical to rb_set_class_path(), except it accepts the name as Ruby's string instead of C's.
void rb_alias_variable(ID dst, ID src)
Aliases a global variable.
void rb_define_class_variable(VALUE, const char *, VALUE)
Just another name of rb_cv_set.
VALUE rb_obj_remove_instance_variable(VALUE obj, VALUE name)
Resembles Object#remove_instance_variable.
st_index_t rb_ivar_count(VALUE obj)
Number of instance variables defined on an object.
VALUE rb_const_remove(VALUE space, ID name)
Identical to rb_mod_remove_const(), except it takes the name as ID instead of VALUE.
VALUE rb_const_get_from(VALUE space, ID name)
Identical to rb_const_defined_at(), except it returns the actual defined value.
VALUE rb_ivar_defined(VALUE obj, ID name)
Queries if the instance variable is defined at the object.
VALUE rb_cv_get(VALUE klass, const char *name)
Identical to rb_cvar_get(), except it accepts C's string instead of ID.
int rb_const_defined_at(VALUE space, ID name)
Identical to rb_const_defined(), except it doesn't look for parent classes.
void rb_cv_set(VALUE klass, const char *name, VALUE val)
Identical to rb_cvar_set(), except it accepts C's string instead of ID.
VALUE rb_mod_class_variables(int argc, const VALUE *argv, VALUE recv)
Resembles Module#class_variables.
VALUE rb_f_global_variables(void)
Queries the list of global variables.
VALUE rb_cvar_defined(VALUE klass, ID name)
Queries if the given class has the given class variable.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
int rb_const_defined_from(VALUE space, ID name)
Identical to rb_const_defined(), except it returns false for private constants.
void * rb_mod_const_of(VALUE, void *)
This is a variant of rb_mod_const_at().
int rb_const_defined(VALUE space, ID name)
Queries if the constant is defined at the namespace.
void rb_free_generic_ivar(VALUE obj)
Frees the list of instance variables.
const char * rb_sourcefile(void)
Resembles __FILE__.
void rb_clear_constant_cache_for_id(ID id)
Clears the inline constant caches associated with a particular ID.
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat)
This API is practically a variant of rb_proc_call_kw() now.
ID rb_intern2(const char *name, long len)
Identical to rb_intern(), except it additionally takes the length of the string.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
ID rb_check_id(volatile VALUE *namep)
Detects if the given name is already interned or not.
const char * rb_id2name(ID id)
Retrieves the name mapped to the given id.
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
ID rb_to_id(VALUE str)
Identical to rb_intern(), except it takes an instance of rb_cString.
VALUE rb_id2str(ID id)
Identical to rb_id2name(), except it returns a frozen Ruby String instead of a C String.
rb_gvar_setter_t rb_gvar_var_setter
rb_gvar_marker_t rb_gvar_var_marker
void rb_define_global_const(const char *name, VALUE val)
Identical to rb_define_const(), except it defines that of "global", i.e.
VALUE rb_gv_get(const char *name)
Obtains a global variable.
void rb_define_variable(const char *name, VALUE *var)
"Shares" a global variable between Ruby and C.
void rb_gvar_marker_t(VALUE *var)
Type that represents a global variable marker function.
void rb_deprecate_constant(VALUE mod, const char *name)
Asserts that the given constant is deprecated.
void rb_gvar_setter_t(VALUE val, ID id, VALUE *data)
Type that represents a global variable setter function.
rb_gvar_setter_t rb_gvar_val_setter
This is the setter function that backs global variables defined from a ruby script.
rb_gvar_marker_t rb_gvar_undef_marker
void rb_define_readonly_variable(const char *name, const VALUE *var)
Identical to rb_define_variable(), except it does not allow Ruby programs to assign values to such gl...
rb_gvar_setter_t rb_gvar_readonly_setter
This function just raises rb_eNameError.
rb_gvar_getter_t rb_gvar_undef_getter
VALUE rb_gv_set(const char *name, VALUE val)
Assigns to a global variable.
rb_gvar_marker_t rb_gvar_val_marker
This is the setter function that backs global variables defined from a ruby script.
void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter)
Defines a global variable that is purely function-backended.
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
VALUE rb_gvar_getter_t(ID id, VALUE *data)
Type that represents a global variable getter function.
VALUE rb_iv_get(VALUE obj, const char *name)
Obtains an instance variable.
rb_gvar_setter_t rb_gvar_undef_setter
rb_gvar_getter_t rb_gvar_val_getter
This is the getter function that backs global variables defined from a ruby script.
VALUE rb_iv_set(VALUE obj, const char *name, VALUE val)
Assigns to an instance variable.
void rb_define_hooked_variable(const char *name, VALUE *var, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter)
Identical to rb_define_virtual_variable(), but can also specify a storage.
rb_gvar_getter_t rb_gvar_var_getter
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
int len
Length of the buffer.
static bool rb_ractor_shareable_p(VALUE obj)
Queries if multiple Ractors can share the passed object or not.
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE type(ANYARGS)
ANYARGS-ed function type.
void rb_copy_generic_ivar(VALUE clone, VALUE obj)
Copies the list of instance variables.
static VALUE RBASIC_CLASS(VALUE obj)
Queries the class of an object.
#define RBASIC(obj)
Convenient casting macro.
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
#define ROBJECT(obj)
Convenient casting macro.
static VALUE * ROBJECT_IVPTR(VALUE obj)
Queries the instance variables.
#define StringValue(v)
Ensures that the parameter object is a String.
static char * RSTRING_END(VALUE str)
Queries the end of the contents pointer of the string.
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
#define RTYPEDDATA_DATA(v)
Convenient getter macro.
#define TypedData_Wrap_Struct(klass, data_type, sval)
Converts sval, a pointer to your struct, into a Ruby object.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
const char * rb_class2name(VALUE klass)
Queries the name of the passed class.
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
#define RB_NO_KEYWORDS
Do not pass keywords.
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
This is the struct that holds necessary info for a struct.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static enum ruby_value_type rb_type(VALUE obj)
Identical to RB_BUILTIN_TYPE(), except it can also accept special constants.
static enum ruby_value_type RB_BUILTIN_TYPE(VALUE obj)
Queries the type of the object.
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
void ruby_xfree(void *ptr)
Deallocates a storage instance.