Ruby 4.1.0dev (2026-08-28 revision 5eb9a6925b805a17dced976d5b741afe5086aab1)
class.c (5eb9a6925b805a17dced976d5b741afe5086aab1)
1/**********************************************************************
2
3 class.c -
4
5 $Author$
6 created at: Tue Aug 10 15:05:44 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
17#include "ruby/internal/config.h"
18#include <ctype.h>
19
20#include "constant.h"
21#include "debug_counter.h"
22#include "id_table.h"
23#include "internal.h"
24#include "internal/box.h"
25#include "internal/class.h"
26#include "internal/eval.h"
27#include "internal/hash.h"
28#include "internal/object.h"
29#include "internal/string.h"
30#include "internal/variable.h"
31#include "ruby/st.h"
32#include "vm_core.h"
33#include "ruby/ractor.h"
34#include "yjit.h"
35#include "zjit.h"
36
37/* Flags of T_CLASS
38 *
39 * 0: RCLASS_IS_ROOT
40 * The class has been added to the VM roots. Will always be marked and pinned.
41 * This is done for classes defined from C to allow storing them in global variables.
42 * 1: RUBY_FL_SINGLETON
43 * This class is a singleton class.
44 * 2: RCLASS_PRIME_CLASSEXT_WRITABLE
45 * This class's prime classext is the only classext and writable from any boxes.
46 * If unset, the prime classext is writable only from the root box.
47 * 3: RCLASS_IS_INITIALIZED
48 * Class has been initialized.
49 * 4: RCLASS_BOXABLE
50 * Is a builtin class that may be boxed. It larger than a normal class.
51 */
52
53/* Flags of T_ICLASS
54 *
55 * 2: RCLASS_PRIME_CLASSEXT_WRITABLE
56 * This module's prime classext is the only classext and writable from any boxes.
57 * If unset, the prime classext is writable only from the root box.
58 * 4: RCLASS_BOXABLE
59 * Is a builtin class that may be boxed. It larger than a normal class.
60 */
61
62/* Flags of T_MODULE
63 *
64 * 0: RCLASS_IS_ROOT
65 * The class has been added to the VM roots. Will always be marked and pinned.
66 * This is done for classes defined from C to allow storing them in global variables.
67 * 1: <reserved>
68 * Ensures that RUBY_FL_SINGLETON is never set on a T_MODULE. See `rb_class_real`.
69 * 2: RCLASS_PRIME_CLASSEXT_WRITABLE
70 * This module's prime classext is the only classext and writable from any boxes.
71 * If unset, the prime classext is writable only from the root box.
72 * 3: RCLASS_IS_INITIALIZED
73 * Module has been initialized.
74 * 4: RCLASS_BOXABLE
75 * Is a builtin class that may be boxed. It larger than a normal class.
76 * 5: RMODULE_IS_REFINEMENT
77 * Module is used for refinements.
78 */
79
80#define METACLASS_OF(k) RBASIC(k)->klass
81#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
82
84rb_class_unlink_classext(VALUE klass, const rb_box_t *box)
85{
86 st_data_t ext;
87 st_data_t key = (st_data_t)box->box_object;
88 st_delete(box->classext_cow_classes, &klass, 0);
89 st_delete(RCLASS_CLASSEXT_TBL(klass), &key, &ext);
90 return (rb_classext_t *)ext;
91}
92
93void
94rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime)
95{
96 struct rb_id_table *tbl;
97
98 rb_id_table_free(RCLASSEXT_M_TBL(ext));
99
100 if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
101 rb_free_const_table(tbl);
102 }
103
104 if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
105 RUBY_ASSERT(is_prime); // superclasses should only be used on prime
106 size_t depth = RCLASSEXT_SUPERCLASS_DEPTH(ext);
107 if (depth != RCLASS_MAX_SUPERCLASS_DEPTH) {
108 depth++;
109 }
110 SIZED_FREE_N(RCLASSEXT_SUPERCLASSES(ext), depth);
111 }
112
113 if (!is_prime) { // the prime classext will be freed with RClass
114 SIZED_FREE(ext);
115 }
116}
117
118void
119rb_iclass_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime)
120{
121 if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
122 /* Method table is not shared for origin iclasses of classes */
123 rb_id_table_free(RCLASSEXT_M_TBL(ext));
124 }
125
126 if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
127 rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
128 }
129
130 if (!is_prime) { // the prime classext will be freed with RClass
131 SIZED_FREE(ext);
132 }
133}
134
135static void
136iclass_free_orphan_classext(VALUE klass, rb_classext_t *ext)
137{
138 if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
139 /* Method table is not shared for origin iclasses of classes */
140 rb_id_table_free(RCLASSEXT_M_TBL(ext));
141 }
142
143 if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
144 rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
145 }
146
147 SIZED_FREE(ext);
148}
149
151 VALUE obj;
152 rb_classext_t *ext;
153};
154
155static int
156set_box_classext_update(st_data_t *key_ptr, st_data_t *val_ptr, st_data_t a, int existing)
157{
159
160 if (existing) {
161 if (LIKELY(BUILTIN_TYPE(args->obj) == T_ICLASS)) {
162 iclass_free_orphan_classext(args->obj, (rb_classext_t *)*val_ptr);
163 }
164 else {
165 rb_bug("Updating existing classext for non-iclass never happen");
166 }
167 }
168
169 *val_ptr = (st_data_t)args->ext;
170
171 return ST_CONTINUE;
172}
173
174void
175rb_class_set_box_classext(VALUE obj, const rb_box_t *box, rb_classext_t *ext)
176{
177 struct rb_class_set_box_classext_args args = {
178 .obj = obj,
179 .ext = ext,
180 };
181
182 VM_ASSERT(BOX_MUTABLE_P(box));
183
184 st_update(RCLASS_CLASSEXT_TBL(obj), (st_data_t)box->box_object, set_box_classext_update, (st_data_t)&args);
185
186 // The classext references are now visible via the classext table,
187 // so we must issue the write barrier before any further allocations
188 // (e.g. st_insert below) that could trigger GC.
189 rb_gc_writebarrier_remember(obj);
190
191 st_insert(box->classext_cow_classes, (st_data_t)obj, 0);
192}
193
194RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
195
197 struct rb_id_table *tbl;
198 VALUE klass;
199};
200
201static enum rb_id_table_iterator_result
202duplicate_classext_m_tbl_i(ID key, VALUE value, void *data)
203{
204 struct duplicate_id_tbl_data *arg = (struct duplicate_id_tbl_data *)data;
206 rb_method_table_insert0(arg->klass, arg->tbl, key, me, false);
207 return ID_TABLE_CONTINUE;
208}
209
210static struct rb_id_table *
211duplicate_classext_m_tbl(struct rb_id_table *orig, VALUE klass, bool init_missing)
212{
213 struct rb_id_table *tbl;
214 if (!orig) {
215 if (init_missing)
216 return rb_id_table_create(0);
217 else
218 return NULL;
219 }
220 tbl = rb_id_table_create(rb_id_table_size(orig));
221 struct duplicate_id_tbl_data data = {
222 .tbl = tbl,
223 .klass = klass,
224 };
225 rb_id_table_foreach(orig, duplicate_classext_m_tbl_i, &data);
226 return tbl;
227}
228
229static rb_const_entry_t *
230duplicate_classext_const_entry(rb_const_entry_t *src, VALUE klass)
231{
232 // See also: setup_const_entry (variable.c)
234
235 dst->flag = src->flag;
236 dst->line = src->line;
237 RB_OBJ_WRITE(klass, &dst->value, src->value);
238 RB_OBJ_WRITE(klass, &dst->file, src->file);
239
240 return dst;
241}
242
243static enum rb_id_table_iterator_result
244duplicate_classext_const_tbl_i(ID key, VALUE value, void *data)
245{
246 struct duplicate_id_tbl_data *arg = (struct duplicate_id_tbl_data *)data;
247 rb_const_entry_t *entry = duplicate_classext_const_entry((rb_const_entry_t *)value, arg->klass);
248
249 rb_id_table_insert(arg->tbl, key, (VALUE)entry);
250
251 return ID_TABLE_CONTINUE;
252}
253
254static struct rb_id_table *
255duplicate_classext_const_tbl(struct rb_id_table *src, VALUE klass)
256{
257 struct rb_id_table *dst;
258
259 if (!src)
260 return NULL;
261
262 dst = rb_id_table_create(rb_id_table_size(src));
263
264 struct duplicate_id_tbl_data data = {
265 .tbl = dst,
266 .klass = klass,
267 };
268 rb_id_table_foreach(src, duplicate_classext_const_tbl_i, (void *)&data);
269
270 return dst;
271}
272
273static void
274class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_box_t *box)
275{
277
278 rb_classext_t *src = RCLASS_EXT_PRIME(iclass);
279 rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(iclass, box);
280 int first_set = 0;
281
282 if (ext) {
283 // iclass classext for the ns is only for cc/callable_m_tbl if it's created earlier than module's one
284 rb_invalidate_method_caches(RCLASSEXT_CALLABLE_M_TBL(ext), RCLASSEXT_CC_TBL(ext));
285 }
286
287 ext = ZALLOC(rb_classext_t);
288
289 RCLASSEXT_BOX(ext) = box;
290
291 RCLASSEXT_SUPER(ext) = RCLASSEXT_SUPER(src);
292
293 // See also: rb_include_class_new()
294 if (RCLASSEXT_ICLASS_IS_ORIGIN(src) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(src)) {
295 RCLASSEXT_M_TBL(ext) = duplicate_classext_m_tbl(RCLASSEXT_M_TBL(src), iclass, true);
296 }
297 else {
298 RCLASSEXT_M_TBL(ext) = RCLASSEXT_M_TBL(mod_ext);
299 }
300
301 RCLASSEXT_CONST_TBL(ext) = RCLASSEXT_CONST_TBL(mod_ext);
302 RCLASSEXT_CVC_TBL(ext) = RCLASSEXT_CVC_TBL(mod_ext);
303
304 // Those are cache and should be recreated when methods are called
305 // RCLASSEXT_CALLABLE_M_TBL(ext) = NULL;
306 // RCLASSEXT_CC_TBL(ext) = NULL;
307
308 // Subclasses/back-pointers are only in the prime classext.
309
310 RCLASSEXT_SET_ORIGIN(ext, iclass, RCLASSEXT_ORIGIN(src));
311 RCLASSEXT_ICLASS_IS_ORIGIN(ext) = RCLASSEXT_ICLASS_IS_ORIGIN(src);
312 RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) = RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(src);
313
314 RCLASSEXT_SET_INCLUDER(ext, iclass, RCLASSEXT_INCLUDER(src));
315
316 VM_ASSERT(FL_TEST_RAW(iclass, RCLASS_BOXABLE));
317
318 first_set = RCLASS_SET_BOX_CLASSEXT(iclass, box, ext);
319 if (first_set) {
320 RCLASS_SET_PRIME_CLASSEXT_WRITABLE(iclass, false);
321 }
322}
323
325rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_box_t *box)
326{
327 VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
328
330 bool dup_iclass = RB_TYPE_P(klass, T_MODULE) ? true : false;
331
332 RCLASSEXT_BOX(ext) = box;
333
334 RCLASSEXT_SUPER(ext) = RCLASSEXT_SUPER(orig);
335
336 RCLASSEXT_M_TBL(ext) = duplicate_classext_m_tbl(RCLASSEXT_M_TBL(orig), klass, dup_iclass);
337 RCLASSEXT_ICLASS_IS_ORIGIN(ext) = true;
338 RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) = false;
339
340 if (orig->fields_obj) {
341 RB_OBJ_WRITE(klass, &ext->fields_obj, rb_imemo_fields_clone(orig->fields_obj));
342 }
343
344 if (RCLASSEXT_SHARED_CONST_TBL(orig)) {
345 RCLASSEXT_CONST_TBL(ext) = RCLASSEXT_CONST_TBL(orig);
346 RCLASSEXT_SHARED_CONST_TBL(ext) = true;
347 }
348 else {
349 RCLASSEXT_CONST_TBL(ext) = duplicate_classext_const_tbl(RCLASSEXT_CONST_TBL(orig), klass);
350 RCLASSEXT_SHARED_CONST_TBL(ext) = false;
351 }
352 /*
353 * callable_m_tbl is for `super` chain, and entries will be created when the super chain is called.
354 * so initially, it can be NULL and let it be created lazily.
355 * RCLASSEXT_CALLABLE_M_TBL(ext) = NULL;
356 *
357 * cc_tbl is for method inline cache, and method calls from different boxes never occur on
358 * the same code, so the copied classext should have a different cc_tbl from the prime one.
359 * RCLASSEXT_CC_TBL(copy) = NULL
360 */
361
362 VALUE cvc_table = RCLASSEXT_CVC_TBL(orig);
363 if (cvc_table) {
364 cvc_table = rb_marked_id_table_dup(cvc_table);
365 }
366 else if (dup_iclass) {
367 cvc_table = rb_marked_id_table_new(2);
368 }
369 RB_OBJ_WRITE(klass, &RCLASSEXT_CVC_TBL(ext), cvc_table);
370
371 // Subclasses/back-pointers are only in the prime classext.
372
373 RCLASSEXT_SET_ORIGIN(ext, klass, RCLASSEXT_ORIGIN(orig));
374 /*
375 * Members not copied to box's classext values
376 * * refined_class
377 * * as.class.allocator / as.singleton_class.attached_object
378 * * includer
379 * * max IV count
380 * * variation count
381 */
382 RCLASSEXT_PERMANENT_CLASSPATH(ext) = RCLASSEXT_PERMANENT_CLASSPATH(orig);
383 RCLASSEXT_CLASSPATH(ext) = RCLASSEXT_CLASSPATH(orig);
384
385 /* For the usual T_CLASS/T_MODULE, iclass flags are always false */
386
387 if (dup_iclass) {
388 /*
389 * ICLASS has the same m_tbl/const_tbl/cvc_tbl with the included module.
390 * So the module's classext is copied, its tables should be also referred
391 * by the ICLASS's classext for the box.
392 *
393 * Subclasses are only in the prime classext, so read from orig.
394 */
395 VALUE subs_v = RCLASSEXT_SUBCLASSES(orig);
396 if (subs_v) {
397 struct rb_subclasses *subs = (struct rb_subclasses *)subs_v;
398 VALUE *entries = rb_imemo_subclasses_entries(subs_v);
399 for (uint32_t i = 0; i < subs->count; i++) {
400 VALUE iclass = entries[i];
401 if (!iclass) continue;
402
403 /* every node in the subclass list should be an ICLASS built from this module */
404 VM_ASSERT(RB_TYPE_P(iclass, T_ICLASS));
405 VM_ASSERT(RBASIC_CLASS(iclass) == klass);
406
407 if (FL_TEST_RAW(iclass, RCLASS_BOXABLE)) {
408 // Non-boxable ICLASSes (included by classes in main/user boxes) can't
409 // hold per-box classexts, and their includer classes also can't, so
410 // method lookup through them always uses the prime classext.
411 class_duplicate_iclass_classext(iclass, ext, box);
412 }
413 }
414 }
415 }
416
417 return ext;
418}
419
420void
421rb_class_ensure_writable(VALUE klass)
422{
423 VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
424 RCLASS_EXT_WRITABLE(klass);
425}
426
428 rb_class_classext_foreach_callback_func *func;
429 void * callback_arg;
430};
431
432static int
433class_classext_foreach_i(st_data_t key, st_data_t value, st_data_t arg)
434{
436 rb_class_classext_foreach_callback_func *func = foreach_arg->func;
437 func((rb_classext_t *)value, false, (VALUE)key, foreach_arg->callback_arg);
438 return ST_CONTINUE;
439}
440
441void
442rb_class_classext_foreach(VALUE klass, rb_class_classext_foreach_callback_func *func, void *arg)
443{
444 st_table *tbl = RCLASS_CLASSEXT_TBL(klass);
446 if (tbl) {
447 foreach_arg.func = func;
448 foreach_arg.callback_arg = arg;
449 rb_st_foreach(tbl, class_classext_foreach_i, (st_data_t)&foreach_arg);
450 }
451 func(RCLASS_EXT_PRIME(klass), true, (VALUE)NULL, arg);
452}
453
454VALUE
456{
457 return RCLASS_SUPER(klass);
458}
459
460VALUE
461rb_class_singleton_p(VALUE klass)
462{
463 return RCLASS_SINGLETON_P(klass);
464}
465
466unsigned char
467rb_class_variation_count(VALUE klass)
468{
469 return RCLASS_VARIATION_COUNT(klass);
470}
471
472static void
473push_subclass_entry_to_list(VALUE super, VALUE klass)
474{
476 (RB_TYPE_P(super, T_MODULE) && RB_TYPE_P(klass, T_ICLASS)) ||
477 (RB_TYPE_P(super, T_CLASS) && RB_TYPE_P(klass, T_CLASS)) ||
478 (RB_TYPE_P(klass, T_ICLASS) && !NIL_P(RCLASS_REFINED_CLASS(klass)))
479 );
480
481 RB_VM_LOCKING() {
482 VALUE subs_v = RCLASS_SUBCLASSES(super);
483 struct rb_subclasses *subs = (struct rb_subclasses *)subs_v;
484
485 if (!subs || subs->count == subs->capacity) {
486 VALUE *old_entries = subs ? rb_imemo_subclasses_entries(subs_v) : NULL;
487 uint32_t live = 0;
488 for (uint32_t i = 0; subs && i < subs->count; i++) {
489 if (old_entries[i]) live++;
490 }
491
492 uint32_t cap = subs ? subs->capacity : 2;
493 if (live * 2 >= cap) cap *= 2;
494
495 VALUE new_v = rb_imemo_subclasses_new(cap);
496 struct rb_subclasses *new_subs = (struct rb_subclasses *)new_v;
497 VALUE *new_entries = rb_imemo_subclasses_entries(new_v);
498 for (uint32_t i = 0; subs && i < subs->count; i++) {
499 VALUE entry = old_entries[i];
500 if (entry) {
501 new_entries[new_subs->count++] = entry;
502 RB_OBJ_WRITTEN(new_v, Qundef, entry);
503 }
504 }
505 RCLASS_SET_SUBCLASSES(super, new_v);
506 subs_v = new_v;
507 subs = new_subs;
508 }
509
510 rb_imemo_subclasses_entries(subs_v)[subs->count++] = klass;
511 RB_OBJ_WRITTEN(subs_v, Qundef, klass);
512 }
513}
514
515void
516rb_class_subclass_add(VALUE super, VALUE klass)
517{
518 if (super && !UNDEF_P(super)) {
519 RUBY_ASSERT(RB_TYPE_P(super, T_CLASS) || RB_TYPE_P(super, T_MODULE));
520 RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
521 push_subclass_entry_to_list(super, klass);
522 }
523}
524
525static void
526rb_module_add_to_subclasses_list(VALUE module, VALUE iclass)
527{
528 if (module && !UNDEF_P(module)) {
531 push_subclass_entry_to_list(module, iclass);
532 }
533}
534
535void
536rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE arg)
537{
538 VALUE subs_v = RCLASS_SUBCLASSES(klass);
539 if (!subs_v) return;
540
541 struct rb_subclasses *subs = (struct rb_subclasses *)subs_v;
542 VALUE *entries = rb_imemo_subclasses_entries(subs_v);
543 for (uint32_t i = 0; i < subs->count; i++) {
544 VALUE curklass = entries[i];
545 if (curklass) {
546 f(curklass, arg);
547 }
548 }
549}
550
551static void
552class_switch_superclass(VALUE super, VALUE klass)
553{
554 // No need to remove from old super's subclasses list — the GC
555 // will nullify the weak reference when appropriate.
556 rb_class_subclass_add(super, klass);
557}
558
569static VALUE
570class_alloc0(enum ruby_value_type type, VALUE klass, bool boxable)
571{
572 const rb_box_t *box = rb_current_box();
573
574 if (!ruby_box_init_done) {
575 boxable = true;
576 }
577
578 size_t alloc_size = sizeof(struct RClass_and_rb_classext_t);
579 if (boxable) {
580 alloc_size = sizeof(struct RClass_boxable);
581 }
582
584
585 VALUE flags = type | FL_SHAREABLE;
586 if (boxable) flags |= RCLASS_BOXABLE;
587
588 shape_id_t shape_id = ROOT_SHAPE_ID;
589 if (boxable) {
590 shape_id |= SHAPE_ID_LAYOUT_OTHER;
591 }
592 else {
593 shape_id |= SHAPE_ID_LAYOUT_RCLASS;
594 }
595
596 struct RClass *obj = (struct RClass *)rb_newobj(GET_EC(), klass, flags, shape_id, true, alloc_size);
597
598 obj->object_id = 0;
599
600 memset(RCLASS_EXT_PRIME(obj), 0, sizeof(rb_classext_t));
601
602 /* ZALLOC
603 RCLASS_CONST_TBL(obj) = 0;
604 RCLASS_M_TBL(obj) = 0;
605 RCLASS_FIELDS(obj) = 0;
606 RCLASS_SET_SUPER((VALUE)obj, 0);
607 */
608
609 if (boxable) {
610 ((struct RClass_boxable *)obj)->box_classext_tbl = NULL;
611 }
612
613 RCLASS_PRIME_BOX((VALUE)obj) = box;
614 // Classes/Modules defined in user boxes are
615 // writable directly because it exists only in a box.
616 RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, !boxable || BOX_USER_P(box));
617
618 RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
619 RCLASS_SET_REFINED_CLASS((VALUE)obj, Qnil);
620
621 return (VALUE)obj;
622}
623
624static VALUE
625class_alloc(enum ruby_value_type type, VALUE klass)
626{
627 bool boxable = rb_box_available() && BOX_MASTER_P(rb_current_box());
628 return class_alloc0(type, klass, boxable);
629}
630
631static VALUE
632class_associate_super(VALUE klass, VALUE super, bool init)
633{
634 if (super && !UNDEF_P(super)) {
635 // Only maintain subclass lists for T_CLASS→T_CLASS relationships.
636 // Include/prepend inserts ICLASSes into the super chain, but T_CLASS
637 // subclass lists should track only the immutable T_CLASS→T_CLASS link.
638 if (RB_TYPE_P(klass, T_CLASS) && RB_TYPE_P(super, T_CLASS)) {
639 if (RCLASS_SINGLETON_P(klass)) {
640 // Instead of adding singleton classes to the subclass list,
641 // just set a flag so that method cache invalidation takes the
642 // tree path.
643 FL_SET_RAW(super, RCLASS_HAS_SUBCLASSES);
644 }
645 else {
646 class_switch_superclass(super, klass);
647 }
648 }
649 }
650 if (init) {
651 RCLASS_SET_SUPER(klass, super);
652 }
653 else {
654 RCLASS_WRITE_SUPER(klass, super);
655 }
656 rb_class_update_superclasses(klass);
657 return super;
658}
659
660VALUE
661rb_class_set_super(VALUE klass, VALUE super)
662{
663 return class_associate_super(klass, super, false);
664}
665
666static void
667class_initialize_method_table(VALUE c)
668{
669 // initialize the prime classext m_tbl
670 RCLASS_SET_M_TBL(c, rb_id_table_create(0));
671}
672
673static void
674class_clear_method_table(VALUE c)
675{
676 RCLASS_WRITE_M_TBL(c, rb_id_table_create(0));
677}
678
679static VALUE
680class_boot_boxable(VALUE super, bool boxable)
681{
682 VALUE klass = class_alloc0(T_CLASS, rb_cClass, boxable);
683
684 // initialize method table prior to class_associate_super()
685 // because class_associate_super() may cause GC and promote klass
686 class_initialize_method_table(klass);
687
688 class_associate_super(klass, super, true);
689 if (super && !UNDEF_P(super)) {
690 RCLASS_SET_ALLOCATOR(klass, RCLASS_ALLOCATOR(super));
691 rb_class_set_initialized(klass);
692 }
693
694 return (VALUE)klass;
695}
696
706VALUE
708{
709 return class_boot_boxable(super, false);
710}
711
712static VALUE *
713class_superclasses_including_self(VALUE klass)
714{
715 if (RCLASS_SUPERCLASSES_WITH_SELF_P(klass))
716 return RCLASS_SUPERCLASSES(klass);
717
718 size_t depth = RCLASS_SUPERCLASS_DEPTH(klass);
719 VALUE *superclasses = xmalloc(sizeof(VALUE) * (depth + 1));
720 if (depth > 0)
721 memcpy(superclasses, RCLASS_SUPERCLASSES(klass), sizeof(VALUE) * depth);
722 superclasses[depth] = klass;
723
724 return superclasses;
725}
726
727void
728rb_class_update_superclasses(VALUE klass)
729{
730 VALUE *superclasses;
731 size_t super_depth;
732 VALUE super = RCLASS_SUPER(klass);
733
734 if (!RB_TYPE_P(klass, T_CLASS)) return;
735 if (UNDEF_P(super)) return;
736
737 // If the superclass array is already built
738 if (RCLASS_SUPERCLASSES(klass))
739 return;
740
741 // find the proper superclass
742 while (super != Qfalse && !RB_TYPE_P(super, T_CLASS)) {
743 super = RCLASS_SUPER(super);
744 }
745
746 // For BasicObject and uninitialized classes, depth=0 and ary=NULL
747 if (super == Qfalse)
748 return;
749
750 // Sometimes superclasses are set before the full ancestry tree is built
751 // This happens during metaclass construction
752 if (super != rb_cBasicObject && !RCLASS_SUPERCLASS_DEPTH(super)) {
753 rb_class_update_superclasses(super);
754
755 // If it is still unset we need to try later
756 if (!RCLASS_SUPERCLASS_DEPTH(super))
757 return;
758 }
759
760 super_depth = RCLASS_SUPERCLASS_DEPTH(super);
761 if (RCLASS_SUPERCLASSES_WITH_SELF_P(super)) {
762 superclasses = RCLASS_SUPERCLASSES(super);
763 }
764 else {
765 superclasses = class_superclasses_including_self(super);
766 RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true);
767 }
768
769 size_t depth = super_depth == RCLASS_MAX_SUPERCLASS_DEPTH ? super_depth : super_depth + 1;
770 RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false);
771}
772
773void
775{
776 if (!RB_TYPE_P(super, T_CLASS)) {
777 rb_raise(rb_eTypeError, "superclass must be an instance of Class (given an instance of %"PRIsVALUE")",
778 rb_obj_class(super));
779 }
780 if (RCLASS_SINGLETON_P(super)) {
781 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
782 }
783 if (super == rb_cClass) {
784 rb_raise(rb_eTypeError, "can't make subclass of Class");
785 }
786}
787
788VALUE
790{
791 Check_Type(super, T_CLASS);
793 VALUE klass = rb_class_boot(super);
794
795 RCLASS_SET_MAX_IV_COUNT(klass, RCLASS_MAX_IV_COUNT(super));
796 RUBY_ASSERT(getenv("RUBY_BOX") || RCLASS_PRIME_CLASSEXT_WRITABLE_P(klass));
797
798 return klass;
799}
800
801VALUE
802rb_class_s_alloc(VALUE klass)
803{
804 return rb_class_boot(0);
805}
806
807static void
808clone_method(VALUE new_klass, ID mid, const rb_method_entry_t *me)
809{
810 rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));
811}
812
814 VALUE new_klass;
815};
816
817static enum rb_id_table_iterator_result
818clone_method_i(ID key, VALUE value, void *data)
819{
820 const struct clone_method_arg *arg = (struct clone_method_arg *)data;
821 clone_method(arg->new_klass, key, (const rb_method_entry_t *)value);
822 return ID_TABLE_CONTINUE;
823}
824
826 VALUE klass;
827 struct rb_id_table *tbl;
828};
829
830static int
831clone_const(ID key, const rb_const_entry_t *ce, struct clone_const_arg *arg)
832{
834 MEMCPY(nce, ce, rb_const_entry_t, 1);
835 RB_OBJ_WRITTEN(arg->klass, Qundef, ce->value);
836 RB_OBJ_WRITTEN(arg->klass, Qundef, ce->file);
837
838 rb_id_table_insert(arg->tbl, key, (VALUE)nce);
839 return ID_TABLE_CONTINUE;
840}
841
842static enum rb_id_table_iterator_result
843clone_const_i(ID key, VALUE value, void *data)
844{
845 return clone_const(key, (const rb_const_entry_t *)value, data);
846}
847
848static void
849class_init_copy_check(VALUE clone, VALUE orig)
850{
851 if (orig == rb_cBasicObject) {
852 rb_raise(rb_eTypeError, "can't copy the root class");
853 }
854 if (RCLASS_INITIALIZED_P(clone)) {
855 rb_raise(rb_eTypeError, "already initialized class");
856 }
857 if (RCLASS_SINGLETON_P(orig)) {
858 rb_raise(rb_eTypeError, "can't copy singleton class");
859 }
860}
861
863 VALUE clone;
864 VALUE new_table;
865};
866
867static struct rb_cvar_class_tbl_entry *
868cvc_table_entry_alloc(void)
869{
870 return (struct rb_cvar_class_tbl_entry *)SHAREABLE_IMEMO_NEW(struct rb_cvar_class_tbl_entry, imemo_cvar_entry, 0);
871}
872
873static enum rb_id_table_iterator_result
874cvc_table_copy(ID id, VALUE val, void *data)
875{
876 struct cvc_table_copy_ctx *ctx = (struct cvc_table_copy_ctx *)data;
877 struct rb_cvar_class_tbl_entry * orig_entry;
878 orig_entry = (struct rb_cvar_class_tbl_entry *)val;
879
880 struct rb_cvar_class_tbl_entry *ent;
881
882 ent = cvc_table_entry_alloc();
883 RB_OBJ_WRITE((VALUE)ent, &ent->class_value, ctx->clone);
884 RB_OBJ_WRITE(ctx->clone, &ent->cref, orig_entry->cref);
885 ent->global_cvar_state = orig_entry->global_cvar_state;
886 rb_marked_id_table_insert(ctx->new_table, id, (VALUE)ent);
887
888 return ID_TABLE_CONTINUE;
889}
890
891static void
892copy_tables(VALUE clone, VALUE orig)
893{
894 if (RCLASS_CONST_TBL(clone)) {
895 rb_free_const_table(RCLASS_CONST_TBL(clone));
896 RCLASS_WRITE_CONST_TBL(clone, 0, false);
897 }
898 if (RCLASS_CVC_TBL(orig)) {
899 VALUE rb_cvc_tbl = RCLASS_CVC_TBL(orig);
900 VALUE rb_cvc_tbl_dup = rb_marked_id_table_new(rb_marked_id_table_size(rb_cvc_tbl));
901
902 struct cvc_table_copy_ctx ctx;
903 ctx.clone = clone;
904 ctx.new_table = rb_cvc_tbl_dup;
905 rb_marked_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx);
906 RCLASS_WRITE_CVC_TBL(clone, rb_cvc_tbl_dup);
907 }
908 rb_id_table_free(RCLASS_M_TBL(clone));
909 RCLASS_WRITE_M_TBL(clone, 0);
910 if (!RB_TYPE_P(clone, T_ICLASS)) {
911 rb_fields_tbl_copy(clone, orig);
912 }
913 if (RCLASS_CONST_TBL(orig)) {
914 struct clone_const_arg arg;
915 struct rb_id_table *const_tbl;
916 struct rb_id_table *orig_tbl = RCLASS_CONST_TBL(orig);
917 arg.tbl = const_tbl = rb_id_table_create(rb_id_table_size(orig_tbl));
918 arg.klass = clone;
919 rb_id_table_foreach(orig_tbl, clone_const_i, &arg);
920 RCLASS_WRITE_CONST_TBL(clone, const_tbl, false);
921 rb_gc_writebarrier_remember(clone);
922 }
923}
924
925static bool ensure_origin(VALUE klass);
926
927void
928rb_class_set_initialized(VALUE klass)
929{
930 RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE));
931 FL_SET_RAW(klass, RCLASS_IS_INITIALIZED);
932 /* no more re-initialization */
933}
934
935void
936rb_module_check_initializable(VALUE mod)
937{
938 if (RCLASS_INITIALIZED_P(mod)) {
939 rb_raise(rb_eTypeError, "already initialized module");
940 }
941}
942
943/* :nodoc: */
944VALUE
946{
947 /* Only class or module is valid here, but other classes may enter here and
948 * only hit an exception on the OBJ_INIT_COPY checks
949 */
950 switch (BUILTIN_TYPE(clone)) {
951 case T_CLASS:
952 class_init_copy_check(clone, orig);
953 break;
954 case T_MODULE:
955 rb_module_check_initializable(clone);
956 break;
957 default:
958 break;
959 }
960 if (!OBJ_INIT_COPY(clone, orig)) return clone;
961
963 RUBY_ASSERT(BUILTIN_TYPE(clone) == BUILTIN_TYPE(orig));
964
965 rb_class_set_initialized(clone);
966
967 if (!RCLASS_SINGLETON_P(CLASS_OF(clone))) {
968 RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
969 rb_singleton_class_attached(METACLASS_OF(clone), (VALUE)clone);
970 }
971 if (BUILTIN_TYPE(clone) == T_CLASS) {
972 RCLASS_SET_ALLOCATOR(clone, RCLASS_ALLOCATOR(orig));
973 }
974 copy_tables(clone, orig);
975 if (RCLASS_M_TBL(orig)) {
976 struct clone_method_arg arg;
977 arg.new_klass = clone;
978 class_initialize_method_table(clone);
979 rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
980 }
981
982 if (RCLASS_ORIGIN(orig) == orig) {
983 rb_class_set_super(clone, RCLASS_SUPER(orig));
984 }
985 else {
986 VALUE p = RCLASS_SUPER(orig);
987 VALUE orig_origin = RCLASS_ORIGIN(orig);
988 VALUE prev_clone_p = clone;
989 VALUE origin_stack = rb_ary_hidden_new(2);
990 VALUE origin[2];
991 VALUE clone_p = 0;
992 long origin_len;
993 int add_subclass;
994 VALUE clone_origin;
995
996 ensure_origin(clone);
997 clone_origin = RCLASS_ORIGIN(clone);
998
999 while (p && p != orig_origin) {
1000 if (BUILTIN_TYPE(p) != T_ICLASS) {
1001 rb_bug("non iclass between module/class and origin");
1002 }
1003 clone_p = class_alloc(T_ICLASS, METACLASS_OF(p));
1004 RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p));
1005 rb_class_set_super(prev_clone_p, clone_p);
1006 prev_clone_p = clone_p;
1007 RCLASS_SET_CONST_TBL(clone_p, RCLASS_CONST_TBL(p), false);
1008 RCLASS_SET_INCLUDER(clone_p, clone);
1009 add_subclass = TRUE;
1010 if (p != RCLASS_ORIGIN(p)) {
1011 origin[0] = clone_p;
1012 origin[1] = RCLASS_ORIGIN(p);
1013 rb_ary_cat(origin_stack, origin, 2);
1014 }
1015 else if ((origin_len = RARRAY_LEN(origin_stack)) > 1 &&
1016 RARRAY_AREF(origin_stack, origin_len - 1) == p) {
1017 RCLASS_WRITE_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p);
1018 RICLASS_WRITE_ORIGIN_SHARED_MTBL(clone_p);
1019 rb_ary_resize(origin_stack, origin_len);
1020 add_subclass = FALSE;
1021 }
1022 if (add_subclass) {
1023 rb_module_add_to_subclasses_list(METACLASS_OF(p), clone_p);
1024 }
1025 p = RCLASS_SUPER(p);
1026 }
1027
1028 if (p == orig_origin) {
1029 if (clone_p) {
1030 rb_class_set_super(clone_p, clone_origin);
1031 rb_class_set_super(clone_origin, RCLASS_SUPER(orig_origin));
1032 }
1033 copy_tables(clone_origin, orig_origin);
1034 if (RCLASS_M_TBL(orig_origin)) {
1035 struct clone_method_arg arg;
1036 arg.new_klass = clone;
1037 class_initialize_method_table(clone_origin);
1038 rb_id_table_foreach(RCLASS_M_TBL(orig_origin), clone_method_i, &arg);
1039 }
1040 }
1041 else {
1042 rb_bug("no origin for class that has origin");
1043 }
1044
1045 rb_class_update_superclasses(clone);
1046 }
1047
1048 if (RB_TYPE_P(clone, T_CLASS)) {
1049 VALUE super = RCLASS_SUPER(clone);
1050 if (super && RB_TYPE_P(super, T_ICLASS)) {
1051 class_switch_superclass(rb_class_superclass(clone), clone);
1052 }
1053 }
1054
1055 return clone;
1056}
1057
1058VALUE
1060{
1061 return rb_singleton_class_clone_and_attach(obj, Qundef);
1062}
1063
1064// Clone and return the singleton class of `obj` if it has been created and is attached to `obj`.
1065VALUE
1066rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
1067{
1068 const VALUE klass = METACLASS_OF(obj);
1069
1070 // Note that `rb_singleton_class()` can create situations where `klass` is
1071 // attached to an object other than `obj`. In which case `obj` does not have
1072 // a material singleton class attached yet and there is no singleton class
1073 // to clone.
1074 if (!(RCLASS_SINGLETON_P(klass) && RCLASS_ATTACHED_OBJECT(klass) == obj)) {
1075 // nothing to clone
1076 return klass;
1077 }
1078 else {
1079 /* copy singleton(unnamed) class */
1080 bool klass_of_clone_is_new;
1081 RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
1082 VALUE clone = class_alloc(T_CLASS, 0);
1083
1084 if (BUILTIN_TYPE(obj) == T_CLASS) {
1085 klass_of_clone_is_new = true;
1086 RBASIC_SET_CLASS(clone, clone);
1087 }
1088 else {
1089 VALUE klass_metaclass_clone = rb_singleton_class_clone(klass);
1090 // When `METACLASS_OF(klass) == klass_metaclass_clone`, it means the
1091 // recursive call did not clone `METACLASS_OF(klass)`.
1092 klass_of_clone_is_new = (METACLASS_OF(klass) != klass_metaclass_clone);
1093 RBASIC_SET_CLASS(clone, klass_metaclass_clone);
1094 }
1095
1096 // initialize method table before any GC chance
1097 class_initialize_method_table(clone);
1098
1099 rb_class_set_super(clone, RCLASS_SUPER(klass));
1100 rb_fields_tbl_copy(clone, klass);
1101 if (RCLASS_CONST_TBL(klass)) {
1102 struct clone_const_arg arg;
1103 struct rb_id_table *table;
1104 arg.tbl = table = rb_id_table_create(rb_id_table_size(RCLASS_CONST_TBL(klass)));
1105 arg.klass = clone;
1106 rb_id_table_foreach(RCLASS_CONST_TBL(klass), clone_const_i, &arg);
1107 RCLASS_SET_CONST_TBL(clone, table, false);
1108 }
1109 if (!UNDEF_P(attach)) {
1110 rb_singleton_class_attached(clone, attach);
1111 }
1112 {
1113 struct clone_method_arg arg;
1114 arg.new_klass = clone;
1115 rb_id_table_foreach(RCLASS_M_TBL(klass), clone_method_i, &arg);
1116 }
1117 if (klass_of_clone_is_new) {
1118 rb_singleton_class_attached(METACLASS_OF(clone), clone);
1119 }
1120 FL_SET(clone, FL_SINGLETON);
1121
1122 return clone;
1123 }
1124}
1125
1126void
1128{
1129 if (RCLASS_SINGLETON_P(klass)) {
1130 RCLASS_SET_ATTACHED_OBJECT(klass, obj);
1131 }
1132}
1133
1139#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
1140
1141static int
1142rb_singleton_class_has_metaclass_p(VALUE sklass)
1143{
1144 return RCLASS_ATTACHED_OBJECT(METACLASS_OF(sklass)) == sklass;
1145}
1146
1147int
1148rb_singleton_class_internal_p(VALUE sklass)
1149{
1150 return (RB_TYPE_P(RCLASS_ATTACHED_OBJECT(sklass), T_CLASS) &&
1151 !rb_singleton_class_has_metaclass_p(sklass));
1152}
1153
1159#define HAVE_METACLASS_P(k) \
1160 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
1161 rb_singleton_class_has_metaclass_p(k))
1162
1170#define ENSURE_EIGENCLASS(klass) \
1171 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
1172
1173
1183static inline VALUE
1185{
1186 VALUE super;
1187 VALUE metaclass = class_boot_boxable(Qundef, FL_TEST_RAW(klass, RCLASS_BOXABLE));
1188
1189 FL_SET(metaclass, FL_SINGLETON);
1190 rb_singleton_class_attached(metaclass, klass);
1191
1192 if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
1193 SET_METACLASS_OF(klass, metaclass);
1194 SET_METACLASS_OF(metaclass, metaclass);
1195 }
1196 else {
1197 VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
1198 SET_METACLASS_OF(klass, metaclass);
1199 SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp));
1200 }
1201
1202 super = RCLASS_SUPER(klass);
1203 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
1204 class_associate_super(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass, true);
1205 rb_class_set_initialized(klass);
1206
1207 // Full class ancestry may not have been filled until we reach here.
1208 rb_class_update_superclasses(METACLASS_OF(metaclass));
1209
1210 return metaclass;
1211}
1212
1219static inline VALUE
1221{
1222 VALUE orig_class = METACLASS_OF(obj);
1223 VALUE klass = class_alloc0(T_CLASS, rb_cClass, FL_TEST_RAW(orig_class, RCLASS_BOXABLE));
1224 FL_SET(klass, FL_SINGLETON);
1225 class_initialize_method_table(klass);
1226 class_associate_super(klass, orig_class, true);
1227 if (orig_class && !UNDEF_P(orig_class)) {
1228 rb_class_set_initialized(klass);
1229 }
1230
1231 RBASIC_SET_CLASS(obj, klass);
1232 rb_singleton_class_attached(klass, obj);
1233 rb_yjit_invalidate_no_singleton_class(orig_class);
1234 rb_zjit_invalidate_no_singleton_class(orig_class);
1235
1236 SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class)));
1237 return klass;
1238}
1239
1240
1241static VALUE
1242boot_defclass(const char *name, VALUE super)
1243{
1244 VALUE obj = rb_class_boot(super);
1245 ID id = rb_intern(name);
1246
1247 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
1248 rb_vm_register_global_object(obj);
1249 return obj;
1250}
1251
1252/***********************************************************************
1253 *
1254 * Document-class: Refinement
1255 *
1256 * Refinement is a class of the +self+ (current context) inside +refine+
1257 * statement. It allows to import methods from other modules, see #import_methods.
1258 */
1259
1260#if 0 /* for RDoc */
1261/*
1262 * Document-method: Refinement#import_methods
1263 *
1264 * call-seq:
1265 * import_methods(module, ...) -> self
1266 *
1267 * Imports methods from modules. Unlike Module#include,
1268 * Refinement#import_methods copies methods and adds them into the refinement,
1269 * so the refinement is activated in the imported methods.
1270 *
1271 * Note that due to method copying, only methods defined in Ruby code can be imported.
1272 *
1273 * module StrUtils
1274 * def indent(level)
1275 * ' ' * level + self
1276 * end
1277 * end
1278 *
1279 * module M
1280 * refine String do
1281 * import_methods StrUtils
1282 * end
1283 * end
1284 *
1285 * using M
1286 * "foo".indent(3)
1287 * #=> " foo"
1288 *
1289 * module M
1290 * refine String do
1291 * import_methods Enumerable
1292 * # Can't import method which is not defined with Ruby code: Enumerable#drop
1293 * end
1294 * end
1295 *
1296 */
1297
1298static VALUE
1299refinement_import_methods(int argc, VALUE *argv, VALUE refinement)
1300{
1301}
1302# endif
1303
1323void
1324Init_class_hierarchy(void)
1325{
1326 rb_cBasicObject = boot_defclass("BasicObject", 0);
1327 RCLASS_SET_ALLOCATOR(rb_cBasicObject, rb_class_allocate_instance);
1328 FL_SET_RAW(rb_cBasicObject, RCLASS_ALLOCATOR_DEFINED);
1329 RCLASS_SET_EXPECT_NO_IVAR(rb_cBasicObject);
1330
1331 rb_cObject = boot_defclass("Object", rb_cBasicObject);
1332 RCLASS_SET_EXPECT_NO_IVAR(rb_cObject);
1333
1334 /* resolve class name ASAP for order-independence */
1335 rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object"));
1336
1337 rb_cModule = boot_defclass("Module", rb_cObject);
1338 rb_cClass = boot_defclass("Class", rb_cModule);
1339 rb_cRefinement = boot_defclass("Refinement", rb_cModule);
1340
1341#if 0 /* for RDoc */
1342 // we pretend it to be public, otherwise RDoc will ignore it
1343 rb_define_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
1344#endif
1345
1347 RBASIC_SET_CLASS(rb_cClass, rb_cClass);
1348 RBASIC_SET_CLASS(rb_cModule, rb_cClass);
1349 RBASIC_SET_CLASS(rb_cObject, rb_cClass);
1350 RBASIC_SET_CLASS(rb_cRefinement, rb_cClass);
1351 RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
1352
1354}
1355
1356
1367VALUE
1368rb_make_metaclass(VALUE obj, VALUE unused)
1369{
1370 if (BUILTIN_TYPE(obj) == T_CLASS) {
1371 return make_metaclass(obj);
1372 }
1373 else {
1374 return make_singleton_class(obj);
1375 }
1376}
1377
1378VALUE
1380{
1381 VALUE klass;
1382
1383 if (!super) super = rb_cObject;
1384 klass = rb_class_new(super);
1385 rb_make_metaclass(klass, METACLASS_OF(super));
1386
1387 return klass;
1388}
1389
1390
1399VALUE
1401{
1402 ID inherited;
1403 if (!super) super = rb_cObject;
1404 CONST_ID(inherited, "inherited");
1405 return rb_funcall(super, inherited, 1, klass);
1406}
1407
1408#ifdef rb_define_class
1409#undef rb_define_class
1410#endif
1411VALUE
1412rb_define_class(const char *name, VALUE super)
1413{
1414 return rb_define_class_under(rb_cObject, name, super);
1415}
1416
1417#ifdef rb_define_class_under
1418#undef rb_define_class_under
1419#endif
1420VALUE
1421rb_define_class_under(VALUE outer, const char *name, VALUE super)
1422{
1423 return rb_define_class_id_under(outer, rb_intern(name), super);
1424}
1425
1426VALUE
1427rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super)
1428{
1429 VALUE klass;
1430
1431 if (rb_const_defined_at(outer, id)) {
1432 klass = rb_const_get_at(outer, id);
1433 if (!RB_TYPE_P(klass, T_CLASS)) {
1434 if (outer == rb_cObject) {
1435 rb_raise(rb_eTypeError, "%s is not a class (%"PRIsVALUE")",
1436 rb_id2name(id), rb_obj_class(klass));
1437 }
1438 else {
1439 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a class"
1440 " (%"PRIsVALUE")",
1441 outer, rb_id2str(id), rb_obj_class(klass));
1442 }
1443 }
1444 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
1445 if (outer == rb_cObject) {
1446 rb_raise(rb_eTypeError, "superclass mismatch for class %s", rb_id2name(id));
1447 }
1448 else {
1449 rb_raise(rb_eTypeError, "superclass mismatch for class "
1450 "%"PRIsVALUE"::%"PRIsVALUE""
1451 " (%"PRIsVALUE" is given but was %"PRIsVALUE")",
1452 outer, rb_id2str(id), RCLASS_SUPER(klass), super);
1453 }
1454 }
1455
1456 return klass;
1457 }
1458 if (!super) {
1459 if (outer == rb_cObject) {
1460 rb_raise(rb_eArgError, "no super class for '%"PRIsVALUE"'", rb_id2str(id));
1461 }
1462 else {
1463 rb_raise(rb_eArgError, "no super class for '%"PRIsVALUE"::%"PRIsVALUE"'",
1464 rb_class_path(outer), rb_id2str(id));
1465 }
1466 }
1467 klass = rb_define_class_id(id, super);
1468 rb_set_class_path_string(klass, outer, rb_id2str(id));
1469 rb_const_set(outer, id, klass);
1470 rb_class_inherited(super, klass);
1471
1472 return klass;
1473}
1474
1475VALUE
1477{
1478 VALUE klass = rb_define_class_id_under_no_pin(outer, id, super);
1479 rb_vm_register_global_object(klass);
1480 return klass;
1481}
1482
1483VALUE
1484rb_module_s_alloc(VALUE klass)
1485{
1486 VALUE mod = class_alloc(T_MODULE, klass);
1487 class_initialize_method_table(mod);
1488 return mod;
1489}
1490
1491static inline VALUE
1492module_new(VALUE klass)
1493{
1494 VALUE mdl = class_alloc(T_MODULE, klass);
1495 class_initialize_method_table(mdl);
1496 return (VALUE)mdl;
1497}
1498
1499VALUE
1501{
1502 return module_new(rb_cModule);
1503}
1504
1505VALUE
1507{
1508 return module_new(rb_cRefinement);
1509}
1510
1511// Kept for compatibility. Use rb_module_new() instead.
1512VALUE
1514{
1515 return rb_module_new();
1516}
1517
1518#ifdef rb_define_module
1519#undef rb_define_module
1520#endif
1521VALUE
1522rb_define_module(const char *name)
1523{
1524 return rb_define_module_id_under(rb_cObject, rb_intern(name));
1525}
1526
1527#ifdef rb_define_module_under
1528#undef rb_define_module_under
1529#endif
1530VALUE
1531rb_define_module_under(VALUE outer, const char *name)
1532{
1533 return rb_define_module_id_under(outer, rb_intern(name));
1534}
1535
1536VALUE
1538{
1539 VALUE module;
1540
1541 if (rb_const_defined_at(outer, id)) {
1542 module = rb_const_get_at(outer, id);
1543 if (!RB_TYPE_P(module, T_MODULE)) {
1544 if (outer == rb_cObject) {
1545 rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
1546 rb_id2name(id), rb_obj_class(module));
1547 }
1548 else {
1549 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a module"
1550 " (%"PRIsVALUE")",
1551 outer, rb_id2str(id), rb_obj_class(module));
1552 }
1553 }
1554 /* Module may have been defined in Ruby and not pin-rooted */
1555 rb_vm_register_global_object(module);
1556 return module;
1557 }
1558 module = rb_module_new();
1559 rb_const_set(outer, id, module);
1560 rb_set_class_path_string(module, outer, rb_id2str(id));
1561 rb_vm_register_global_object(module);
1562
1563 return module;
1564}
1565
1566VALUE
1567rb_include_class_new(VALUE module, VALUE super)
1568{
1569 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
1570
1571 RCLASS_SET_M_TBL(klass, RCLASS_WRITABLE_M_TBL(module));
1572
1573 RCLASS_SET_ORIGIN(klass, klass);
1574 if (BUILTIN_TYPE(module) == T_ICLASS) {
1575 module = METACLASS_OF(module);
1576 }
1577 RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
1578 if (RCLASS_WRITABLE_CONST_TBL(module)) {
1579 RCLASS_SET_CONST_TBL(klass, RCLASS_WRITABLE_CONST_TBL(module), true);
1580 }
1581 else {
1582 RCLASS_WRITE_CONST_TBL(module, rb_id_table_create(0), false);
1583 RCLASS_SET_CONST_TBL(klass, RCLASS_WRITABLE_CONST_TBL(module), true);
1584 }
1585
1586 RCLASS_SET_CVC_TBL(klass, RCLASS_WRITABLE_CVC_TBL(module));
1587
1588 class_associate_super(klass, super, true);
1589 RBASIC_SET_CLASS(klass, module);
1590
1591 return (VALUE)klass;
1592}
1593
1594static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
1595
1596static void
1597ensure_includable(VALUE klass, VALUE module)
1598{
1599 rb_class_modify_check(klass);
1600 Check_Type(module, T_MODULE);
1601 rb_class_set_initialized(module);
1602 if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
1603 rb_raise(rb_eArgError, "refinement module is not allowed");
1604 }
1605}
1606
1607void
1609{
1610 int changed = 0;
1611
1612 ensure_includable(klass, module);
1613
1614 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
1615 if (changed < 0)
1616 rb_raise(rb_eArgError, "cyclic include detected");
1617
1618 if (RB_TYPE_P(klass, T_MODULE)) {
1619 VALUE subs_v = RCLASS_SUBCLASSES(klass);
1620 if (subs_v) {
1621 struct rb_subclasses *subs = (struct rb_subclasses *)subs_v;
1622 VALUE *entries = rb_imemo_subclasses_entries(subs_v);
1623 for (uint32_t i = 0; i < subs->count; i++) {
1624 VALUE check_class = entries[i];
1625 if (!check_class) continue;
1626
1627 int do_include = 1;
1628 /* During lazy sweeping, the entry could be a dead object that
1629 * has not yet been swept. */
1630 if (!rb_objspace_garbage_object_p(check_class)) {
1631 VALUE walk = check_class;
1632 while (walk) {
1633 RUBY_ASSERT(!rb_objspace_garbage_object_p(walk));
1634
1635 if (RB_TYPE_P(walk, T_ICLASS) &&
1636 (METACLASS_OF(walk) == module)) {
1637 do_include = 0;
1638 }
1639 walk = RCLASS_SUPER(walk);
1640 }
1641
1642 if (do_include) {
1643 include_modules_at(check_class, RCLASS_ORIGIN(check_class), module, TRUE);
1644 }
1645 }
1646 }
1647 }
1648 }
1649}
1650
1651static enum rb_id_table_iterator_result
1652add_refined_method_entry_i(ID key, VALUE value, void *data)
1653{
1654 rb_add_refined_method_entry((VALUE)data, key);
1655 return ID_TABLE_CONTINUE;
1656}
1657
1658static enum rb_id_table_iterator_result
1659clear_module_cache_i(ID id, VALUE val, void *data)
1660{
1661 VALUE klass = (VALUE)data;
1662 rb_clear_method_cache(klass, id);
1663 return ID_TABLE_CONTINUE;
1664}
1665
1666static bool
1667module_in_super_chain(const VALUE klass, VALUE module)
1668{
1669 struct rb_id_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
1670 if (klass_m_tbl) {
1671 while (module) {
1672 if (klass_m_tbl == RCLASS_M_TBL(module))
1673 return true;
1674 module = RCLASS_SUPER(module);
1675 }
1676 }
1677 return false;
1678}
1679
1680// For each ID key in the class constant table, we're going to clear the VM's
1681// inline constant caches associated with it.
1682static enum rb_id_table_iterator_result
1683clear_constant_cache_i(ID id, VALUE value, void *data)
1684{
1686 return ID_TABLE_CONTINUE;
1687}
1688
1689static int
1690do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super, bool check_cyclic)
1691{
1692 VALUE p, iclass, origin_stack = 0;
1693 int method_changed = 0;
1694 long origin_len;
1695 VALUE klass_origin = RCLASS_ORIGIN(klass);
1696 VALUE original_klass = klass;
1697
1698 if (check_cyclic && module_in_super_chain(klass, module))
1699 return -1;
1700
1701 while (module) {
1702 int c_seen = FALSE;
1703 int superclass_seen = FALSE;
1704 struct rb_id_table *tbl;
1705
1706 if (klass == c) {
1707 c_seen = TRUE;
1708 }
1709 if (klass_origin != c || search_super) {
1710 /* ignore if the module included already in superclasses for include,
1711 * ignore if the module included before origin class for prepend
1712 */
1713 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
1714 int type = BUILTIN_TYPE(p);
1715 if (klass_origin == p && !search_super)
1716 break;
1717 if (c == p)
1718 c_seen = TRUE;
1719 if (type == T_ICLASS) {
1720 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
1721 if (!superclass_seen && c_seen) {
1722 c = p; /* move insertion point */
1723 }
1724 goto skip;
1725 }
1726 }
1727 else if (type == T_CLASS) {
1728 superclass_seen = TRUE;
1729 }
1730 }
1731 }
1732
1733 VALUE super_class = RCLASS_SUPER(c);
1734
1735 // invalidate inline method cache
1736 RB_DEBUG_COUNTER_INC(cvar_include_invalidate);
1737 ruby_vm_global_cvar_state++;
1738 tbl = RCLASS_M_TBL(module);
1739 if (tbl && rb_id_table_size(tbl)) {
1740 if (search_super) { // include
1741 if (super_class && !RB_TYPE_P(super_class, T_MODULE)) {
1742 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)super_class);
1743 }
1744 }
1745 else { // prepend
1746 if (!RB_TYPE_P(original_klass, T_MODULE)) {
1747 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)original_klass);
1748 }
1749 }
1750 method_changed = 1;
1751 }
1752
1753 // setup T_ICLASS for the include/prepend module
1754 iclass = rb_include_class_new(module, super_class);
1755 c = rb_class_set_super(c, iclass);
1756 RCLASS_SET_INCLUDER(iclass, klass);
1757 if (module != RCLASS_ORIGIN(module)) {
1758 if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
1759 VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
1760 rb_ary_cat(origin_stack, origin, 2);
1761 }
1762 else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 &&
1763 RARRAY_AREF(origin_stack, origin_len - 1) == module) {
1764 RCLASS_WRITE_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
1765 RICLASS_WRITE_ORIGIN_SHARED_MTBL(iclass);
1766 rb_ary_resize(origin_stack, origin_len);
1767 }
1768
1769 VALUE m = module;
1770 if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
1771 rb_module_add_to_subclasses_list(m, iclass);
1772
1773 if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
1774 VALUE refined_class =
1775 rb_refinement_module_get_refined_class(klass);
1776
1777 rb_id_table_foreach(RCLASS_M_TBL(module), add_refined_method_entry_i, (void *)refined_class);
1779 }
1780
1781 tbl = RCLASS_CONST_TBL(module);
1782 if (tbl && rb_id_table_size(tbl))
1783 rb_id_table_foreach(tbl, clear_constant_cache_i, NULL);
1784 skip:
1785 module = RCLASS_SUPER(module);
1786 }
1787
1788 return method_changed;
1789}
1790
1791static int
1792include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
1793{
1794 return do_include_modules_at(klass, c, module, search_super, true);
1795}
1796
1797static enum rb_id_table_iterator_result
1798move_refined_method(ID key, VALUE value, void *data)
1799{
1800 rb_method_entry_t *me = (rb_method_entry_t *)value;
1801
1802 if (me->def->type == VM_METHOD_TYPE_REFINED) {
1803 VALUE klass = (VALUE)data;
1804 struct rb_id_table *tbl = RCLASS_WRITABLE_M_TBL(klass);
1805
1806 if (me->def->body.refined.orig_me) {
1807 const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
1808 RB_OBJ_WRITE(me, &me->def->body.refined.orig_me, NULL);
1809 new_me = rb_method_entry_clone(me);
1810 rb_method_table_insert(klass, tbl, key, new_me);
1811 rb_method_entry_copy(me, orig_me);
1812 return ID_TABLE_CONTINUE;
1813 }
1814 else {
1815 rb_method_table_insert(klass, tbl, key, me);
1816 return ID_TABLE_DELETE;
1817 }
1818 }
1819 else {
1820 return ID_TABLE_CONTINUE;
1821 }
1822}
1823
1824static enum rb_id_table_iterator_result
1825cache_clear_refined_method(ID key, VALUE value, void *data)
1826{
1827 rb_method_entry_t *me = (rb_method_entry_t *) value;
1828
1829 if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
1830 VALUE klass = (VALUE)data;
1831 rb_clear_method_cache(klass, me->called_id);
1832 }
1833 // Refined method entries without an orig_me is going to stay in the method
1834 // table of klass, like before the move, so no need to clear the cache.
1835
1836 return ID_TABLE_CONTINUE;
1837}
1838
1839static bool
1840ensure_origin(VALUE klass)
1841{
1842 VALUE origin = RCLASS_ORIGIN(klass);
1843 if (origin == klass) {
1844 origin = class_alloc(T_ICLASS, klass);
1845 RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass));
1846 rb_class_set_super(origin, RCLASS_SUPER(klass));
1847 rb_class_set_super(klass, origin); // writes origin into RCLASS_SUPER(klass)
1848 RCLASS_WRITE_ORIGIN(klass, origin);
1849
1850 // RCLASS_WRITE_ORIGIN marks origin as an origin, so this is the first
1851 // point that it sees M_TBL and may mark it
1852 rb_gc_writebarrier_remember(origin);
1853
1854 class_clear_method_table(klass);
1855 rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
1856 rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
1857 return true;
1858 }
1859 return false;
1860}
1861
1862void
1864{
1865 int changed;
1866 bool klass_had_no_origin;
1867
1868 ensure_includable(klass, module);
1869 if (module_in_super_chain(klass, module))
1870 rb_raise(rb_eArgError, "cyclic prepend detected");
1871
1872 klass_had_no_origin = ensure_origin(klass);
1873 changed = do_include_modules_at(klass, klass, module, FALSE, false);
1874 RUBY_ASSERT(changed >= 0); // already checked for cyclic prepend above
1875 if (changed) {
1876 rb_vm_check_redefinition_by_prepend(klass);
1877 }
1878 if (RB_TYPE_P(klass, T_MODULE)) {
1879 VALUE subs_v = RCLASS_SUBCLASSES(klass);
1880 VALUE klass_origin = RCLASS_ORIGIN(klass);
1881 struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
1882 struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
1883 if (subs_v) {
1884 struct rb_subclasses *subs = (struct rb_subclasses *)subs_v;
1885 VALUE *entries = rb_imemo_subclasses_entries(subs_v);
1886 VALUE new_origins = 0;
1887 for (uint32_t i = 0; i < subs->count; i++) {
1888 const VALUE subclass = entries[i];
1889 if (!subclass) continue;
1890 /* During lazy sweeping, the entry could be a dead object that
1891 * has not yet been swept. */
1892 if (!rb_objspace_garbage_object_p(subclass)) {
1893 if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(subclass)) {
1894 // backfill an origin iclass to handle refinements and future prepends
1895 rb_id_table_foreach(RCLASS_M_TBL(subclass), clear_module_cache_i, (void *)subclass);
1896 RCLASS_WRITE_M_TBL(subclass, klass_m_tbl);
1897 VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(subclass));
1898 rb_class_set_super(subclass, origin);
1899 RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(subclass));
1900 RCLASS_WRITE_ORIGIN(subclass, origin);
1901 RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
1902 if (!new_origins) new_origins = rb_ary_hidden_new(1);
1903 rb_ary_push(new_origins, origin);
1904 }
1905 include_modules_at(subclass, subclass, module, FALSE);
1906 }
1907 }
1908 /* Register after the loop. Registering during it would visit the
1909 * new iclass and prepend module into it a second time. */
1910 if (new_origins) {
1911 for (long i = 0; i < RARRAY_LEN(new_origins); i++) {
1912 rb_module_add_to_subclasses_list(klass, RARRAY_AREF(new_origins, i));
1913 }
1914 }
1915 RB_GC_GUARD(new_origins);
1916 }
1917 }
1918}
1919
1920/*
1921 * call-seq:
1922 * mod.included_modules -> array
1923 *
1924 * Returns the list of modules included or prepended in <i>mod</i>
1925 * or one of <i>mod</i>'s ancestors.
1926 *
1927 * module Sub
1928 * end
1929 *
1930 * module Mixin
1931 * prepend Sub
1932 * end
1933 *
1934 * module Outer
1935 * include Mixin
1936 * end
1937 *
1938 * Mixin.included_modules #=> [Sub]
1939 * Outer.included_modules #=> [Sub, Mixin]
1940 */
1941
1942VALUE
1944{
1945 VALUE ary = rb_ary_new();
1946 VALUE p;
1947 VALUE origin = RCLASS_ORIGIN(mod);
1948
1949 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
1950 if (p != origin && RCLASS_ORIGIN(p) == p && BUILTIN_TYPE(p) == T_ICLASS) {
1951 VALUE m = METACLASS_OF(p);
1952 if (RB_TYPE_P(m, T_MODULE))
1953 rb_ary_push(ary, m);
1954 }
1955 }
1956 return ary;
1957}
1958
1959/*
1960 * call-seq:
1961 * mod.include?(module) -> true or false
1962 *
1963 * Returns <code>true</code> if <i>module</i> is included
1964 * or prepended in <i>mod</i> or one of <i>mod</i>'s ancestors.
1965 *
1966 * module A
1967 * end
1968 * class B
1969 * include A
1970 * end
1971 * class C < B
1972 * end
1973 * B.include?(A) #=> true
1974 * C.include?(A) #=> true
1975 * A.include?(A) #=> false
1976 */
1977
1978VALUE
1980{
1981 VALUE p;
1982
1983 Check_Type(mod2, T_MODULE);
1984 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
1985 if (BUILTIN_TYPE(p) == T_ICLASS && !RICLASS_IS_ORIGIN_P(p)) {
1986 if (METACLASS_OF(p) == mod2) return Qtrue;
1987 }
1988 }
1989 return Qfalse;
1990}
1991
1992/*
1993 * call-seq:
1994 * mod.ancestors -> array
1995 *
1996 * Returns a list of modules included/prepended in <i>mod</i>
1997 * (including <i>mod</i> itself).
1998 *
1999 * module Mod
2000 * include Math
2001 * include Comparable
2002 * prepend Enumerable
2003 * end
2004 *
2005 * Mod.ancestors #=> [Enumerable, Mod, Comparable, Math]
2006 * Math.ancestors #=> [Math]
2007 * Enumerable.ancestors #=> [Enumerable]
2008 */
2009
2010VALUE
2012{
2013 VALUE p, ary = rb_ary_new();
2014 VALUE refined_class = Qnil;
2015 if (BUILTIN_TYPE(mod) == T_MODULE && FL_TEST(mod, RMODULE_IS_REFINEMENT)) {
2016 refined_class = rb_refinement_module_get_refined_class(mod);
2017 }
2018
2019 for (p = mod; p; p = RCLASS_SUPER(p)) {
2020 if (p == refined_class) break;
2021 if (p != RCLASS_ORIGIN(p)) continue;
2022 if (BUILTIN_TYPE(p) == T_ICLASS) {
2023 rb_ary_push(ary, METACLASS_OF(p));
2024 }
2025 else {
2026 rb_ary_push(ary, p);
2027 }
2028 }
2029 return ary;
2030}
2031
2033{
2034 VALUE buffer;
2035 long count;
2036 long maxcount;
2037 bool immediate_only;
2038};
2039
2040static void
2041class_descendants_recursive(VALUE klass, VALUE v)
2042{
2043 struct subclass_traverse_data *data = (struct subclass_traverse_data *) v;
2044
2045 if (RB_TYPE_P(klass, T_ICLASS)) return; // skip refinement ICLASSes
2046
2047 if (!RCLASS_SINGLETON_P(klass)) {
2048 if (data->buffer && data->count < data->maxcount && !rb_objspace_garbage_object_p(klass)) {
2049 // assumes that this does not cause GC as long as the length does not exceed the capacity
2050 rb_ary_push(data->buffer, klass);
2051 }
2052 data->count++;
2053 if (data->immediate_only) return;
2054 }
2055 rb_class_foreach_subclass(klass, class_descendants_recursive, v);
2056}
2057
2058static VALUE
2059class_descendants(VALUE klass, bool immediate_only)
2060{
2061 struct subclass_traverse_data data = { Qfalse, 0, -1, immediate_only };
2062
2063 // estimate the count of subclasses
2064 rb_class_foreach_subclass(klass, class_descendants_recursive, (VALUE) &data);
2065
2066 // the following allocation may cause GC which may change the number of subclasses
2067 data.buffer = rb_ary_new_capa(data.count);
2068 data.maxcount = data.count;
2069 data.count = 0;
2070
2071 size_t gc_count = rb_gc_count();
2072
2073 // enumerate subclasses
2074 rb_class_foreach_subclass(klass, class_descendants_recursive, (VALUE) &data);
2075
2076 if (gc_count != rb_gc_count()) {
2077 rb_bug("GC must not occur during the subclass iteration of Class#descendants");
2078 }
2079
2080 return data.buffer;
2081}
2082
2083/*
2084 * call-seq:
2085 * subclasses -> array
2086 *
2087 * Returns an array of classes where the receiver is the
2088 * direct superclass of the class, excluding singleton classes.
2089 * The order of the returned array is not defined.
2090 *
2091 * class A; end
2092 * class B < A; end
2093 * class C < B; end
2094 * class D < A; end
2095 *
2096 * A.subclasses #=> [D, B]
2097 * B.subclasses #=> [C]
2098 * C.subclasses #=> []
2099 *
2100 * Anonymous subclasses (not associated with a constant) are
2101 * returned, too:
2102 *
2103 * c = Class.new(A)
2104 * A.subclasses # => [#<Class:0x00007f003c77bd78>, D, B]
2105 *
2106 * Note that the parent does not hold references to subclasses
2107 * and doesn't prevent them from being garbage collected. This
2108 * means that the subclass might disappear when all references
2109 * to it are dropped:
2110 *
2111 * # drop the reference to subclass, it can be garbage-collected now
2112 * c = nil
2113 *
2114 * A.subclasses
2115 * # It can be
2116 * # => [#<Class:0x00007f003c77bd78>, D, B]
2117 * # ...or just
2118 * # => [D, B]
2119 * # ...depending on whether garbage collector was run
2120 */
2121
2122VALUE
2124{
2125 return class_descendants(klass, true);
2126}
2127
2129{
2130 VALUE buffer;
2131 long count;
2132 long maxcount;
2133 st_table *visited;
2134};
2135
2136static void module_descendants_recursive(VALUE entry, VALUE v);
2137
2138static void
2139module_descendants_add(VALUE klass, struct descendants_traverse_data *data)
2140{
2141 // skip entries beyond the estimation to keep the enumeration pass allocation-free
2142 if (data->buffer && data->count >= data->maxcount) return;
2143
2144 if (st_insert(data->visited, (st_data_t)klass, 1)) return; // already visited
2145
2146 if (data->buffer) {
2147 // assumes that this does not cause GC as long as the length does not exceed the capacity
2148 rb_ary_push(data->buffer, klass);
2149 }
2150 data->count++;
2151 rb_class_foreach_subclass(klass, module_descendants_recursive, (VALUE)data);
2152}
2153
2154// an include done in another box is not in the ancestors here if the includer
2155// has a classext per box, e.g. a module included into a builtin class
2156static bool
2157iclass_in_ancestors_p(VALUE iclass, VALUE includer)
2158{
2159 for (VALUE p = includer; p; p = RCLASS_SUPER(p)) {
2160 if (p == iclass) return true;
2161 }
2162 return false;
2163}
2164
2165static void
2166module_descendants_recursive(VALUE entry, VALUE v)
2167{
2168 struct descendants_traverse_data *data = (struct descendants_traverse_data *)v;
2169
2170 if (rb_objspace_garbage_object_p(entry)) return;
2171
2172 if (RB_TYPE_P(entry, T_ICLASS)) {
2173 // resolve the ICLASS to the including class or module;
2174 // refinement ICLASSes have no includer
2175 VALUE includer = RCLASS_INCLUDER(entry);
2176 while (includer && RB_TYPE_P(includer, T_ICLASS)) {
2177 includer = RCLASS_INCLUDER(includer);
2178 }
2179 if (!includer || UNDEF_P(includer)) return;
2180 if (rb_objspace_garbage_object_p(includer)) return;
2181 if (RCLASS_SINGLETON_P(includer)) return; // e.g. Object#extend
2182 if (!iclass_in_ancestors_p(entry, includer)) return;
2183 module_descendants_add(includer, data);
2184 }
2185 else {
2186 if (RCLASS_SINGLETON_P(entry)) return;
2187 module_descendants_add(entry, data);
2188 }
2189}
2190
2191/*
2192 * call-seq:
2193 * descendants -> array
2194 *
2195 * Returns an array of classes and modules that have the receiver in
2196 * their ancestors. This is the inverse of Module#ancestors:
2197 * +x.descendants.include?(y)+ holds if and only if
2198 * +y.ancestors.include?(x)+ holds, except that the receiver itself,
2199 * singleton classes, and refinements are never included.
2200 * The order of the returned array is not defined.
2201 *
2202 * module A; end
2203 * module B; include A; end
2204 * class C; include B; end
2205 * class D < C; end
2206 *
2207 * A.descendants #=> [B, C, D]
2208 * B.descendants #=> [C, D]
2209 * C.descendants #=> [D]
2210 *
2211 * Note that the receiver does not hold references to its descendants
2212 * and doesn't prevent them from being garbage collected. This means
2213 * that a descendant might disappear from the result when all
2214 * references to it are dropped, depending on whether garbage
2215 * collector was run.
2216 */
2217
2218VALUE
2220{
2221 struct descendants_traverse_data data = { Qfalse, 0, -1, NULL };
2222
2223 // estimate the count of descendants
2224 data.visited = st_init_numtable();
2225 st_insert(data.visited, (st_data_t)mod, 1); // exclude the receiver
2226 rb_class_foreach_subclass(mod, module_descendants_recursive, (VALUE)&data);
2227 st_free_table(data.visited);
2228
2229 // the following allocation may cause GC which may change the number of descendants
2230 data.buffer = rb_ary_new_capa(data.count);
2231 data.maxcount = data.count;
2232 data.count = 0;
2233 // pre-sized so that st_insert() does not cause GC during the enumeration
2234 data.visited = st_init_numtable_with_size(data.maxcount + 1);
2235 st_insert(data.visited, (st_data_t)mod, 1); // exclude the receiver
2236
2237 size_t gc_count = rb_gc_count();
2238
2239 rb_class_foreach_subclass(mod, module_descendants_recursive, (VALUE)&data);
2240
2241 if (gc_count != rb_gc_count()) {
2242 rb_bug("GC must not occur during the subclass iteration of Module#descendants");
2243 }
2244 st_free_table(data.visited);
2245
2246 return data.buffer;
2247}
2248
2249/*
2250 * call-seq:
2251 * attached_object -> object
2252 *
2253 * Returns the object for which the receiver is the singleton class.
2254 *
2255 * Raises an TypeError if the class is not a singleton class.
2256 *
2257 * class Foo; end
2258 *
2259 * Foo.singleton_class.attached_object #=> Foo
2260 * Foo.attached_object #=> TypeError: `Foo' is not a singleton class
2261 * Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370>
2262 * TrueClass.attached_object #=> TypeError: `TrueClass' is not a singleton class
2263 * NilClass.attached_object #=> TypeError: `NilClass' is not a singleton class
2264 */
2265
2266VALUE
2268{
2269 if (!RCLASS_SINGLETON_P(klass)) {
2270 rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass);
2271 }
2272
2273 return RCLASS_ATTACHED_OBJECT(klass);
2274}
2275
2276static void
2277ins_methods_push(st_data_t name, st_data_t ary)
2278{
2279 rb_ary_push((VALUE)ary, ID2SYM((ID)name));
2280}
2281
2282static int
2283ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
2284{
2285 switch ((rb_method_visibility_t)type) {
2286 case METHOD_VISI_UNDEF:
2287 case METHOD_VISI_PRIVATE:
2288 break;
2289 default: /* everything but private */
2290 ins_methods_push(name, ary);
2291 break;
2292 }
2293 return ST_CONTINUE;
2294}
2295
2296static int
2297ins_methods_type_i(st_data_t name, st_data_t type, st_data_t ary, rb_method_visibility_t visi)
2298{
2299 if ((rb_method_visibility_t)type == visi) {
2300 ins_methods_push(name, ary);
2301 }
2302 return ST_CONTINUE;
2303}
2304
2305static int
2306ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
2307{
2308 return ins_methods_type_i(name, type, ary, METHOD_VISI_PROTECTED);
2309}
2310
2311static int
2312ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
2313{
2314 return ins_methods_type_i(name, type, ary, METHOD_VISI_PRIVATE);
2315}
2316
2317static int
2318ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
2319{
2320 return ins_methods_type_i(name, type, ary, METHOD_VISI_PUBLIC);
2321}
2322
2323static int
2324ins_methods_undef_i(st_data_t name, st_data_t type, st_data_t ary)
2325{
2326 return ins_methods_type_i(name, type, ary, METHOD_VISI_UNDEF);
2327}
2328
2330 st_table *list;
2331 int recur;
2332};
2333
2334static enum rb_id_table_iterator_result
2335method_entry_i(ID key, VALUE value, void *data)
2336{
2337 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
2338 struct method_entry_arg *arg = (struct method_entry_arg *)data;
2339 rb_method_visibility_t type;
2340
2341 if (me->def->type == VM_METHOD_TYPE_REFINED) {
2342 VALUE owner = me->owner;
2343 me = rb_resolve_refined_method(Qnil, me);
2344 if (!me) return ID_TABLE_CONTINUE;
2345 if (!arg->recur && me->owner != owner) return ID_TABLE_CONTINUE;
2346 }
2347 if (!st_is_member(arg->list, key)) {
2348 if (UNDEFINED_METHOD_ENTRY_P(me)) {
2349 type = METHOD_VISI_UNDEF; /* none */
2350 }
2351 else {
2352 type = METHOD_ENTRY_VISI(me);
2353 RUBY_ASSERT(type != METHOD_VISI_UNDEF);
2354 }
2355 st_add_direct(arg->list, key, (st_data_t)type);
2356 }
2357 return ID_TABLE_CONTINUE;
2358}
2359
2360static void
2361add_instance_method_list(VALUE mod, struct method_entry_arg *me_arg)
2362{
2363 struct rb_id_table *m_tbl = RCLASS_M_TBL(mod);
2364 if (!m_tbl) return;
2365 rb_id_table_foreach(m_tbl, method_entry_i, me_arg);
2366}
2367
2368static bool
2369particular_class_p(VALUE mod)
2370{
2371 if (!mod) return false;
2372 if (RCLASS_SINGLETON_P(mod)) return true;
2373 if (BUILTIN_TYPE(mod) == T_ICLASS) return true;
2374 return false;
2375}
2376
2377static VALUE
2378class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
2379{
2380 VALUE ary;
2381 int recur = TRUE, prepended = 0;
2382 struct method_entry_arg me_arg;
2383
2384 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
2385
2386 me_arg.list = st_init_numtable();
2387 me_arg.recur = recur;
2388
2389 if (obj) {
2390 for (; particular_class_p(mod); mod = RCLASS_SUPER(mod)) {
2391 add_instance_method_list(mod, &me_arg);
2392 }
2393 }
2394
2395 if (!recur && RCLASS_ORIGIN(mod) != mod) {
2396 mod = RCLASS_ORIGIN(mod);
2397 prepended = 1;
2398 }
2399
2400 for (; mod; mod = RCLASS_SUPER(mod)) {
2401 add_instance_method_list(mod, &me_arg);
2402 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
2403 if (!recur) break;
2404 }
2405 ary = rb_ary_new2(me_arg.list->num_entries);
2406 st_foreach(me_arg.list, func, ary);
2407 st_free_table(me_arg.list);
2408
2409 return ary;
2410}
2411
2412/*
2413 * call-seq:
2414 * mod.instance_methods(include_super=true) -> array
2415 *
2416 * Returns an array containing the names of the public and protected instance
2417 * methods in the receiver. For a module, these are the public and protected methods;
2418 * for a class, they are the instance (not singleton) methods. If the optional
2419 * parameter is <code>false</code>, the methods of any ancestors are not included.
2420 *
2421 * module A
2422 * def method1() end
2423 * end
2424 * class B
2425 * include A
2426 * def method2() end
2427 * end
2428 * class C < B
2429 * def method3() end
2430 * end
2431 *
2432 * A.instance_methods(false) #=> [:method1]
2433 * B.instance_methods(false) #=> [:method2]
2434 * B.instance_methods(true).include?(:method1) #=> true
2435 * C.instance_methods(false) #=> [:method3]
2436 * C.instance_methods.include?(:method2) #=> true
2437 *
2438 * Note that method visibility changes in the current class, as well as aliases,
2439 * are considered as methods of the current class by this method:
2440 *
2441 * class C < B
2442 * alias method4 method2
2443 * protected :method2
2444 * end
2445 * C.instance_methods(false).sort #=> [:method2, :method3, :method4]
2446 */
2447
2448VALUE
2449rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
2450{
2451 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
2452}
2453
2454/*
2455 * call-seq:
2456 * mod.protected_instance_methods(include_super=true) -> array
2457 *
2458 * Returns a list of the protected instance methods defined in
2459 * <i>mod</i>. If the optional parameter is <code>false</code>, the
2460 * methods of any ancestors are not included.
2461 */
2462
2463VALUE
2465{
2466 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
2467}
2468
2469/*
2470 * call-seq:
2471 * mod.private_instance_methods(include_super=true) -> array
2472 *
2473 * Returns a list of the private instance methods defined in
2474 * <i>mod</i>. If the optional parameter is <code>false</code>, the
2475 * methods of any ancestors are not included.
2476 *
2477 * module Mod
2478 * def method1() end
2479 * private :method1
2480 * def method2() end
2481 * end
2482 * Mod.instance_methods #=> [:method2]
2483 * Mod.private_instance_methods #=> [:method1]
2484 */
2485
2486VALUE
2488{
2489 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
2490}
2491
2492/*
2493 * call-seq:
2494 * mod.public_instance_methods(include_super=true) -> array
2495 *
2496 * Returns a list of the public instance methods defined in <i>mod</i>.
2497 * If the optional parameter is <code>false</code>, the methods of
2498 * any ancestors are not included.
2499 */
2500
2501VALUE
2503{
2504 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
2505}
2506
2507/*
2508 * call-seq:
2509 * mod.undefined_instance_methods -> array
2510 *
2511 * Returns a list of the undefined instance methods defined in <i>mod</i>.
2512 * The undefined methods of any ancestors are not included.
2513 */
2514
2515VALUE
2516rb_class_undefined_instance_methods(VALUE mod)
2517{
2518 VALUE include_super = Qfalse;
2519 return class_instance_method_list(1, &include_super, mod, 0, ins_methods_undef_i);
2520}
2521
2522/*
2523 * call-seq:
2524 * obj.methods(regular=true) -> array
2525 *
2526 * Returns a list of the names of public and protected methods of
2527 * <i>obj</i>. This will include all the methods accessible in
2528 * <i>obj</i>'s ancestors.
2529 * If the optional parameter is <code>false</code>, it
2530 * returns an array of <i>obj</i>'s public and protected singleton methods,
2531 * the array will not include methods in modules included in <i>obj</i>.
2532 *
2533 * class Klass
2534 * def klass_method()
2535 * end
2536 * end
2537 * k = Klass.new
2538 * k.methods[0..9] #=> [:klass_method, :nil?, :===,
2539 * # :==~, :!, :eql?
2540 * # :hash, :<=>, :class, :singleton_class]
2541 * k.methods.length #=> 56
2542 *
2543 * k.methods(false) #=> []
2544 * def k.singleton_method; end
2545 * k.methods(false) #=> [:singleton_method]
2546 *
2547 * module M123; def m123; end end
2548 * k.extend M123
2549 * k.methods(false) #=> [:singleton_method]
2550 */
2551
2552VALUE
2553rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
2554{
2555 rb_check_arity(argc, 0, 1);
2556 if (argc > 0 && !RTEST(argv[0])) {
2557 return rb_obj_singleton_methods(argc, argv, obj);
2558 }
2559 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
2560}
2561
2562/*
2563 * call-seq:
2564 * obj.protected_methods(all=true) -> array
2565 *
2566 * Returns the list of protected methods accessible to <i>obj</i>. If
2567 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2568 * in the receiver will be listed.
2569 */
2570
2571VALUE
2572rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
2573{
2574 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
2575}
2576
2577/*
2578 * call-seq:
2579 * obj.private_methods(all=true) -> array
2580 *
2581 * Returns the list of private methods accessible to <i>obj</i>. If
2582 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2583 * in the receiver will be listed.
2584 */
2585
2586VALUE
2587rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
2588{
2589 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
2590}
2591
2592/*
2593 * call-seq:
2594 * obj.public_methods(all=true) -> array
2595 *
2596 * Returns the list of public methods accessible to <i>obj</i>. If
2597 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2598 * in the receiver will be listed.
2599 */
2600
2601VALUE
2602rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
2603{
2604 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
2605}
2606
2607/*
2608 * call-seq:
2609 * obj.singleton_methods(all=true) -> array
2610 *
2611 * Returns an array of the names of singleton methods for <i>obj</i>.
2612 * If the optional <i>all</i> parameter is true, the list will include
2613 * methods in modules included in <i>obj</i>.
2614 * Only public and protected singleton methods are returned.
2615 *
2616 * module Other
2617 * def three() end
2618 * end
2619 *
2620 * class Single
2621 * def Single.four() end
2622 * end
2623 *
2624 * a = Single.new
2625 *
2626 * def a.one()
2627 * end
2628 *
2629 * class << a
2630 * include Other
2631 * def two()
2632 * end
2633 * end
2634 *
2635 * Single.singleton_methods #=> [:four]
2636 * a.singleton_methods(false) #=> [:two, :one]
2637 * a.singleton_methods #=> [:two, :one, :three]
2638 */
2639
2640VALUE
2641rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
2642{
2643 VALUE ary, klass, origin;
2644 struct method_entry_arg me_arg;
2645 struct rb_id_table *mtbl;
2646 int recur = TRUE;
2647
2648 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
2649 if (RB_TYPE_P(obj, T_CLASS) && RCLASS_SINGLETON_P(obj)) {
2650 rb_singleton_class(obj);
2651 }
2652 klass = CLASS_OF(obj);
2653 origin = RCLASS_ORIGIN(klass);
2654 me_arg.list = st_init_numtable();
2655 me_arg.recur = recur;
2656 if (klass && RCLASS_SINGLETON_P(klass)) {
2657 if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
2658 klass = RCLASS_SUPER(klass);
2659 }
2660 if (recur) {
2661 while (klass && (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS))) {
2662 if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
2663 klass = RCLASS_SUPER(klass);
2664 }
2665 }
2666 ary = rb_ary_new2(me_arg.list->num_entries);
2667 st_foreach(me_arg.list, ins_methods_i, ary);
2668 st_free_table(me_arg.list);
2669
2670 return ary;
2671}
2672
2681#ifdef rb_define_method_id
2682#undef rb_define_method_id
2683#endif
2684void
2685rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
2686{
2687 rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC);
2688}
2689
2690#ifdef rb_define_method
2691#undef rb_define_method
2692#endif
2693void
2694rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2695{
2696 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PUBLIC);
2697}
2698
2699#ifdef rb_define_protected_method
2700#undef rb_define_protected_method
2701#endif
2702void
2703rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2704{
2705 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PROTECTED);
2706}
2707
2708#ifdef rb_define_private_method
2709#undef rb_define_private_method
2710#endif
2711void
2712rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2713{
2714 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PRIVATE);
2715}
2716
2717void
2718rb_undef_method(VALUE klass, const char *name)
2719{
2720 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
2721}
2722
2723static enum rb_id_table_iterator_result
2724undef_method_i(ID name, VALUE value, void *data)
2725{
2726 VALUE klass = (VALUE)data;
2727 rb_add_method(klass, name, VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
2728 return ID_TABLE_CONTINUE;
2729}
2730
2731void
2732rb_undef_methods_from(VALUE klass, VALUE super)
2733{
2734 struct rb_id_table *mtbl = RCLASS_M_TBL(super);
2735 if (mtbl) {
2736 rb_id_table_foreach(mtbl, undef_method_i, (void *)klass);
2737 }
2738}
2739
2748static inline VALUE
2749special_singleton_class_of(VALUE obj)
2750{
2751 switch (obj) {
2752 case Qnil: return rb_cNilClass;
2753 case Qfalse: return rb_cFalseClass;
2754 case Qtrue: return rb_cTrueClass;
2755 default: return Qnil;
2756 }
2757}
2758
2759VALUE
2760rb_special_singleton_class(VALUE obj)
2761{
2762 return special_singleton_class_of(obj);
2763}
2764
2774static VALUE
2775singleton_class_of(VALUE obj, bool ensure_eigenclass)
2776{
2777 VALUE klass;
2778
2779 switch (TYPE(obj)) {
2780 case T_FIXNUM:
2781 case T_BIGNUM:
2782 case T_FLOAT:
2783 case T_SYMBOL:
2784 rb_raise(rb_eTypeError, "can't define singleton");
2785
2786 case T_FALSE:
2787 case T_TRUE:
2788 case T_NIL:
2789 klass = special_singleton_class_of(obj);
2790 if (NIL_P(klass))
2791 rb_bug("unknown immediate %p", (void *)obj);
2792 return klass;
2793
2794 case T_STRING:
2795 if (CHILLED_STRING_P(obj)) {
2796 CHILLED_STRING_MUTATED(obj);
2797 }
2798 else if (FL_TEST_RAW(obj, RSTRING_FSTR)) {
2799 rb_raise(rb_eTypeError, "can't define singleton");
2800 }
2801 }
2802
2803 bool needs_lock = rb_multi_ractor_p() && rb_ractor_shareable_p(obj);
2804 unsigned int lev;
2805 if (needs_lock) {
2806 RB_VM_LOCK_ENTER_LEV(&lev);
2807 }
2808 {
2809 klass = METACLASS_OF(obj);
2810 if (!(RCLASS_SINGLETON_P(klass) &&
2811 RCLASS_ATTACHED_OBJECT(klass) == obj)) {
2812 klass = rb_make_metaclass(obj, klass);
2813 }
2814 RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
2815 if (ensure_eigenclass && RB_TYPE_P(obj, T_CLASS)) {
2816 /* ensures an exposed class belongs to its own eigenclass */
2817 (void)ENSURE_EIGENCLASS(klass);
2818 }
2819 }
2820 if (needs_lock) {
2821 RB_VM_LOCK_LEAVE_LEV(&lev);
2822 }
2823
2824 return klass;
2825}
2826
2827void
2829{
2830 VALUE klass;
2831
2832 /* Freeze singleton classes of singleton class, as singleton class is frozen, and so on */
2833 /* In each iteration, check the current object's class pointer is the singleton class of the object. */
2834 while ((klass = RBASIC_CLASS(attached_object)) &&
2835 FL_TEST_RAW(klass, FL_SINGLETON) &&
2836 !OBJ_FROZEN_RAW(klass) &&
2837 (RCLASS_ATTACHED_OBJECT(klass) == attached_object)) {
2838 attached_object = klass;
2839 OBJ_FREEZE(attached_object);
2840 }
2841}
2842
2850VALUE
2852{
2853 VALUE klass;
2854
2855 if (SPECIAL_CONST_P(obj)) {
2856 return rb_special_singleton_class(obj);
2857 }
2858 klass = METACLASS_OF(obj);
2859 if (!RCLASS_SINGLETON_P(klass)) return Qnil;
2860 if (RCLASS_ATTACHED_OBJECT(klass) != obj) return Qnil;
2861 return klass;
2862}
2863
2864VALUE
2866{
2867 return singleton_class_of(obj, true);
2868}
2869
2879#ifdef rb_define_singleton_method
2880#undef rb_define_singleton_method
2881#endif
2882void
2883rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
2884{
2885 rb_define_method(singleton_class_of(obj, false), name, func, argc);
2886}
2887
2888#ifdef rb_define_module_function
2889#undef rb_define_module_function
2890#endif
2891void
2892rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
2893{
2894 rb_define_private_method(module, name, func, argc);
2895 rb_define_singleton_method(module, name, func, argc);
2896}
2897
2898#ifdef rb_define_global_function
2899#undef rb_define_global_function
2900#endif
2901void
2902rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
2903{
2904 rb_define_module_function(rb_mKernel, name, func, argc);
2905}
2906
2907void
2908rb_define_alias(VALUE klass, const char *name1, const char *name2)
2909{
2910 rb_alias(klass, rb_intern(name1), rb_intern(name2));
2911}
2912
2913void
2914rb_define_attr(VALUE klass, const char *name, int read, int write)
2915{
2916 rb_attr(klass, rb_intern(name), read, write, FALSE);
2917}
2918
2919VALUE
2920rb_keyword_error_new(const char *error, VALUE keys)
2921{
2922 long i = 0, len = RARRAY_LEN(keys);
2923 VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
2924
2925 if (len > 0) {
2926 rb_str_cat_cstr(error_message, ": ");
2927 while (1) {
2928 const VALUE k = RARRAY_AREF(keys, i);
2929 rb_str_append(error_message, rb_inspect(k));
2930 if (++i >= len) break;
2931 rb_str_cat_cstr(error_message, ", ");
2932 }
2933 }
2934
2935 return rb_exc_new_str(rb_eArgError, error_message);
2936}
2937
2938NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
2939static void
2940rb_keyword_error(const char *error, VALUE keys)
2941{
2942 rb_exc_raise(rb_keyword_error_new(error, keys));
2943}
2944
2945NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
2946static void
2947unknown_keyword_error(VALUE hash, const ID *table, int keywords)
2948{
2949 int i;
2950 for (i = 0; i < keywords; i++) {
2951 st_data_t key = ID2SYM(table[i]);
2952 rb_hash_stlike_delete(hash, &key, NULL);
2953 }
2954 rb_keyword_error("unknown", rb_hash_keys(hash));
2955}
2956
2957
2958static int
2959separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
2960{
2961 VALUE *kwdhash = (VALUE *)arg;
2962 if (!SYMBOL_P(key)) kwdhash++;
2963 if (!*kwdhash) *kwdhash = rb_hash_new();
2964 rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
2965 return ST_CONTINUE;
2966}
2967
2968VALUE
2970{
2971 VALUE parthash[2] = {0, 0};
2972 VALUE hash = *orighash;
2973
2974 if (RHASH_EMPTY_P(hash)) {
2975 *orighash = 0;
2976 return hash;
2977 }
2978 rb_hash_foreach(hash, separate_symbol, (st_data_t)&parthash);
2979 *orighash = parthash[1];
2980 if (parthash[1] && RBASIC_CLASS(hash) != rb_cHash) {
2981 RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
2982 }
2983 return parthash[0];
2984}
2985
2986int
2987rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
2988{
2989 int i = 0, j;
2990 int rest = 0;
2991 VALUE missing = Qnil;
2992 st_data_t key;
2993
2994#define extract_kwarg(keyword, val) \
2995 (key = (st_data_t)(keyword), values ? \
2996 (rb_hash_stlike_delete(keyword_hash, &key, &(val)) || ((val) = Qundef, 0)) : \
2997 rb_hash_stlike_lookup(keyword_hash, key, NULL))
2998
2999 if (NIL_P(keyword_hash)) keyword_hash = 0;
3000
3001 if (optional < 0) {
3002 rest = 1;
3003 optional = -1-optional;
3004 }
3005 if (required) {
3006 for (; i < required; i++) {
3007 VALUE keyword = ID2SYM(table[i]);
3008 if (keyword_hash) {
3009 if (extract_kwarg(keyword, values[i])) {
3010 continue;
3011 }
3012 }
3013 if (NIL_P(missing)) missing = rb_ary_hidden_new(1);
3014 rb_ary_push(missing, keyword);
3015 }
3016 if (!NIL_P(missing)) {
3017 rb_keyword_error("missing", missing);
3018 }
3019 }
3020 j = i;
3021 if (optional && keyword_hash) {
3022 for (i = 0; i < optional; i++) {
3023 if (extract_kwarg(ID2SYM(table[required+i]), values[required+i])) {
3024 j++;
3025 }
3026 }
3027 }
3028 if (!rest && keyword_hash) {
3029 if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : j)) {
3030 unknown_keyword_error(keyword_hash, table, required+optional);
3031 }
3032 }
3033 if (values && !keyword_hash) {
3034 for (i = 0; i < required + optional; i++) {
3035 values[i] = Qundef;
3036 }
3037 }
3038 return j;
3039#undef extract_kwarg
3040}
3041
3043 int kw_flag;
3044 int n_lead;
3045 int n_opt;
3046 int n_trail;
3047 bool f_var;
3048 bool f_hash;
3049 bool f_block;
3050};
3051
3052static void
3053rb_scan_args_parse(int kw_flag, const char *fmt, struct rb_scan_args_t *arg)
3054{
3055 const char *p = fmt;
3056
3057 memset(arg, 0, sizeof(*arg));
3058 arg->kw_flag = kw_flag;
3059
3060 if (ISDIGIT(*p)) {
3061 arg->n_lead = *p - '0';
3062 p++;
3063 if (ISDIGIT(*p)) {
3064 arg->n_opt = *p - '0';
3065 p++;
3066 }
3067 }
3068 if (*p == '*') {
3069 arg->f_var = 1;
3070 p++;
3071 }
3072 if (ISDIGIT(*p)) {
3073 arg->n_trail = *p - '0';
3074 p++;
3075 }
3076 if (*p == ':') {
3077 arg->f_hash = 1;
3078 p++;
3079 }
3080 if (*p == '&') {
3081 arg->f_block = 1;
3082 p++;
3083 }
3084 if (*p != '\0') {
3085 rb_fatal("bad scan arg format: %s", fmt);
3086 }
3087}
3088
3089static int
3090rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *const argv, va_list vargs)
3091{
3092 int i, argi = 0;
3093 VALUE *var, hash = Qnil;
3094#define rb_scan_args_next_param() va_arg(vargs, VALUE *)
3095 const int kw_flag = arg->kw_flag;
3096 const int n_lead = arg->n_lead;
3097 const int n_opt = arg->n_opt;
3098 const int n_trail = arg->n_trail;
3099 const int n_mand = n_lead + n_trail;
3100 const bool f_var = arg->f_var;
3101 const bool f_hash = arg->f_hash;
3102 const bool f_block = arg->f_block;
3103
3104 /* capture an option hash - phase 1: pop from the argv */
3105 if (f_hash && argc > 0) {
3106 VALUE last = argv[argc - 1];
3107 if (rb_scan_args_keyword_p(kw_flag, last)) {
3108 hash = rb_hash_dup(last);
3109 argc--;
3110 }
3111 }
3112
3113 if (argc < n_mand) {
3114 goto argc_error;
3115 }
3116
3117 /* capture leading mandatory arguments */
3118 for (i = 0; i < n_lead; i++) {
3119 var = rb_scan_args_next_param();
3120 if (var) *var = argv[argi];
3121 argi++;
3122 }
3123 /* capture optional arguments */
3124 for (i = 0; i < n_opt; i++) {
3125 var = rb_scan_args_next_param();
3126 if (argi < argc - n_trail) {
3127 if (var) *var = argv[argi];
3128 argi++;
3129 }
3130 else {
3131 if (var) *var = Qnil;
3132 }
3133 }
3134 /* capture variable length arguments */
3135 if (f_var) {
3136 int n_var = argc - argi - n_trail;
3137
3138 var = rb_scan_args_next_param();
3139 if (0 < n_var) {
3140 if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
3141 argi += n_var;
3142 }
3143 else {
3144 if (var) *var = rb_ary_new();
3145 }
3146 }
3147 /* capture trailing mandatory arguments */
3148 for (i = 0; i < n_trail; i++) {
3149 var = rb_scan_args_next_param();
3150 if (var) *var = argv[argi];
3151 argi++;
3152 }
3153 /* capture an option hash - phase 2: assignment */
3154 if (f_hash) {
3155 var = rb_scan_args_next_param();
3156 if (var) *var = hash;
3157 }
3158 /* capture iterator block */
3159 if (f_block) {
3160 var = rb_scan_args_next_param();
3161 if (rb_block_given_p()) {
3162 *var = rb_block_proc();
3163 }
3164 else {
3165 *var = Qnil;
3166 }
3167 }
3168
3169 if (argi == argc) {
3170 return argc;
3171 }
3172
3173 argc_error:
3174 return -(argc + 1);
3175#undef rb_scan_args_next_param
3176}
3177
3178static int
3179rb_scan_args_result(const struct rb_scan_args_t *const arg, int argc)
3180{
3181 const int n_lead = arg->n_lead;
3182 const int n_opt = arg->n_opt;
3183 const int n_trail = arg->n_trail;
3184 const int n_mand = n_lead + n_trail;
3185 const bool f_var = arg->f_var;
3186
3187 if (argc >= 0) {
3188 return argc;
3189 }
3190
3191 argc = -argc - 1;
3192 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
3194}
3195
3196#undef rb_scan_args
3197int
3198rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
3199{
3200 va_list vargs;
3201 struct rb_scan_args_t arg;
3202 rb_scan_args_parse(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, fmt, &arg);
3203 va_start(vargs,fmt);
3204 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
3205 va_end(vargs);
3206 return rb_scan_args_result(&arg, argc);
3207}
3208
3209#undef rb_scan_args_kw
3210int
3211rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt, ...)
3212{
3213 va_list vargs;
3214 struct rb_scan_args_t arg;
3215 rb_scan_args_parse(kw_flag, fmt, &arg);
3216 va_start(vargs,fmt);
3217 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
3218 va_end(vargs);
3219 return rb_scan_args_result(&arg, argc);
3220}
3221
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_method_id(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_protected_method(klass, mid, func, arity)
Defines klass#mid and makes it protected.
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition dllexport.h:45
static VALUE RB_OBJ_FROZEN_RAW(VALUE obj)
This is an implementation detail of RB_OBJ_FROZEN().
Definition fl_type.h:696
static void RB_FL_SET_RAW(VALUE obj, VALUE flags)
This is an implementation detail of RB_FL_SET().
Definition fl_type.h:541
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod)
Identical to rb_class_instance_methods(), except it returns names of methods that are protected only.
Definition class.c:2464
static VALUE class_alloc0(enum ruby_value_type type, VALUE klass, bool boxable)
Allocates a struct RClass for a new class, iclass, or module.
Definition class.c:570
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition class.c:1608
VALUE rb_refinement_new(void)
Creates a new, anonymous refinement.
Definition class.c:1506
VALUE rb_class_new(VALUE super)
Creates a new, anonymous class.
Definition class.c:789
static VALUE make_singleton_class(VALUE obj)
Creates a singleton class for obj.
Definition class.c:1220
VALUE rb_singleton_class_clone(VALUE obj)
Clones a singleton class.
Definition class.c:1059
void rb_prepend_module(VALUE klass, VALUE module)
Identical to rb_include_module(), except it "prepends" the passed module to the klass,...
Definition class.c:1863
VALUE rb_class_subclasses(VALUE klass)
Queries the class's direct descendants.
Definition class.c:2123
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
Definition class.c:2865
VALUE rb_class_attached_object(VALUE klass)
Returns the attached object for a singleton class.
Definition class.c:2267
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
Identical to rb_class_instance_methods(), except it returns names of singleton methods instead of ins...
Definition class.c:2641
VALUE rb_module_new(void)
Creates a new, anonymous module.
Definition class.c:1500
#define META_CLASS_OF_CLASS_CLASS_P(k)
whether k is a meta^(n)-class of Class class
Definition class.c:1139
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
Generates an array of symbols, which are the list of method names defined in the passed class.
Definition class.c:2449
void rb_check_inheritable(VALUE super)
Asserts that the given class can derive a child class.
Definition class.c:774
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
Identical to rb_class_instance_methods(), except it returns names of methods that are public only.
Definition class.c:2502
VALUE rb_class_super_of(VALUE klass)
Internal header for Objspace.
Definition class.c:455
VALUE rb_class_boot(VALUE super)
A utility function that wraps class_alloc.
Definition class.c:707
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
Definition eval.c:443
VALUE rb_define_module_id_under(VALUE outer, ID id)
Identical to rb_define_module_under(), except it takes the name in ID instead of C's string.
Definition class.c:1537
void rb_singleton_class_attached(VALUE klass, VALUE obj)
Attaches a singleton class to its corresponding object.
Definition class.c:1127
VALUE rb_mod_included_modules(VALUE mod)
Queries the list of included modules.
Definition class.c:1943
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super)
Identical to rb_define_class_under(), except it takes the name in ID instead of C's string.
Definition class.c:1476
VALUE rb_mod_ancestors(VALUE mod)
Queries the module's ancestors.
Definition class.c:2011
static VALUE make_metaclass(VALUE klass)
Creates a metaclass of klass
Definition class.c:1184
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
Definition class.c:1400
VALUE rb_mod_include_p(VALUE mod, VALUE mod2)
Queries if the passed module is included by the module.
Definition class.c:1979
void rb_freeze_singleton_class(VALUE attached_object)
This is an implementation detail of RB_OBJ_FREEZE().
Definition class.c:2828
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod)
Identical to rb_class_instance_methods(), except it returns names of methods that are private only.
Definition class.c:2487
#define ENSURE_EIGENCLASS(klass)
ensures klass belongs to its own eigenclass.
Definition class.c:1170
VALUE rb_mod_init_copy(VALUE clone, VALUE orig)
The comment that comes with this function says :nodoc:.
Definition class.c:945
VALUE rb_mod_descendants(VALUE mod)
Queries the module's descendants.
Definition class.c:2219
VALUE rb_singleton_class_get(VALUE obj)
Returns the singleton class of obj, or nil if obj is not a singleton object.
Definition class.c:2851
VALUE rb_define_module_id(ID id)
This is a very badly designed API that creates an anonymous module.
Definition class.c:1513
VALUE rb_define_class_id(ID id, VALUE super)
This is a very badly designed API that creates an anonymous class.
Definition class.c:1379
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition class.c:2908
VALUE rb_extract_keywords(VALUE *orighash)
Splits a hash into two.
Definition class.c:2969
void rb_define_attr(VALUE klass, const char *name, int read, int write)
Defines public accessor method(s) for an attribute.
Definition class.c:2914
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition class.c:2718
int rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt,...)
Identical to rb_scan_args(), except it also accepts kw_splat.
Definition class.c:3211
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.
Definition class.c:3198
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition eval.c:1032
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
Definition class.c:2987
#define TYPE(_)
Old name of rb_type.
Definition value_type.h:108
#define FL_SINGLETON
Old name of RUBY_FL_SINGLETON.
Definition fl_type.h:58
#define OBJ_INIT_COPY(obj, orig)
Old name of RB_OBJ_INIT_COPY.
Definition object.h:41
#define ALLOC
Old name of RB_ALLOC.
Definition memory.h:400
#define T_STRING
Old name of RUBY_T_STRING.
Definition value_type.h:78
#define Qundef
Old name of RUBY_Qundef.
#define T_NIL
Old name of RUBY_T_NIL.
Definition value_type.h:72
#define T_FLOAT
Old name of RUBY_T_FLOAT.
Definition value_type.h:64
#define ID2SYM
Old name of RB_ID2SYM.
Definition symbol.h:44
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
Definition value_type.h:57
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
Definition fl_type.h:131
#define T_FIXNUM
Old name of RUBY_T_FIXNUM.
Definition value_type.h:63
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
Definition assume.h:29
#define ZALLOC
Old name of RB_ZALLOC.
Definition memory.h:402
#define FL_SHAREABLE
Old name of RUBY_FL_SHAREABLE.
Definition fl_type.h:62
#define CLASS_OF
Old name of rb_class_of.
Definition globals.h:205
#define xmalloc
Old name of ruby_xmalloc.
Definition xmalloc.h:53
#define T_MODULE
Old name of RUBY_T_MODULE.
Definition value_type.h:70
#define ISDIGIT
Old name of rb_isdigit.
Definition ctype.h:93
#define T_TRUE
Old name of RUBY_T_TRUE.
Definition value_type.h:81
#define T_ICLASS
Old name of RUBY_T_ICLASS.
Definition value_type.h:66
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:128
#define FL_SET
Old name of RB_FL_SET.
Definition fl_type.h:125
#define T_FALSE
Old name of RUBY_T_FALSE.
Definition value_type.h:61
#define Qtrue
Old name of RUBY_Qtrue.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define NIL_P
Old name of RB_NIL_P.
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
Definition value_type.h:80
#define T_CLASS
Old name of RUBY_T_CLASS.
Definition value_type.h:58
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
Definition value_type.h:85
#define FL_TEST
Old name of RB_FL_TEST.
Definition fl_type.h:127
#define CONST_ID
Old name of RUBY_CONST_ID.
Definition symbol.h:47
#define rb_ary_new2
Old name of rb_ary_new_capa.
Definition array.h:657
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition fl_type.h:126
#define SYMBOL_P
Old name of RB_SYMBOL_P.
Definition value_type.h:88
#define OBJ_FROZEN_RAW
Old name of RB_OBJ_FROZEN_RAW.
Definition fl_type.h:134
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition eval.c:675
VALUE rb_eTypeError
TypeError exception.
Definition error.c:1431
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Identical to rb_exc_new_cstr(), except it takes a Ruby's string instead of C's.
Definition error.c:1482
VALUE rb_cClass
Class class.
Definition object.c:62
VALUE rb_class_superclass(VALUE klass)
Queries the parent of the given class.
Definition object.c:2306
VALUE rb_mKernel
Kernel module.
Definition object.c:59
VALUE rb_cObject
Object class.
Definition object.c:60
VALUE rb_cRefinement
Refinement class.
Definition object.c:63
VALUE rb_cNilClass
NilClass class.
Definition object.c:65
VALUE rb_cHash
Hash class.
Definition hash.c:122
VALUE rb_cFalseClass
FalseClass class.
Definition object.c:67
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
Definition object.c:234
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition object.c:668
VALUE rb_cBasicObject
BasicObject class.
Definition object.c:58
VALUE rb_cModule
Module class.
Definition object.c:61
VALUE rb_class_real(VALUE klass)
Finds a "real" class.
Definition object.c:225
VALUE rb_cTrueClass
TrueClass class.
Definition object.c:66
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
Definition gc.h:468
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition gc.h:456
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition vm_eval.c:1123
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Identical to rb_ary_new_from_args(), except how objects are passed.
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len)
Destructively appends multiple elements at the end of the array.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
VALUE rb_ary_resize(VALUE ary, long len)
Expands or shrinks the passed array to the passed length.
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
Definition error.h:35
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition error.h:284
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
Definition proc.c:1575
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
Definition string.c:3897
#define rb_str_cat_cstr(buf, str)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1657
void rb_const_set(VALUE space, ID name, VALUE val)
Names a constant.
Definition variable.c:3886
VALUE rb_const_get_at(VALUE space, ID name)
Identical to rb_const_defined_at(), except it returns the actual defined value.
Definition variable.c:3414
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.
Definition variable.c:437
int rb_const_defined_at(VALUE space, ID name)
Identical to rb_const_defined(), except it doesn't look for parent classes.
Definition variable.c:3746
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
Definition variable.c:394
void rb_alias(VALUE klass, ID dst, ID src)
Resembles alias.
Definition vm_method.c:2857
void rb_attr(VALUE klass, ID name, int need_reader, int need_writer, int honour_visibility)
This function resembles now-deprecated Module#attr.
Definition vm_method.c:2437
void rb_clear_constant_cache_for_id(ID id)
Clears the inline constant caches associated with a particular ID.
Definition vm_method.c:333
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
Definition symbol.h:285
int len
Length of the buffer.
Definition io.h:8
static bool rb_ractor_shareable_p(VALUE obj)
Queries if multiple Ractors can share the passed object or not.
Definition ractor.h:249
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
Definition memory.h:372
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition memory.h:167
VALUE type(ANYARGS)
ANYARGS-ed function type.
void rb_hash_foreach(VALUE q, int_type *w, VALUE e)
Iteration over the given hash.
#define RARRAY_LEN
Just another name of rb_array_len.
Definition rarray.h:50
#define RARRAY_AREF(a, i)
Definition rarray.h:402
static VALUE RBASIC_CLASS(VALUE obj)
Queries the class of an object.
Definition rbasic.h:166
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
Definition rclass.h:44
#define RHASH_SIZE(h)
Queries the size of the hash.
Definition rhash.h:69
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
Definition rhash.h:79
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
Same behaviour as rb_scan_args().
Definition scan_args.h:50
#define RTEST
This is an old name of RB_TEST.
#define ANYARGS
Functions declared using this macro take arbitrary arguments, including void.
Definition stdarg.h:64
Definition class.h:82
Definition class.c:2329
Internal header for Ruby Box.
Definition box.h:14
Definition constant.h:33
Internal header for Class.
Definition class.h:30
Definition method.h:55
Definition st.h:79
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
Definition value_type.h:425
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition value_type.h:376
ruby_value_type
C-level type of an object.
Definition value_type.h:113