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