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