Ruby 3.5.0dev (2025-10-30 revision 481f994449f35ce4050757561e89a776903ee425)
class.c (481f994449f35ce4050757561e89a776903ee425)
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;
1607 const rb_namespace_t *ns = rb_current_namespace();
1608
1609 id = rb_intern(name);
1610 if (NAMESPACE_OPTIONAL_P(ns)) {
1611 return rb_define_class_id_under(ns->ns_object, id, super);
1612 }
1613 if (rb_const_defined(rb_cObject, id)) {
1614 klass = rb_const_get(rb_cObject, id);
1615 if (!RB_TYPE_P(klass, T_CLASS)) {
1616 rb_raise(rb_eTypeError, "%s is not a class (%"PRIsVALUE")",
1617 name, rb_obj_class(klass));
1618 }
1619 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
1620 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
1621 }
1622
1623 /* Class may have been defined in Ruby and not pin-rooted */
1624 rb_vm_register_global_object(klass);
1625 return klass;
1626 }
1627 if (!super) {
1628 rb_raise(rb_eArgError, "no super class for '%s'", name);
1629 }
1630 klass = rb_define_class_id(id, super);
1631 rb_vm_register_global_object(klass);
1632 rb_const_set(rb_cObject, id, klass);
1633 rb_class_inherited(super, klass);
1634
1635 return klass;
1636}
1637
1638VALUE
1639rb_define_class_under(VALUE outer, const char *name, VALUE super)
1640{
1641 return rb_define_class_id_under(outer, rb_intern(name), super);
1642}
1643
1644VALUE
1645rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super)
1646{
1647 VALUE klass;
1648
1649 if (rb_const_defined_at(outer, id)) {
1650 klass = rb_const_get_at(outer, id);
1651 if (!RB_TYPE_P(klass, T_CLASS)) {
1652 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a class"
1653 " (%"PRIsVALUE")",
1654 outer, rb_id2str(id), rb_obj_class(klass));
1655 }
1656 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
1657 rb_raise(rb_eTypeError, "superclass mismatch for class "
1658 "%"PRIsVALUE"::%"PRIsVALUE""
1659 " (%"PRIsVALUE" is given but was %"PRIsVALUE")",
1660 outer, rb_id2str(id), RCLASS_SUPER(klass), super);
1661 }
1662
1663 return klass;
1664 }
1665 if (!super) {
1666 rb_raise(rb_eArgError, "no super class for '%"PRIsVALUE"::%"PRIsVALUE"'",
1667 rb_class_path(outer), rb_id2str(id));
1668 }
1669 klass = rb_define_class_id(id, super);
1670 rb_set_class_path_string(klass, outer, rb_id2str(id));
1671 rb_const_set(outer, id, klass);
1672 rb_class_inherited(super, klass);
1673
1674 return klass;
1675}
1676
1677VALUE
1679{
1680 VALUE klass = rb_define_class_id_under_no_pin(outer, id, super);
1681 rb_vm_register_global_object(klass);
1682 return klass;
1683}
1684
1685VALUE
1686rb_module_s_alloc(VALUE klass)
1687{
1688 VALUE mod = class_alloc(T_MODULE, klass);
1689 class_initialize_method_table(mod);
1690 return mod;
1691}
1692
1693static inline VALUE
1694module_new(VALUE klass)
1695{
1696 VALUE mdl = class_alloc(T_MODULE, klass);
1697 class_initialize_method_table(mdl);
1698 return (VALUE)mdl;
1699}
1700
1701VALUE
1703{
1704 return module_new(rb_cModule);
1705}
1706
1707VALUE
1709{
1710 return module_new(rb_cRefinement);
1711}
1712
1713// Kept for compatibility. Use rb_module_new() instead.
1714VALUE
1716{
1717 return rb_module_new();
1718}
1719
1720VALUE
1721rb_define_module(const char *name)
1722{
1723 VALUE module;
1724 ID id;
1725 const rb_namespace_t *ns = rb_current_namespace();
1726
1727 id = rb_intern(name);
1728 if (NAMESPACE_OPTIONAL_P(ns)) {
1729 return rb_define_module_id_under(ns->ns_object, id);
1730 }
1731 if (rb_const_defined(rb_cObject, id)) {
1732 module = rb_const_get(rb_cObject, id);
1733 if (!RB_TYPE_P(module, T_MODULE)) {
1734 rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
1735 name, rb_obj_class(module));
1736 }
1737 /* Module may have been defined in Ruby and not pin-rooted */
1738 rb_vm_register_global_object(module);
1739 return module;
1740 }
1741 module = rb_module_new();
1742 rb_vm_register_global_object(module);
1743 rb_const_set(rb_cObject, id, module);
1744
1745 return module;
1746}
1747
1748VALUE
1749rb_define_module_under(VALUE outer, const char *name)
1750{
1751 return rb_define_module_id_under(outer, rb_intern(name));
1752}
1753
1754VALUE
1756{
1757 VALUE module;
1758
1759 if (rb_const_defined_at(outer, id)) {
1760 module = rb_const_get_at(outer, id);
1761 if (!RB_TYPE_P(module, T_MODULE)) {
1762 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a module"
1763 " (%"PRIsVALUE")",
1764 outer, rb_id2str(id), rb_obj_class(module));
1765 }
1766 /* Module may have been defined in Ruby and not pin-rooted */
1767 rb_vm_register_global_object(module);
1768 return module;
1769 }
1770 module = rb_module_new();
1771 rb_const_set(outer, id, module);
1772 rb_set_class_path_string(module, outer, rb_id2str(id));
1773 rb_vm_register_global_object(module);
1774
1775 return module;
1776}
1777
1778VALUE
1779rb_include_class_new(VALUE module, VALUE super)
1780{
1781 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
1782
1783 RCLASS_SET_M_TBL(klass, RCLASS_WRITABLE_M_TBL(module));
1784
1785 RCLASS_SET_ORIGIN(klass, klass);
1786 if (BUILTIN_TYPE(module) == T_ICLASS) {
1787 module = METACLASS_OF(module);
1788 }
1789 RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
1790 if (RCLASS_WRITABLE_CONST_TBL(module)) {
1791 RCLASS_SET_CONST_TBL(klass, RCLASS_WRITABLE_CONST_TBL(module), true);
1792 }
1793 else {
1794 RCLASS_WRITE_CONST_TBL(module, rb_id_table_create(0), false);
1795 RCLASS_SET_CONST_TBL(klass, RCLASS_WRITABLE_CONST_TBL(module), true);
1796 }
1797
1798 RCLASS_SET_CVC_TBL(klass, RCLASS_WRITABLE_CVC_TBL(module));
1799
1800 class_associate_super(klass, super, true);
1801 RBASIC_SET_CLASS(klass, module);
1802
1803 return (VALUE)klass;
1804}
1805
1806static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
1807
1808static void
1809ensure_includable(VALUE klass, VALUE module)
1810{
1811 rb_class_modify_check(klass);
1812 Check_Type(module, T_MODULE);
1813 rb_class_set_initialized(module);
1814 if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
1815 rb_raise(rb_eArgError, "refinement module is not allowed");
1816 }
1817}
1818
1819void
1821{
1822 int changed = 0;
1823
1824 ensure_includable(klass, module);
1825
1826 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
1827 if (changed < 0)
1828 rb_raise(rb_eArgError, "cyclic include detected");
1829
1830 if (RB_TYPE_P(klass, T_MODULE)) {
1831 rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES_FIRST(klass);
1832 while (iclass) {
1833 int do_include = 1;
1834 VALUE check_class = iclass->klass;
1835 /* During lazy sweeping, iclass->klass could be a dead object that
1836 * has not yet been swept. */
1837 if (!rb_objspace_garbage_object_p(check_class)) {
1838 while (check_class) {
1839 RUBY_ASSERT(!rb_objspace_garbage_object_p(check_class));
1840
1841 if (RB_TYPE_P(check_class, T_ICLASS) &&
1842 (METACLASS_OF(check_class) == module)) {
1843 do_include = 0;
1844 }
1845 check_class = RCLASS_SUPER(check_class);
1846 }
1847
1848 if (do_include) {
1849 include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
1850 }
1851 }
1852
1853 iclass = iclass->next;
1854 }
1855 }
1856}
1857
1858static enum rb_id_table_iterator_result
1859add_refined_method_entry_i(ID key, VALUE value, void *data)
1860{
1861 rb_add_refined_method_entry((VALUE)data, key);
1862 return ID_TABLE_CONTINUE;
1863}
1864
1865static enum rb_id_table_iterator_result
1866clear_module_cache_i(ID id, VALUE val, void *data)
1867{
1868 VALUE klass = (VALUE)data;
1869 rb_clear_method_cache(klass, id);
1870 return ID_TABLE_CONTINUE;
1871}
1872
1873static bool
1874module_in_super_chain(const VALUE klass, VALUE module)
1875{
1876 struct rb_id_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
1877 if (klass_m_tbl) {
1878 while (module) {
1879 if (klass_m_tbl == RCLASS_M_TBL(module))
1880 return true;
1881 module = RCLASS_SUPER(module);
1882 }
1883 }
1884 return false;
1885}
1886
1887// For each ID key in the class constant table, we're going to clear the VM's
1888// inline constant caches associated with it.
1889static enum rb_id_table_iterator_result
1890clear_constant_cache_i(ID id, VALUE value, void *data)
1891{
1893 return ID_TABLE_CONTINUE;
1894}
1895
1896static int
1897do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super, bool check_cyclic)
1898{
1899 VALUE p, iclass, origin_stack = 0;
1900 int method_changed = 0;
1901 long origin_len;
1902 VALUE klass_origin = RCLASS_ORIGIN(klass);
1903 VALUE original_klass = klass;
1904
1905 if (check_cyclic && module_in_super_chain(klass, module))
1906 return -1;
1907
1908 while (module) {
1909 int c_seen = FALSE;
1910 int superclass_seen = FALSE;
1911 struct rb_id_table *tbl;
1912
1913 if (klass == c) {
1914 c_seen = TRUE;
1915 }
1916 if (klass_origin != c || search_super) {
1917 /* ignore if the module included already in superclasses for include,
1918 * ignore if the module included before origin class for prepend
1919 */
1920 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
1921 int type = BUILTIN_TYPE(p);
1922 if (klass_origin == p && !search_super)
1923 break;
1924 if (c == p)
1925 c_seen = TRUE;
1926 if (type == T_ICLASS) {
1927 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
1928 if (!superclass_seen && c_seen) {
1929 c = p; /* move insertion point */
1930 }
1931 goto skip;
1932 }
1933 }
1934 else if (type == T_CLASS) {
1935 superclass_seen = TRUE;
1936 }
1937 }
1938 }
1939
1940 VALUE super_class = RCLASS_SUPER(c);
1941
1942 // invalidate inline method cache
1943 RB_DEBUG_COUNTER_INC(cvar_include_invalidate);
1944 ruby_vm_global_cvar_state++;
1945 tbl = RCLASS_M_TBL(module);
1946 if (tbl && rb_id_table_size(tbl)) {
1947 if (search_super) { // include
1948 if (super_class && !RB_TYPE_P(super_class, T_MODULE)) {
1949 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)super_class);
1950 }
1951 }
1952 else { // prepend
1953 if (!RB_TYPE_P(original_klass, T_MODULE)) {
1954 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)original_klass);
1955 }
1956 }
1957 method_changed = 1;
1958 }
1959
1960 // setup T_ICLASS for the include/prepend module
1961 iclass = rb_include_class_new(module, super_class);
1962 c = rb_class_set_super(c, iclass);
1963 RCLASS_SET_INCLUDER(iclass, klass);
1964 if (module != RCLASS_ORIGIN(module)) {
1965 if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
1966 VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
1967 rb_ary_cat(origin_stack, origin, 2);
1968 }
1969 else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 &&
1970 RARRAY_AREF(origin_stack, origin_len - 1) == module) {
1971 RCLASS_WRITE_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
1972 RICLASS_WRITE_ORIGIN_SHARED_MTBL(iclass);
1973 rb_ary_resize(origin_stack, origin_len);
1974 }
1975
1976 VALUE m = module;
1977 if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
1978 rb_module_add_to_subclasses_list(m, iclass);
1979
1980 if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
1981 VALUE refined_class =
1982 rb_refinement_module_get_refined_class(klass);
1983
1984 rb_id_table_foreach(RCLASS_M_TBL(module), add_refined_method_entry_i, (void *)refined_class);
1986 }
1987
1988 tbl = RCLASS_CONST_TBL(module);
1989 if (tbl && rb_id_table_size(tbl))
1990 rb_id_table_foreach(tbl, clear_constant_cache_i, NULL);
1991 skip:
1992 module = RCLASS_SUPER(module);
1993 }
1994
1995 return method_changed;
1996}
1997
1998static int
1999include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
2000{
2001 return do_include_modules_at(klass, c, module, search_super, true);
2002}
2003
2004static enum rb_id_table_iterator_result
2005move_refined_method(ID key, VALUE value, void *data)
2006{
2007 rb_method_entry_t *me = (rb_method_entry_t *)value;
2008
2009 if (me->def->type == VM_METHOD_TYPE_REFINED) {
2010 VALUE klass = (VALUE)data;
2011 struct rb_id_table *tbl = RCLASS_WRITABLE_M_TBL(klass);
2012
2013 if (me->def->body.refined.orig_me) {
2014 const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
2015 RB_OBJ_WRITE(me, &me->def->body.refined.orig_me, NULL);
2016 new_me = rb_method_entry_clone(me);
2017 rb_method_table_insert(klass, tbl, key, new_me);
2018 rb_method_entry_copy(me, orig_me);
2019 return ID_TABLE_CONTINUE;
2020 }
2021 else {
2022 rb_method_table_insert(klass, tbl, key, me);
2023 return ID_TABLE_DELETE;
2024 }
2025 }
2026 else {
2027 return ID_TABLE_CONTINUE;
2028 }
2029}
2030
2031static enum rb_id_table_iterator_result
2032cache_clear_refined_method(ID key, VALUE value, void *data)
2033{
2034 rb_method_entry_t *me = (rb_method_entry_t *) value;
2035
2036 if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
2037 VALUE klass = (VALUE)data;
2038 rb_clear_method_cache(klass, me->called_id);
2039 }
2040 // Refined method entries without an orig_me is going to stay in the method
2041 // table of klass, like before the move, so no need to clear the cache.
2042
2043 return ID_TABLE_CONTINUE;
2044}
2045
2046static bool
2047ensure_origin(VALUE klass)
2048{
2049 VALUE origin = RCLASS_ORIGIN(klass);
2050 if (origin == klass) {
2051 origin = class_alloc(T_ICLASS, klass);
2052 RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass));
2053 rb_class_set_super(origin, RCLASS_SUPER(klass));
2054 rb_class_set_super(klass, origin); // writes origin into RCLASS_SUPER(klass)
2055 RCLASS_WRITE_ORIGIN(klass, origin);
2056
2057 // RCLASS_WRITE_ORIGIN marks origin as an origin, so this is the first
2058 // point that it sees M_TBL and may mark it
2059 rb_gc_writebarrier_remember(origin);
2060
2061 class_clear_method_table(klass);
2062 rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
2063 rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
2064 return true;
2065 }
2066 return false;
2067}
2068
2069void
2071{
2072 int changed;
2073 bool klass_had_no_origin;
2074
2075 ensure_includable(klass, module);
2076 if (module_in_super_chain(klass, module))
2077 rb_raise(rb_eArgError, "cyclic prepend detected");
2078
2079 klass_had_no_origin = ensure_origin(klass);
2080 changed = do_include_modules_at(klass, klass, module, FALSE, false);
2081 RUBY_ASSERT(changed >= 0); // already checked for cyclic prepend above
2082 if (changed) {
2083 rb_vm_check_redefinition_by_prepend(klass);
2084 }
2085 if (RB_TYPE_P(klass, T_MODULE)) {
2086 rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES_FIRST(klass);
2087 VALUE klass_origin = RCLASS_ORIGIN(klass);
2088 struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
2089 struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
2090 while (iclass) {
2091 /* During lazy sweeping, iclass->klass could be a dead object that
2092 * has not yet been swept. */
2093 if (!rb_objspace_garbage_object_p(iclass->klass)) {
2094 const VALUE subclass = iclass->klass;
2095 if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(subclass)) {
2096 // backfill an origin iclass to handle refinements and future prepends
2097 rb_id_table_foreach(RCLASS_M_TBL(subclass), clear_module_cache_i, (void *)subclass);
2098 RCLASS_WRITE_M_TBL(subclass, klass_m_tbl);
2099 VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(subclass));
2100 rb_class_set_super(subclass, origin);
2101 RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(subclass));
2102 RCLASS_WRITE_ORIGIN(subclass, origin);
2103 RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
2104 }
2105 include_modules_at(subclass, subclass, module, FALSE);
2106 }
2107
2108 iclass = iclass->next;
2109 }
2110 }
2111}
2112
2113/*
2114 * call-seq:
2115 * mod.included_modules -> array
2116 *
2117 * Returns the list of modules included or prepended in <i>mod</i>
2118 * or one of <i>mod</i>'s ancestors.
2119 *
2120 * module Sub
2121 * end
2122 *
2123 * module Mixin
2124 * prepend Sub
2125 * end
2126 *
2127 * module Outer
2128 * include Mixin
2129 * end
2130 *
2131 * Mixin.included_modules #=> [Sub]
2132 * Outer.included_modules #=> [Sub, Mixin]
2133 */
2134
2135VALUE
2137{
2138 VALUE ary = rb_ary_new();
2139 VALUE p;
2140 VALUE origin = RCLASS_ORIGIN(mod);
2141
2142 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
2143 if (p != origin && RCLASS_ORIGIN(p) == p && BUILTIN_TYPE(p) == T_ICLASS) {
2144 VALUE m = METACLASS_OF(p);
2145 if (RB_TYPE_P(m, T_MODULE))
2146 rb_ary_push(ary, m);
2147 }
2148 }
2149 return ary;
2150}
2151
2152/*
2153 * call-seq:
2154 * mod.include?(module) -> true or false
2155 *
2156 * Returns <code>true</code> if <i>module</i> is included
2157 * or prepended in <i>mod</i> or one of <i>mod</i>'s ancestors.
2158 *
2159 * module A
2160 * end
2161 * class B
2162 * include A
2163 * end
2164 * class C < B
2165 * end
2166 * B.include?(A) #=> true
2167 * C.include?(A) #=> true
2168 * A.include?(A) #=> false
2169 */
2170
2171VALUE
2173{
2174 VALUE p;
2175
2176 Check_Type(mod2, T_MODULE);
2177 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
2178 if (BUILTIN_TYPE(p) == T_ICLASS && !RICLASS_IS_ORIGIN_P(p)) {
2179 if (METACLASS_OF(p) == mod2) return Qtrue;
2180 }
2181 }
2182 return Qfalse;
2183}
2184
2185/*
2186 * call-seq:
2187 * mod.ancestors -> array
2188 *
2189 * Returns a list of modules included/prepended in <i>mod</i>
2190 * (including <i>mod</i> itself).
2191 *
2192 * module Mod
2193 * include Math
2194 * include Comparable
2195 * prepend Enumerable
2196 * end
2197 *
2198 * Mod.ancestors #=> [Enumerable, Mod, Comparable, Math]
2199 * Math.ancestors #=> [Math]
2200 * Enumerable.ancestors #=> [Enumerable]
2201 */
2202
2203VALUE
2205{
2206 VALUE p, ary = rb_ary_new();
2207 VALUE refined_class = Qnil;
2208 if (BUILTIN_TYPE(mod) == T_MODULE && FL_TEST(mod, RMODULE_IS_REFINEMENT)) {
2209 refined_class = rb_refinement_module_get_refined_class(mod);
2210 }
2211
2212 for (p = mod; p; p = RCLASS_SUPER(p)) {
2213 if (p == refined_class) break;
2214 if (p != RCLASS_ORIGIN(p)) continue;
2215 if (BUILTIN_TYPE(p) == T_ICLASS) {
2216 rb_ary_push(ary, METACLASS_OF(p));
2217 }
2218 else {
2219 rb_ary_push(ary, p);
2220 }
2221 }
2222 return ary;
2223}
2224
2226{
2227 VALUE buffer;
2228 long count;
2229 long maxcount;
2230 bool immediate_only;
2231};
2232
2233static void
2234class_descendants_recursive(VALUE klass, VALUE v)
2235{
2236 struct subclass_traverse_data *data = (struct subclass_traverse_data *) v;
2237
2238 if (BUILTIN_TYPE(klass) == T_CLASS && !RCLASS_SINGLETON_P(klass)) {
2239 if (data->buffer && data->count < data->maxcount && !rb_objspace_garbage_object_p(klass)) {
2240 // assumes that this does not cause GC as long as the length does not exceed the capacity
2241 rb_ary_push(data->buffer, klass);
2242 }
2243 data->count++;
2244 if (!data->immediate_only) {
2245 rb_class_foreach_subclass(klass, class_descendants_recursive, v);
2246 }
2247 }
2248 else {
2249 rb_class_foreach_subclass(klass, class_descendants_recursive, v);
2250 }
2251}
2252
2253static VALUE
2254class_descendants(VALUE klass, bool immediate_only)
2255{
2256 struct subclass_traverse_data data = { Qfalse, 0, -1, immediate_only };
2257
2258 // estimate the count of subclasses
2259 rb_class_foreach_subclass(klass, class_descendants_recursive, (VALUE) &data);
2260
2261 // the following allocation may cause GC which may change the number of subclasses
2262 data.buffer = rb_ary_new_capa(data.count);
2263 data.maxcount = data.count;
2264 data.count = 0;
2265
2266 size_t gc_count = rb_gc_count();
2267
2268 // enumerate subclasses
2269 rb_class_foreach_subclass(klass, class_descendants_recursive, (VALUE) &data);
2270
2271 if (gc_count != rb_gc_count()) {
2272 rb_bug("GC must not occur during the subclass iteration of Class#descendants");
2273 }
2274
2275 return data.buffer;
2276}
2277
2278/*
2279 * call-seq:
2280 * subclasses -> array
2281 *
2282 * Returns an array of classes where the receiver is the
2283 * direct superclass of the class, excluding singleton classes.
2284 * The order of the returned array is not defined.
2285 *
2286 * class A; end
2287 * class B < A; end
2288 * class C < B; end
2289 * class D < A; end
2290 *
2291 * A.subclasses #=> [D, B]
2292 * B.subclasses #=> [C]
2293 * C.subclasses #=> []
2294 *
2295 * Anonymous subclasses (not associated with a constant) are
2296 * returned, too:
2297 *
2298 * c = Class.new(A)
2299 * A.subclasses # => [#<Class:0x00007f003c77bd78>, D, B]
2300 *
2301 * Note that the parent does not hold references to subclasses
2302 * and doesn't prevent them from being garbage collected. This
2303 * means that the subclass might disappear when all references
2304 * to it are dropped:
2305 *
2306 * # drop the reference to subclass, it can be garbage-collected now
2307 * c = nil
2308 *
2309 * A.subclasses
2310 * # It can be
2311 * # => [#<Class:0x00007f003c77bd78>, D, B]
2312 * # ...or just
2313 * # => [D, B]
2314 * # ...depending on whether garbage collector was run
2315 */
2316
2317VALUE
2319{
2320 return class_descendants(klass, true);
2321}
2322
2323/*
2324 * call-seq:
2325 * attached_object -> object
2326 *
2327 * Returns the object for which the receiver is the singleton class.
2328 *
2329 * Raises an TypeError if the class is not a singleton class.
2330 *
2331 * class Foo; end
2332 *
2333 * Foo.singleton_class.attached_object #=> Foo
2334 * Foo.attached_object #=> TypeError: `Foo' is not a singleton class
2335 * Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370>
2336 * TrueClass.attached_object #=> TypeError: `TrueClass' is not a singleton class
2337 * NilClass.attached_object #=> TypeError: `NilClass' is not a singleton class
2338 */
2339
2340VALUE
2342{
2343 if (!RCLASS_SINGLETON_P(klass)) {
2344 rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass);
2345 }
2346
2347 return RCLASS_ATTACHED_OBJECT(klass);
2348}
2349
2350static void
2351ins_methods_push(st_data_t name, st_data_t ary)
2352{
2353 rb_ary_push((VALUE)ary, ID2SYM((ID)name));
2354}
2355
2356static int
2357ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
2358{
2359 switch ((rb_method_visibility_t)type) {
2360 case METHOD_VISI_UNDEF:
2361 case METHOD_VISI_PRIVATE:
2362 break;
2363 default: /* everything but private */
2364 ins_methods_push(name, ary);
2365 break;
2366 }
2367 return ST_CONTINUE;
2368}
2369
2370static int
2371ins_methods_type_i(st_data_t name, st_data_t type, st_data_t ary, rb_method_visibility_t visi)
2372{
2373 if ((rb_method_visibility_t)type == visi) {
2374 ins_methods_push(name, ary);
2375 }
2376 return ST_CONTINUE;
2377}
2378
2379static int
2380ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
2381{
2382 return ins_methods_type_i(name, type, ary, METHOD_VISI_PROTECTED);
2383}
2384
2385static int
2386ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
2387{
2388 return ins_methods_type_i(name, type, ary, METHOD_VISI_PRIVATE);
2389}
2390
2391static int
2392ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
2393{
2394 return ins_methods_type_i(name, type, ary, METHOD_VISI_PUBLIC);
2395}
2396
2397static int
2398ins_methods_undef_i(st_data_t name, st_data_t type, st_data_t ary)
2399{
2400 return ins_methods_type_i(name, type, ary, METHOD_VISI_UNDEF);
2401}
2402
2404 st_table *list;
2405 int recur;
2406};
2407
2408static enum rb_id_table_iterator_result
2409method_entry_i(ID key, VALUE value, void *data)
2410{
2411 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
2412 struct method_entry_arg *arg = (struct method_entry_arg *)data;
2413 rb_method_visibility_t type;
2414
2415 if (me->def->type == VM_METHOD_TYPE_REFINED) {
2416 VALUE owner = me->owner;
2417 me = rb_resolve_refined_method(Qnil, me);
2418 if (!me) return ID_TABLE_CONTINUE;
2419 if (!arg->recur && me->owner != owner) return ID_TABLE_CONTINUE;
2420 }
2421 if (!st_is_member(arg->list, key)) {
2422 if (UNDEFINED_METHOD_ENTRY_P(me)) {
2423 type = METHOD_VISI_UNDEF; /* none */
2424 }
2425 else {
2426 type = METHOD_ENTRY_VISI(me);
2427 RUBY_ASSERT(type != METHOD_VISI_UNDEF);
2428 }
2429 st_add_direct(arg->list, key, (st_data_t)type);
2430 }
2431 return ID_TABLE_CONTINUE;
2432}
2433
2434static void
2435add_instance_method_list(VALUE mod, struct method_entry_arg *me_arg)
2436{
2437 struct rb_id_table *m_tbl = RCLASS_M_TBL(mod);
2438 if (!m_tbl) return;
2439 rb_id_table_foreach(m_tbl, method_entry_i, me_arg);
2440}
2441
2442static bool
2443particular_class_p(VALUE mod)
2444{
2445 if (!mod) return false;
2446 if (RCLASS_SINGLETON_P(mod)) return true;
2447 if (BUILTIN_TYPE(mod) == T_ICLASS) return true;
2448 return false;
2449}
2450
2451static VALUE
2452class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
2453{
2454 VALUE ary;
2455 int recur = TRUE, prepended = 0;
2456 struct method_entry_arg me_arg;
2457
2458 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
2459
2460 me_arg.list = st_init_numtable();
2461 me_arg.recur = recur;
2462
2463 if (obj) {
2464 for (; particular_class_p(mod); mod = RCLASS_SUPER(mod)) {
2465 add_instance_method_list(mod, &me_arg);
2466 }
2467 }
2468
2469 if (!recur && RCLASS_ORIGIN(mod) != mod) {
2470 mod = RCLASS_ORIGIN(mod);
2471 prepended = 1;
2472 }
2473
2474 for (; mod; mod = RCLASS_SUPER(mod)) {
2475 add_instance_method_list(mod, &me_arg);
2476 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
2477 if (!recur) break;
2478 }
2479 ary = rb_ary_new2(me_arg.list->num_entries);
2480 st_foreach(me_arg.list, func, ary);
2481 st_free_table(me_arg.list);
2482
2483 return ary;
2484}
2485
2486/*
2487 * call-seq:
2488 * mod.instance_methods(include_super=true) -> array
2489 *
2490 * Returns an array containing the names of the public and protected instance
2491 * methods in the receiver. For a module, these are the public and protected methods;
2492 * for a class, they are the instance (not singleton) methods. If the optional
2493 * parameter is <code>false</code>, the methods of any ancestors are not included.
2494 *
2495 * module A
2496 * def method1() end
2497 * end
2498 * class B
2499 * include A
2500 * def method2() end
2501 * end
2502 * class C < B
2503 * def method3() end
2504 * end
2505 *
2506 * A.instance_methods(false) #=> [:method1]
2507 * B.instance_methods(false) #=> [:method2]
2508 * B.instance_methods(true).include?(:method1) #=> true
2509 * C.instance_methods(false) #=> [:method3]
2510 * C.instance_methods.include?(:method2) #=> true
2511 *
2512 * Note that method visibility changes in the current class, as well as aliases,
2513 * are considered as methods of the current class by this method:
2514 *
2515 * class C < B
2516 * alias method4 method2
2517 * protected :method2
2518 * end
2519 * C.instance_methods(false).sort #=> [:method2, :method3, :method4]
2520 */
2521
2522VALUE
2523rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
2524{
2525 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
2526}
2527
2528/*
2529 * call-seq:
2530 * mod.protected_instance_methods(include_super=true) -> array
2531 *
2532 * Returns a list of the protected instance methods defined in
2533 * <i>mod</i>. If the optional parameter is <code>false</code>, the
2534 * methods of any ancestors are not included.
2535 */
2536
2537VALUE
2539{
2540 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
2541}
2542
2543/*
2544 * call-seq:
2545 * mod.private_instance_methods(include_super=true) -> array
2546 *
2547 * Returns a list of the private instance methods defined in
2548 * <i>mod</i>. If the optional parameter is <code>false</code>, the
2549 * methods of any ancestors are not included.
2550 *
2551 * module Mod
2552 * def method1() end
2553 * private :method1
2554 * def method2() end
2555 * end
2556 * Mod.instance_methods #=> [:method2]
2557 * Mod.private_instance_methods #=> [:method1]
2558 */
2559
2560VALUE
2562{
2563 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
2564}
2565
2566/*
2567 * call-seq:
2568 * mod.public_instance_methods(include_super=true) -> array
2569 *
2570 * Returns a list of the public instance methods defined in <i>mod</i>.
2571 * If the optional parameter is <code>false</code>, the methods of
2572 * any ancestors are not included.
2573 */
2574
2575VALUE
2577{
2578 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
2579}
2580
2581/*
2582 * call-seq:
2583 * mod.undefined_instance_methods -> array
2584 *
2585 * Returns a list of the undefined instance methods defined in <i>mod</i>.
2586 * The undefined methods of any ancestors are not included.
2587 */
2588
2589VALUE
2590rb_class_undefined_instance_methods(VALUE mod)
2591{
2592 VALUE include_super = Qfalse;
2593 return class_instance_method_list(1, &include_super, mod, 0, ins_methods_undef_i);
2594}
2595
2596/*
2597 * call-seq:
2598 * obj.methods(regular=true) -> array
2599 *
2600 * Returns a list of the names of public and protected methods of
2601 * <i>obj</i>. This will include all the methods accessible in
2602 * <i>obj</i>'s ancestors.
2603 * If the optional parameter is <code>false</code>, it
2604 * returns an array of <i>obj</i>'s public and protected singleton methods,
2605 * the array will not include methods in modules included in <i>obj</i>.
2606 *
2607 * class Klass
2608 * def klass_method()
2609 * end
2610 * end
2611 * k = Klass.new
2612 * k.methods[0..9] #=> [:klass_method, :nil?, :===,
2613 * # :==~, :!, :eql?
2614 * # :hash, :<=>, :class, :singleton_class]
2615 * k.methods.length #=> 56
2616 *
2617 * k.methods(false) #=> []
2618 * def k.singleton_method; end
2619 * k.methods(false) #=> [:singleton_method]
2620 *
2621 * module M123; def m123; end end
2622 * k.extend M123
2623 * k.methods(false) #=> [:singleton_method]
2624 */
2625
2626VALUE
2627rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
2628{
2629 rb_check_arity(argc, 0, 1);
2630 if (argc > 0 && !RTEST(argv[0])) {
2631 return rb_obj_singleton_methods(argc, argv, obj);
2632 }
2633 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
2634}
2635
2636/*
2637 * call-seq:
2638 * obj.protected_methods(all=true) -> array
2639 *
2640 * Returns the list of protected methods accessible to <i>obj</i>. If
2641 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2642 * in the receiver will be listed.
2643 */
2644
2645VALUE
2646rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
2647{
2648 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
2649}
2650
2651/*
2652 * call-seq:
2653 * obj.private_methods(all=true) -> array
2654 *
2655 * Returns the list of private methods accessible to <i>obj</i>. If
2656 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2657 * in the receiver will be listed.
2658 */
2659
2660VALUE
2661rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
2662{
2663 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
2664}
2665
2666/*
2667 * call-seq:
2668 * obj.public_methods(all=true) -> array
2669 *
2670 * Returns the list of public methods accessible to <i>obj</i>. If
2671 * the <i>all</i> parameter is set to <code>false</code>, only those methods
2672 * in the receiver will be listed.
2673 */
2674
2675VALUE
2676rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
2677{
2678 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
2679}
2680
2681/*
2682 * call-seq:
2683 * obj.singleton_methods(all=true) -> array
2684 *
2685 * Returns an array of the names of singleton methods for <i>obj</i>.
2686 * If the optional <i>all</i> parameter is true, the list will include
2687 * methods in modules included in <i>obj</i>.
2688 * Only public and protected singleton methods are returned.
2689 *
2690 * module Other
2691 * def three() end
2692 * end
2693 *
2694 * class Single
2695 * def Single.four() end
2696 * end
2697 *
2698 * a = Single.new
2699 *
2700 * def a.one()
2701 * end
2702 *
2703 * class << a
2704 * include Other
2705 * def two()
2706 * end
2707 * end
2708 *
2709 * Single.singleton_methods #=> [:four]
2710 * a.singleton_methods(false) #=> [:two, :one]
2711 * a.singleton_methods #=> [:two, :one, :three]
2712 */
2713
2714VALUE
2715rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
2716{
2717 VALUE ary, klass, origin;
2718 struct method_entry_arg me_arg;
2719 struct rb_id_table *mtbl;
2720 int recur = TRUE;
2721
2722 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
2723 if (RCLASS_SINGLETON_P(obj)) {
2724 rb_singleton_class(obj);
2725 }
2726 klass = CLASS_OF(obj);
2727 origin = RCLASS_ORIGIN(klass);
2728 me_arg.list = st_init_numtable();
2729 me_arg.recur = recur;
2730 if (klass && RCLASS_SINGLETON_P(klass)) {
2731 if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
2732 klass = RCLASS_SUPER(klass);
2733 }
2734 if (recur) {
2735 while (klass && (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS))) {
2736 if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
2737 klass = RCLASS_SUPER(klass);
2738 }
2739 }
2740 ary = rb_ary_new2(me_arg.list->num_entries);
2741 st_foreach(me_arg.list, ins_methods_i, ary);
2742 st_free_table(me_arg.list);
2743
2744 return ary;
2745}
2746
2755#ifdef rb_define_method_id
2756#undef rb_define_method_id
2757#endif
2758void
2759rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
2760{
2761 rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC);
2762}
2763
2764#ifdef rb_define_method
2765#undef rb_define_method
2766#endif
2767void
2768rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2769{
2770 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PUBLIC);
2771}
2772
2773#ifdef rb_define_protected_method
2774#undef rb_define_protected_method
2775#endif
2776void
2777rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2778{
2779 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PROTECTED);
2780}
2781
2782#ifdef rb_define_private_method
2783#undef rb_define_private_method
2784#endif
2785void
2786rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
2787{
2788 rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PRIVATE);
2789}
2790
2791void
2792rb_undef_method(VALUE klass, const char *name)
2793{
2794 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
2795}
2796
2797static enum rb_id_table_iterator_result
2798undef_method_i(ID name, VALUE value, void *data)
2799{
2800 VALUE klass = (VALUE)data;
2801 rb_add_method(klass, name, VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
2802 return ID_TABLE_CONTINUE;
2803}
2804
2805void
2806rb_undef_methods_from(VALUE klass, VALUE super)
2807{
2808 struct rb_id_table *mtbl = RCLASS_M_TBL(super);
2809 if (mtbl) {
2810 rb_id_table_foreach(mtbl, undef_method_i, (void *)klass);
2811 }
2812}
2813
2822static inline VALUE
2823special_singleton_class_of(VALUE obj)
2824{
2825 switch (obj) {
2826 case Qnil: return rb_cNilClass;
2827 case Qfalse: return rb_cFalseClass;
2828 case Qtrue: return rb_cTrueClass;
2829 default: return Qnil;
2830 }
2831}
2832
2833VALUE
2834rb_special_singleton_class(VALUE obj)
2835{
2836 return special_singleton_class_of(obj);
2837}
2838
2848static VALUE
2849singleton_class_of(VALUE obj)
2850{
2851 VALUE klass;
2852
2853 switch (TYPE(obj)) {
2854 case T_FIXNUM:
2855 case T_BIGNUM:
2856 case T_FLOAT:
2857 case T_SYMBOL:
2858 rb_raise(rb_eTypeError, "can't define singleton");
2859
2860 case T_FALSE:
2861 case T_TRUE:
2862 case T_NIL:
2863 klass = special_singleton_class_of(obj);
2864 if (NIL_P(klass))
2865 rb_bug("unknown immediate %p", (void *)obj);
2866 return klass;
2867
2868 case T_STRING:
2869 if (CHILLED_STRING_P(obj)) {
2870 CHILLED_STRING_MUTATED(obj);
2871 }
2872 else if (FL_TEST_RAW(obj, RSTRING_FSTR)) {
2873 rb_raise(rb_eTypeError, "can't define singleton");
2874 }
2875 }
2876
2877 klass = METACLASS_OF(obj);
2878 if (!(RCLASS_SINGLETON_P(klass) &&
2879 RCLASS_ATTACHED_OBJECT(klass) == obj)) {
2880 klass = rb_make_metaclass(obj, klass);
2881 }
2882
2883 RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
2884
2885 return klass;
2886}
2887
2888void
2890{
2891 /* should not propagate to meta-meta-class, and so on */
2892 if (!RCLASS_SINGLETON_P(x)) {
2893 VALUE klass = RBASIC_CLASS(x);
2894 if (klass && // no class when hidden from ObjectSpace
2895 FL_TEST_RAW(klass, FL_SINGLETON) &&
2896 !OBJ_FROZEN_RAW(klass)) {
2897 OBJ_FREEZE(klass);
2898 }
2899 }
2900}
2901
2909VALUE
2911{
2912 VALUE klass;
2913
2914 if (SPECIAL_CONST_P(obj)) {
2915 return rb_special_singleton_class(obj);
2916 }
2917 klass = METACLASS_OF(obj);
2918 if (!RCLASS_SINGLETON_P(klass)) return Qnil;
2919 if (RCLASS_ATTACHED_OBJECT(klass) != obj) return Qnil;
2920 return klass;
2921}
2922
2923VALUE
2925{
2926 VALUE klass = singleton_class_of(obj);
2927
2928 /* ensures an exposed class belongs to its own eigenclass */
2929 if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass);
2930
2931 return klass;
2932}
2933
2943#ifdef rb_define_singleton_method
2944#undef rb_define_singleton_method
2945#endif
2946void
2947rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
2948{
2949 rb_define_method(singleton_class_of(obj), name, func, argc);
2950}
2951
2952#ifdef rb_define_module_function
2953#undef rb_define_module_function
2954#endif
2955void
2956rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
2957{
2958 rb_define_private_method(module, name, func, argc);
2959 rb_define_singleton_method(module, name, func, argc);
2960}
2961
2962#ifdef rb_define_global_function
2963#undef rb_define_global_function
2964#endif
2965void
2966rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
2967{
2968 rb_define_module_function(rb_mKernel, name, func, argc);
2969}
2970
2971void
2972rb_define_alias(VALUE klass, const char *name1, const char *name2)
2973{
2974 rb_alias(klass, rb_intern(name1), rb_intern(name2));
2975}
2976
2977void
2978rb_define_attr(VALUE klass, const char *name, int read, int write)
2979{
2980 rb_attr(klass, rb_intern(name), read, write, FALSE);
2981}
2982
2983VALUE
2984rb_keyword_error_new(const char *error, VALUE keys)
2985{
2986 long i = 0, len = RARRAY_LEN(keys);
2987 VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
2988
2989 if (len > 0) {
2990 rb_str_cat_cstr(error_message, ": ");
2991 while (1) {
2992 const VALUE k = RARRAY_AREF(keys, i);
2993 rb_str_append(error_message, rb_inspect(k));
2994 if (++i >= len) break;
2995 rb_str_cat_cstr(error_message, ", ");
2996 }
2997 }
2998
2999 return rb_exc_new_str(rb_eArgError, error_message);
3000}
3001
3002NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
3003static void
3004rb_keyword_error(const char *error, VALUE keys)
3005{
3006 rb_exc_raise(rb_keyword_error_new(error, keys));
3007}
3008
3009NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
3010static void
3011unknown_keyword_error(VALUE hash, const ID *table, int keywords)
3012{
3013 int i;
3014 for (i = 0; i < keywords; i++) {
3015 st_data_t key = ID2SYM(table[i]);
3016 rb_hash_stlike_delete(hash, &key, NULL);
3017 }
3018 rb_keyword_error("unknown", rb_hash_keys(hash));
3019}
3020
3021
3022static int
3023separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
3024{
3025 VALUE *kwdhash = (VALUE *)arg;
3026 if (!SYMBOL_P(key)) kwdhash++;
3027 if (!*kwdhash) *kwdhash = rb_hash_new();
3028 rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
3029 return ST_CONTINUE;
3030}
3031
3032VALUE
3034{
3035 VALUE parthash[2] = {0, 0};
3036 VALUE hash = *orighash;
3037
3038 if (RHASH_EMPTY_P(hash)) {
3039 *orighash = 0;
3040 return hash;
3041 }
3042 rb_hash_foreach(hash, separate_symbol, (st_data_t)&parthash);
3043 *orighash = parthash[1];
3044 if (parthash[1] && RBASIC_CLASS(hash) != rb_cHash) {
3045 RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
3046 }
3047 return parthash[0];
3048}
3049
3050int
3051rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
3052{
3053 int i = 0, j;
3054 int rest = 0;
3055 VALUE missing = Qnil;
3056 st_data_t key;
3057
3058#define extract_kwarg(keyword, val) \
3059 (key = (st_data_t)(keyword), values ? \
3060 (rb_hash_stlike_delete(keyword_hash, &key, &(val)) || ((val) = Qundef, 0)) : \
3061 rb_hash_stlike_lookup(keyword_hash, key, NULL))
3062
3063 if (NIL_P(keyword_hash)) keyword_hash = 0;
3064
3065 if (optional < 0) {
3066 rest = 1;
3067 optional = -1-optional;
3068 }
3069 if (required) {
3070 for (; i < required; i++) {
3071 VALUE keyword = ID2SYM(table[i]);
3072 if (keyword_hash) {
3073 if (extract_kwarg(keyword, values[i])) {
3074 continue;
3075 }
3076 }
3077 if (NIL_P(missing)) missing = rb_ary_hidden_new(1);
3078 rb_ary_push(missing, keyword);
3079 }
3080 if (!NIL_P(missing)) {
3081 rb_keyword_error("missing", missing);
3082 }
3083 }
3084 j = i;
3085 if (optional && keyword_hash) {
3086 for (i = 0; i < optional; i++) {
3087 if (extract_kwarg(ID2SYM(table[required+i]), values[required+i])) {
3088 j++;
3089 }
3090 }
3091 }
3092 if (!rest && keyword_hash) {
3093 if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : j)) {
3094 unknown_keyword_error(keyword_hash, table, required+optional);
3095 }
3096 }
3097 if (values && !keyword_hash) {
3098 for (i = 0; i < required + optional; i++) {
3099 values[i] = Qundef;
3100 }
3101 }
3102 return j;
3103#undef extract_kwarg
3104}
3105
3107 int kw_flag;
3108 int n_lead;
3109 int n_opt;
3110 int n_trail;
3111 bool f_var;
3112 bool f_hash;
3113 bool f_block;
3114};
3115
3116static void
3117rb_scan_args_parse(int kw_flag, const char *fmt, struct rb_scan_args_t *arg)
3118{
3119 const char *p = fmt;
3120
3121 memset(arg, 0, sizeof(*arg));
3122 arg->kw_flag = kw_flag;
3123
3124 if (ISDIGIT(*p)) {
3125 arg->n_lead = *p - '0';
3126 p++;
3127 if (ISDIGIT(*p)) {
3128 arg->n_opt = *p - '0';
3129 p++;
3130 }
3131 }
3132 if (*p == '*') {
3133 arg->f_var = 1;
3134 p++;
3135 }
3136 if (ISDIGIT(*p)) {
3137 arg->n_trail = *p - '0';
3138 p++;
3139 }
3140 if (*p == ':') {
3141 arg->f_hash = 1;
3142 p++;
3143 }
3144 if (*p == '&') {
3145 arg->f_block = 1;
3146 p++;
3147 }
3148 if (*p != '\0') {
3149 rb_fatal("bad scan arg format: %s", fmt);
3150 }
3151}
3152
3153static int
3154rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *const argv, va_list vargs)
3155{
3156 int i, argi = 0;
3157 VALUE *var, hash = Qnil;
3158#define rb_scan_args_next_param() va_arg(vargs, VALUE *)
3159 const int kw_flag = arg->kw_flag;
3160 const int n_lead = arg->n_lead;
3161 const int n_opt = arg->n_opt;
3162 const int n_trail = arg->n_trail;
3163 const int n_mand = n_lead + n_trail;
3164 const bool f_var = arg->f_var;
3165 const bool f_hash = arg->f_hash;
3166 const bool f_block = arg->f_block;
3167
3168 /* capture an option hash - phase 1: pop from the argv */
3169 if (f_hash && argc > 0) {
3170 VALUE last = argv[argc - 1];
3171 if (rb_scan_args_keyword_p(kw_flag, last)) {
3172 hash = rb_hash_dup(last);
3173 argc--;
3174 }
3175 }
3176
3177 if (argc < n_mand) {
3178 goto argc_error;
3179 }
3180
3181 /* capture leading mandatory arguments */
3182 for (i = 0; i < n_lead; i++) {
3183 var = rb_scan_args_next_param();
3184 if (var) *var = argv[argi];
3185 argi++;
3186 }
3187 /* capture optional arguments */
3188 for (i = 0; i < n_opt; i++) {
3189 var = rb_scan_args_next_param();
3190 if (argi < argc - n_trail) {
3191 if (var) *var = argv[argi];
3192 argi++;
3193 }
3194 else {
3195 if (var) *var = Qnil;
3196 }
3197 }
3198 /* capture variable length arguments */
3199 if (f_var) {
3200 int n_var = argc - argi - n_trail;
3201
3202 var = rb_scan_args_next_param();
3203 if (0 < n_var) {
3204 if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
3205 argi += n_var;
3206 }
3207 else {
3208 if (var) *var = rb_ary_new();
3209 }
3210 }
3211 /* capture trailing mandatory arguments */
3212 for (i = 0; i < n_trail; i++) {
3213 var = rb_scan_args_next_param();
3214 if (var) *var = argv[argi];
3215 argi++;
3216 }
3217 /* capture an option hash - phase 2: assignment */
3218 if (f_hash) {
3219 var = rb_scan_args_next_param();
3220 if (var) *var = hash;
3221 }
3222 /* capture iterator block */
3223 if (f_block) {
3224 var = rb_scan_args_next_param();
3225 if (rb_block_given_p()) {
3226 *var = rb_block_proc();
3227 }
3228 else {
3229 *var = Qnil;
3230 }
3231 }
3232
3233 if (argi == argc) {
3234 return argc;
3235 }
3236
3237 argc_error:
3238 return -(argc + 1);
3239#undef rb_scan_args_next_param
3240}
3241
3242static int
3243rb_scan_args_result(const struct rb_scan_args_t *const arg, int argc)
3244{
3245 const int n_lead = arg->n_lead;
3246 const int n_opt = arg->n_opt;
3247 const int n_trail = arg->n_trail;
3248 const int n_mand = n_lead + n_trail;
3249 const bool f_var = arg->f_var;
3250
3251 if (argc >= 0) {
3252 return argc;
3253 }
3254
3255 argc = -argc - 1;
3256 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
3258}
3259
3260#undef rb_scan_args
3261int
3262rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
3263{
3264 va_list vargs;
3265 struct rb_scan_args_t arg;
3266 rb_scan_args_parse(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, fmt, &arg);
3267 va_start(vargs,fmt);
3268 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
3269 va_end(vargs);
3270 return rb_scan_args_result(&arg, argc);
3271}
3272
3273#undef rb_scan_args_kw
3274int
3275rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt, ...)
3276{
3277 va_list vargs;
3278 struct rb_scan_args_t arg;
3279 rb_scan_args_parse(kw_flag, fmt, &arg);
3280 va_start(vargs,fmt);
3281 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
3282 va_end(vargs);
3283 return rb_scan_args_result(&arg, argc);
3284}
3285
#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:2538
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition class.c:1820
VALUE rb_refinement_new(void)
Creates a new, anonymous refinement.
Definition class.c:1708
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:2070
VALUE rb_class_subclasses(VALUE klass)
Queries the class's direct descendants.
Definition class.c:2318
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
Definition class.c:2924
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition class.c:1639
VALUE rb_class_attached_object(VALUE klass)
Returns the attached object for a singleton class.
Definition class.c:2341
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:2715
VALUE rb_module_new(void)
Creates a new, anonymous module.
Definition class.c:1702
#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:2523
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:2576
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:1721
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:1755
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:2889
VALUE rb_mod_included_modules(VALUE mod)
Queries the list of included modules.
Definition class.c:2136
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:1678
VALUE rb_mod_ancestors(VALUE mod)
Queries the module's ancestors.
Definition class.c:2204
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:2172
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:2561
#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:1749
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:2910
VALUE rb_define_module_id(ID id)
This is a very badly designed API that creates an anonymous module.
Definition class.c:1715
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:2972
VALUE rb_extract_keywords(VALUE *orighash)
Splits a hash into two.
Definition class.c:3033
void rb_define_attr(VALUE klass, const char *name, int read, int write)
Defines public accessor method(s) for an attribute.
Definition class.c:2978
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition class.c:2792
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:3275
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:3262
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:3051
#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:3787
#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:2403
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