Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
class.c
Go to the documentation of this file.
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
27#include <ctype.h>
28
29#include "gc.h"
30#include "constant.h"
31#include "id_table.h"
32#include "internal.h"
33#include "internal/class.h"
34#include "internal/eval.h"
35#include "internal/hash.h"
36#include "internal/object.h"
37#include "internal/string.h"
38#include "internal/variable.h"
39#include "ruby/st.h"
40#include "vm_core.h"
41
42#define id_attached id__attached__
43
44#define METACLASS_OF(k) RBASIC(k)->klass
45#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
46
47void
49{
50 rb_subclass_entry_t *entry, *head;
51
52 if (super && super != Qundef) {
54 entry->klass = klass;
55 entry->next = NULL;
56
57 head = RCLASS_EXT(super)->subclasses;
58 if (head) {
59 entry->next = head;
60 RCLASS_EXT(head->klass)->parent_subclasses = &entry->next;
61 }
62
63 RCLASS_EXT(super)->subclasses = entry;
64 RCLASS_EXT(klass)->parent_subclasses = &RCLASS_EXT(super)->subclasses;
65 }
66}
67
68static void
69rb_module_add_to_subclasses_list(VALUE module, VALUE iclass)
70{
71 rb_subclass_entry_t *entry, *head;
72
74 entry->klass = iclass;
75 entry->next = NULL;
76
77 head = RCLASS_EXT(module)->subclasses;
78 if (head) {
79 entry->next = head;
80 RCLASS_EXT(head->klass)->module_subclasses = &entry->next;
81 }
82
83 RCLASS_EXT(module)->subclasses = entry;
84 RCLASS_EXT(iclass)->module_subclasses = &RCLASS_EXT(module)->subclasses;
85}
86
87void
89{
91
92 if (RCLASS_EXT(klass)->parent_subclasses) {
93 entry = *RCLASS_EXT(klass)->parent_subclasses;
94
95 *RCLASS_EXT(klass)->parent_subclasses = entry->next;
96 if (entry->next) {
97 RCLASS_EXT(entry->next->klass)->parent_subclasses = RCLASS_EXT(klass)->parent_subclasses;
98 }
99 xfree(entry);
100 }
101
102 RCLASS_EXT(klass)->parent_subclasses = NULL;
103}
104
105void
107{
108 rb_subclass_entry_t *entry;
109
110 if (RCLASS_EXT(klass)->module_subclasses) {
111 entry = *RCLASS_EXT(klass)->module_subclasses;
112 *RCLASS_EXT(klass)->module_subclasses = entry->next;
113
114 if (entry->next) {
115 RCLASS_EXT(entry->next->klass)->module_subclasses = RCLASS_EXT(klass)->module_subclasses;
116 }
117
118 xfree(entry);
119 }
120
121 RCLASS_EXT(klass)->module_subclasses = NULL;
122}
123
124void
126{
127 rb_subclass_entry_t *cur = RCLASS_EXT(klass)->subclasses;
128
129 /* do not be tempted to simplify this loop into a for loop, the order of
130 operations is important here if `f` modifies the linked list */
131 while (cur) {
132 VALUE curklass = cur->klass;
133 cur = cur->next;
134 f(curklass, arg);
135 }
136}
137
138static void
139class_detach_subclasses(VALUE klass, VALUE arg)
140{
142}
143
144void
146{
147 rb_class_foreach_subclass(klass, class_detach_subclasses, Qnil);
148}
149
150static void
151class_detach_module_subclasses(VALUE klass, VALUE arg)
152{
154}
155
156void
158{
159 rb_class_foreach_subclass(klass, class_detach_module_subclasses, Qnil);
160}
161
174static VALUE
175class_alloc(VALUE flags, VALUE klass)
176{
177 NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | FL_PROMOTED1 /* start from age == 2 */ | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0));
178 obj->ptr = ZALLOC(rb_classext_t);
179 /* ZALLOC
180 RCLASS_IV_TBL(obj) = 0;
181 RCLASS_CONST_TBL(obj) = 0;
182 RCLASS_M_TBL(obj) = 0;
183 RCLASS_IV_INDEX_TBL(obj) = 0;
184 RCLASS_SET_SUPER((VALUE)obj, 0);
185 RCLASS_EXT(obj)->subclasses = NULL;
186 RCLASS_EXT(obj)->parent_subclasses = NULL;
187 RCLASS_EXT(obj)->module_subclasses = NULL;
188 */
189 RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
192 RCLASS_EXT(obj)->allocator = 0;
193
194 return (VALUE)obj;
195}
196
197static void
198RCLASS_M_TBL_INIT(VALUE c)
199{
201}
202
212VALUE
214{
215 VALUE klass = class_alloc(T_CLASS, rb_cClass);
216
217 RCLASS_SET_SUPER(klass, super);
218 RCLASS_M_TBL_INIT(klass);
219
220 return (VALUE)klass;
221}
222
223
230void
232{
233 if (!RB_TYPE_P(super, T_CLASS)) {
234 rb_raise(rb_eTypeError, "superclass must be an instance of Class (given an instance of %"PRIsVALUE")",
235 rb_obj_class(super));
236 }
237 if (RBASIC(super)->flags & FL_SINGLETON) {
238 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
239 }
240 if (super == rb_cClass) {
241 rb_raise(rb_eTypeError, "can't make subclass of Class");
242 }
243}
244
245
252VALUE
254{
255 Check_Type(super, T_CLASS);
257 return rb_class_boot(super);
258}
259
260static void
261clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *me)
262{
263 if (me->def->type == VM_METHOD_TYPE_ISEQ) {
264 rb_cref_t *new_cref;
265 rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &new_cref);
266 rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
267 }
268 else {
269 rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));
270 }
271}
272
276};
277
279clone_method_i(ID key, VALUE value, void *data)
280{
281 const struct clone_method_arg *arg = (struct clone_method_arg *)data;
282 clone_method(arg->old_klass, arg->new_klass, key, (const rb_method_entry_t *)value);
283 return ID_TABLE_CONTINUE;
284}
285
289};
290
291static int
292clone_const(ID key, const rb_const_entry_t *ce, struct clone_const_arg *arg)
293{
295 MEMCPY(nce, ce, rb_const_entry_t, 1);
296 RB_OBJ_WRITTEN(arg->klass, Qundef, ce->value);
297 RB_OBJ_WRITTEN(arg->klass, Qundef, ce->file);
298
299 rb_id_table_insert(arg->tbl, key, (VALUE)nce);
300 return ID_TABLE_CONTINUE;
301}
302
304clone_const_i(ID key, VALUE value, void *data)
305{
306 return clone_const(key, (const rb_const_entry_t *)value, data);
307}
308
309static void
310class_init_copy_check(VALUE clone, VALUE orig)
311{
312 if (orig == rb_cBasicObject) {
313 rb_raise(rb_eTypeError, "can't copy the root class");
314 }
315 if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
316 rb_raise(rb_eTypeError, "already initialized class");
317 }
318 if (FL_TEST(orig, FL_SINGLETON)) {
319 rb_raise(rb_eTypeError, "can't copy singleton class");
320 }
321}
322
323static void
324copy_tables(VALUE clone, VALUE orig)
325{
326 if (RCLASS_IV_TBL(clone)) {
328 RCLASS_IV_TBL(clone) = 0;
329 }
330 if (RCLASS_CONST_TBL(clone)) {
332 RCLASS_CONST_TBL(clone) = 0;
333 }
334 RCLASS_M_TBL(clone) = 0;
335 if (RCLASS_IV_TBL(orig)) {
337
338 rb_iv_tbl_copy(clone, orig);
339 CONST_ID(id, "__tmp_classpath__");
340 st_delete(RCLASS_IV_TBL(clone), &id, 0);
341 CONST_ID(id, "__classpath__");
342 st_delete(RCLASS_IV_TBL(clone), &id, 0);
343 CONST_ID(id, "__classid__");
344 st_delete(RCLASS_IV_TBL(clone), &id, 0);
345 }
346 if (RCLASS_CONST_TBL(orig)) {
347 struct clone_const_arg arg;
348
349 arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
350 arg.klass = clone;
351 rb_id_table_foreach(RCLASS_CONST_TBL(orig), clone_const_i, &arg);
352 }
353}
354
355static void ensure_origin(VALUE klass);
356
357/* :nodoc: */
358VALUE
360{
361 if (RB_TYPE_P(clone, T_CLASS)) {
362 class_init_copy_check(clone, orig);
363 }
364 if (!OBJ_INIT_COPY(clone, orig)) return clone;
365
366 /* cloned flag is refer at constant inline cache
367 * see vm_get_const_key_cref() in vm_insnhelper.c
368 */
369 FL_SET(clone, RCLASS_CLONED);
370 FL_SET(orig , RCLASS_CLONED);
371
372 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
373 RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
375 }
376 RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
377 copy_tables(clone, orig);
378 if (RCLASS_M_TBL(orig)) {
379 struct clone_method_arg arg;
380 arg.old_klass = orig;
381 arg.new_klass = clone;
382 RCLASS_M_TBL_INIT(clone);
383 rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
384 }
385
386 if (RCLASS_ORIGIN(orig) == orig) {
387 RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
388 }
389 else {
390 VALUE p = RCLASS_SUPER(orig);
391 VALUE orig_origin = RCLASS_ORIGIN(orig);
392 VALUE prev_clone_p = clone;
393 VALUE origin_stack = rb_ary_tmp_new(2);
394 VALUE origin[2];
395 VALUE clone_p = 0;
396 long origin_len;
397 int add_subclass;
398 VALUE clone_origin;
399
400 ensure_origin(clone);
401 clone_origin = RCLASS_ORIGIN(clone);
402
403 while (p && p != orig_origin) {
404 if (BUILTIN_TYPE(p) != T_ICLASS) {
405 rb_bug("non iclass between module/class and origin");
406 }
407 clone_p = class_alloc(RBASIC(p)->flags, RBASIC(p)->klass);
408 RCLASS_SET_SUPER(prev_clone_p, clone_p);
409 prev_clone_p = clone_p;
410 RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p);
412 RCLASS_IV_TBL(clone_p) = RCLASS_IV_TBL(p);
413 RCLASS_EXT(clone_p)->allocator = RCLASS_EXT(p)->allocator;
414 if (RB_TYPE_P(clone, T_CLASS)) {
415 RCLASS_SET_INCLUDER(clone_p, clone);
416 }
417 add_subclass = TRUE;
418 if (p != RCLASS_ORIGIN(p)) {
419 origin[0] = clone_p;
420 origin[1] = RCLASS_ORIGIN(p);
421 rb_ary_cat(origin_stack, origin, 2);
422 }
423 else if ((origin_len = RARRAY_LEN(origin_stack)) > 1 &&
424 RARRAY_AREF(origin_stack, origin_len - 1) == p) {
425 RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p);
426 RICLASS_SET_ORIGIN_SHARED_MTBL(clone_p);
427 rb_ary_resize(origin_stack, origin_len);
428 add_subclass = FALSE;
429 }
430 if (add_subclass) {
431 rb_module_add_to_subclasses_list(RBASIC(p)->klass, clone_p);
432 }
433 p = RCLASS_SUPER(p);
434 }
435
436 if (p == orig_origin) {
437 if (clone_p) {
438 RCLASS_SET_SUPER(clone_p, clone_origin);
439 RCLASS_SET_SUPER(clone_origin, RCLASS_SUPER(orig_origin));
440 }
441 copy_tables(clone_origin, orig_origin);
442 if (RCLASS_M_TBL(orig_origin)) {
443 struct clone_method_arg arg;
444 arg.old_klass = orig;
445 arg.new_klass = clone;
446 RCLASS_M_TBL_INIT(clone_origin);
447 rb_id_table_foreach(RCLASS_M_TBL(orig_origin), clone_method_i, &arg);
448 }
449 }
450 else {
451 rb_bug("no origin for class that has origin");
452 }
453 }
454
455 return clone;
456}
457
458VALUE
460{
462}
463
464// Clone and return the singleton class of `obj` if it has been created and is attached to `obj`.
465VALUE
467{
468 const VALUE klass = RBASIC(obj)->klass;
469
470 // Note that `rb_singleton_class()` can create situations where `klass` is
471 // attached to an object other than `obj`. In which case `obj` does not have
472 // a material singleton class attached yet and there is no singleton class
473 // to clone.
474 if (!(FL_TEST(klass, FL_SINGLETON) && rb_attr_get(klass, id_attached) == obj)) {
475 // nothing to clone
476 return klass;
477 }
478 else {
479 /* copy singleton(unnamed) class */
480 bool klass_of_clone_is_new;
481 VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
482
483 if (BUILTIN_TYPE(obj) == T_CLASS) {
484 klass_of_clone_is_new = true;
485 RBASIC_SET_CLASS(clone, clone);
486 }
487 else {
488 VALUE klass_metaclass_clone = rb_singleton_class_clone(klass);
489 // When `METACLASS_OF(klass) == klass_metaclass_clone`, it means the
490 // recursive call did not clone `METACLASS_OF(klass)`.
491 klass_of_clone_is_new = (METACLASS_OF(klass) != klass_metaclass_clone);
492 RBASIC_SET_CLASS(clone, klass_metaclass_clone);
493 }
494
495 RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
496 RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
497 if (RCLASS_IV_TBL(klass)) {
498 rb_iv_tbl_copy(clone, klass);
499 }
500 if (RCLASS_CONST_TBL(klass)) {
501 struct clone_const_arg arg;
502 arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
503 arg.klass = clone;
504 rb_id_table_foreach(RCLASS_CONST_TBL(klass), clone_const_i, &arg);
505 }
506 if (attach != Qundef) {
507 rb_singleton_class_attached(clone, attach);
508 }
509 RCLASS_M_TBL_INIT(clone);
510 {
511 struct clone_method_arg arg;
512 arg.old_klass = klass;
513 arg.new_klass = clone;
514 rb_id_table_foreach(RCLASS_M_TBL(klass), clone_method_i, &arg);
515 }
516 if (klass_of_clone_is_new) {
517 rb_singleton_class_attached(RBASIC(clone)->klass, clone);
518 }
519 FL_SET(clone, FL_SINGLETON);
520
521 return clone;
522 }
523}
524
529void
531{
532 if (FL_TEST(klass, FL_SINGLETON)) {
533 if (!RCLASS_IV_TBL(klass)) {
535 }
536 rb_class_ivar_set(klass, id_attached, obj);
537 }
538}
539
545#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
546
547static int
548rb_singleton_class_has_metaclass_p(VALUE sklass)
549{
550 return rb_attr_get(METACLASS_OF(sklass), id_attached) == sklass;
551}
552
553int
555{
556 return (RB_TYPE_P(rb_attr_get(sklass, id_attached), T_CLASS) &&
557 !rb_singleton_class_has_metaclass_p(sklass));
558}
559
565#define HAVE_METACLASS_P(k) \
566 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
567 rb_singleton_class_has_metaclass_p(k))
568
576#define ENSURE_EIGENCLASS(klass) \
577 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
578
579
589static inline VALUE
590make_metaclass(VALUE klass)
591{
592 VALUE super;
593 VALUE metaclass = rb_class_boot(Qundef);
594
595 FL_SET(metaclass, FL_SINGLETON);
596 rb_singleton_class_attached(metaclass, klass);
597
598 if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
599 SET_METACLASS_OF(klass, metaclass);
600 SET_METACLASS_OF(metaclass, metaclass);
601 }
602 else {
603 VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
604 SET_METACLASS_OF(klass, metaclass);
605 SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp));
606 }
607
608 super = RCLASS_SUPER(klass);
609 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
610 RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
611
612 return metaclass;
613}
614
621static inline VALUE
622make_singleton_class(VALUE obj)
623{
624 VALUE orig_class = RBASIC(obj)->klass;
625 VALUE klass = rb_class_boot(orig_class);
626
627 FL_SET(klass, FL_SINGLETON);
628 RBASIC_SET_CLASS(obj, klass);
629 rb_singleton_class_attached(klass, obj);
630
631 SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class)));
632 return klass;
633}
634
635
636static VALUE
637boot_defclass(const char *name, VALUE super)
638{
639 VALUE obj = rb_class_boot(super);
640 ID id = rb_intern(name);
641
642 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
644 return obj;
645}
646
647void
649{
650 rb_cBasicObject = boot_defclass("BasicObject", 0);
651 rb_cObject = boot_defclass("Object", rb_cBasicObject);
653
654 /* resolve class name ASAP for order-independence */
656
657 rb_cModule = boot_defclass("Module", rb_cObject);
658 rb_cClass = boot_defclass("Class", rb_cModule);
659
660 rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
661 RBASIC_SET_CLASS(rb_cClass, rb_cClass);
662 RBASIC_SET_CLASS(rb_cModule, rb_cClass);
663 RBASIC_SET_CLASS(rb_cObject, rb_cClass);
664 RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
665}
666
667
678VALUE
680{
681 if (BUILTIN_TYPE(obj) == T_CLASS) {
682 return make_metaclass(obj);
683 }
684 else {
685 return make_singleton_class(obj);
686 }
687}
688
689
700VALUE
702{
703 VALUE klass;
704
705 if (!super) super = rb_cObject;
706 klass = rb_class_new(super);
707 rb_make_metaclass(klass, RBASIC(super)->klass);
708
709 return klass;
710}
711
712
723{
724 ID inherited;
725 if (!super) super = rb_cObject;
726 CONST_ID(inherited, "inherited");
727 return rb_funcall(super, inherited, 1, klass);
728}
729
730
731
747VALUE
748rb_define_class(const char *name, VALUE super)
749{
750 VALUE klass;
751 ID id;
752
753 id = rb_intern(name);
754 if (rb_const_defined(rb_cObject, id)) {
755 klass = rb_const_get(rb_cObject, id);
756 if (!RB_TYPE_P(klass, T_CLASS)) {
757 rb_raise(rb_eTypeError, "%s is not a class (%"PRIsVALUE")",
758 name, rb_obj_class(klass));
759 }
760 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
761 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
762 }
763
764 /* Class may have been defined in Ruby and not pin-rooted */
766 return klass;
767 }
768 if (!super) {
769 rb_raise(rb_eArgError, "no super class for `%s'", name);
770 }
771 klass = rb_define_class_id(id, super);
773 rb_const_set(rb_cObject, id, klass);
774 rb_class_inherited(super, klass);
775
776 return klass;
777}
778
779
796VALUE
797rb_define_class_under(VALUE outer, const char *name, VALUE super)
798{
799 return rb_define_class_id_under(outer, rb_intern(name), super);
800}
801
802
819VALUE
821{
822 VALUE klass;
823
824 if (rb_const_defined_at(outer, id)) {
825 klass = rb_const_get_at(outer, id);
826 if (!RB_TYPE_P(klass, T_CLASS)) {
827 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a class"
828 " (%"PRIsVALUE")",
829 outer, rb_id2str(id), rb_obj_class(klass));
830 }
831 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
832 rb_raise(rb_eTypeError, "superclass mismatch for class "
833 "%"PRIsVALUE"::%"PRIsVALUE""
834 " (%"PRIsVALUE" is given but was %"PRIsVALUE")",
835 outer, rb_id2str(id), RCLASS_SUPER(klass), super);
836 }
837 /* Class may have been defined in Ruby and not pin-rooted */
839
840 return klass;
841 }
842 if (!super) {
843 rb_raise(rb_eArgError, "no super class for `%"PRIsVALUE"::%"PRIsVALUE"'",
844 rb_class_path(outer), rb_id2str(id));
845 }
846 klass = rb_define_class_id(id, super);
847 rb_set_class_path_string(klass, outer, rb_id2str(id));
848 rb_const_set(outer, id, klass);
849 rb_class_inherited(super, klass);
851
852 return klass;
853}
854
855VALUE
857{
858 VALUE mdl = class_alloc(T_MODULE, rb_cModule);
859 RCLASS_M_TBL_INIT(mdl);
860 return (VALUE)mdl;
861}
862
863// Kept for compatibility. Use rb_module_new() instead.
864VALUE
866{
867 return rb_module_new();
868}
869
870VALUE
872{
873 VALUE module;
874 ID id;
875
876 id = rb_intern(name);
877 if (rb_const_defined(rb_cObject, id)) {
878 module = rb_const_get(rb_cObject, id);
879 if (!RB_TYPE_P(module, T_MODULE)) {
880 rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
881 name, rb_obj_class(module));
882 }
883 /* Module may have been defined in Ruby and not pin-rooted */
884 rb_vm_add_root_module(module);
885 return module;
886 }
887 module = rb_module_new();
888 rb_vm_add_root_module(module);
889 rb_const_set(rb_cObject, id, module);
890
891 return module;
892}
893
894VALUE
896{
898}
899
900VALUE
902{
903 VALUE module;
904
905 if (rb_const_defined_at(outer, id)) {
906 module = rb_const_get_at(outer, id);
907 if (!RB_TYPE_P(module, T_MODULE)) {
908 rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a module"
909 " (%"PRIsVALUE")",
910 outer, rb_id2str(id), rb_obj_class(module));
911 }
912 return module;
913 }
914 module = rb_module_new();
915 rb_const_set(outer, id, module);
916 rb_set_class_path_string(module, outer, rb_id2str(id));
918
919 return module;
920}
921
922VALUE
924{
925 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
926
927 RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
928
929 RCLASS_SET_ORIGIN(klass, klass);
930 if (BUILTIN_TYPE(module) == T_ICLASS) {
931 module = RBASIC(module)->klass;
932 }
933 RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
934 if (!RCLASS_IV_TBL(module)) {
936 }
937 if (!RCLASS_CONST_TBL(module)) {
939 }
940 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
941 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
942
943 RCLASS_SET_SUPER(klass, super);
944 RBASIC_SET_CLASS(klass, module);
945
946 return (VALUE)klass;
947}
948
949static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
950
951static void
952ensure_includable(VALUE klass, VALUE module)
953{
955 Check_Type(module, T_MODULE);
956 if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
957 rb_raise(rb_eArgError, "refinement module is not allowed");
958 }
959}
960
961void
963{
964 int changed = 0;
965
966 ensure_includable(klass, module);
967
968 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
969 if (changed < 0)
970 rb_raise(rb_eArgError, "cyclic include detected");
971
972 if (RB_TYPE_P(klass, T_MODULE)) {
973 rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
974 int do_include = 1;
975 while (iclass) {
976 VALUE check_class = iclass->klass;
977 /* During lazy sweeping, iclass->klass could be a dead object that
978 * has not yet been swept. */
979 if (!rb_objspace_garbage_object_p(check_class)) {
980 while (check_class) {
981 if (RB_TYPE_P(check_class, T_ICLASS) &&
982 (RBASIC(check_class)->klass == module)) {
983 do_include = 0;
984 }
985 check_class = RCLASS_SUPER(check_class);
986 }
987
988 if (do_include) {
989 include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
990 }
991 }
992
993 iclass = iclass->next;
994 }
995 }
996}
997
999add_refined_method_entry_i(ID key, VALUE value, void *data)
1000{
1002 return ID_TABLE_CONTINUE;
1003}
1004
1006clear_module_cache_i(ID id, VALUE val, void *data)
1007{
1008 VALUE klass = (VALUE)data;
1009 rb_clear_method_cache(klass, id);
1010 return ID_TABLE_CONTINUE;
1011}
1012
1013static int
1014include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
1015{
1016 VALUE p, iclass, origin_stack = 0;
1017 int method_changed = 0, constant_changed = 0, add_subclass;
1018 long origin_len;
1019 struct rb_id_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
1020 VALUE original_klass = klass;
1021
1022 while (module) {
1023 int origin_seen = FALSE;
1024 int superclass_seen = FALSE;
1025 struct rb_id_table *tbl;
1026
1027 if (klass == c)
1028 origin_seen = TRUE;
1029 if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
1030 return -1;
1031 /* ignore if the module included already in superclasses */
1032 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
1033 int type = BUILTIN_TYPE(p);
1034 if (c == p)
1035 origin_seen = TRUE;
1036 if (type == T_ICLASS) {
1037 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
1038 if (!superclass_seen && origin_seen) {
1039 c = p; /* move insertion point */
1040 }
1041 goto skip;
1042 }
1043 }
1044 else if (type == T_CLASS) {
1045 if (!search_super) break;
1046 superclass_seen = TRUE;
1047 }
1048 }
1049
1050 VALUE super_class = RCLASS_SUPER(c);
1051
1052 // invalidate inline method cache
1053 tbl = RCLASS_M_TBL(module);
1054 if (tbl && rb_id_table_size(tbl)) {
1055 if (search_super) { // include
1056 if (super_class && !RB_TYPE_P(super_class, T_MODULE)) {
1057 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)super_class);
1058 }
1059 }
1060 else { // prepend
1061 if (!RB_TYPE_P(original_klass, T_MODULE)) {
1062 rb_id_table_foreach(tbl, clear_module_cache_i, (void *)original_klass);
1063 }
1064 }
1065 method_changed = 1;
1066 }
1067
1068 // setup T_ICLASS for the include/prepend module
1069 iclass = rb_include_class_new(module, super_class);
1070 c = RCLASS_SET_SUPER(c, iclass);
1071 RCLASS_SET_INCLUDER(iclass, klass);
1072 add_subclass = TRUE;
1073 if (module != RCLASS_ORIGIN(module)) {
1074 if (!origin_stack) origin_stack = rb_ary_tmp_new(2);
1075 VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
1076 rb_ary_cat(origin_stack, origin, 2);
1077 }
1078 else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 &&
1079 RARRAY_AREF(origin_stack, origin_len - 1) == module) {
1080 RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
1081 RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
1082 rb_ary_resize(origin_stack, origin_len);
1083 add_subclass = FALSE;
1084 }
1085
1086 {
1087 VALUE m = module;
1088 if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass;
1089 if (add_subclass) rb_module_add_to_subclasses_list(m, iclass);
1090 }
1091
1092 if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
1093 VALUE refined_class =
1094 rb_refinement_module_get_refined_class(klass);
1095
1096 rb_id_table_foreach(RCLASS_M_TBL(module), add_refined_method_entry_i, (void *)refined_class);
1098 }
1099
1100 tbl = RCLASS_CONST_TBL(module);
1101 if (tbl && rb_id_table_size(tbl)) constant_changed = 1;
1102 skip:
1103 module = RCLASS_SUPER(module);
1104 }
1105
1106 if (constant_changed) rb_clear_constant_cache();
1107
1108 return method_changed;
1109}
1110
1112move_refined_method(ID key, VALUE value, void *data)
1113{
1114 rb_method_entry_t *me = (rb_method_entry_t *)value;
1115
1116 if (me->def->type == VM_METHOD_TYPE_REFINED) {
1117 VALUE klass = (VALUE)data;
1118 struct rb_id_table *tbl = RCLASS_M_TBL(klass);
1119
1120 if (me->def->body.refined.orig_me) {
1121 const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
1123 new_me = rb_method_entry_clone(me);
1124 rb_method_table_insert(klass, tbl, key, new_me);
1125 rb_method_entry_copy(me, orig_me);
1126 return ID_TABLE_CONTINUE;
1127 }
1128 else {
1129 rb_method_table_insert(klass, tbl, key, me);
1130 return ID_TABLE_DELETE;
1131 }
1132 }
1133 else {
1134 return ID_TABLE_CONTINUE;
1135 }
1136}
1137
1139cache_clear_refined_method(ID key, VALUE value, void *data)
1140{
1141 rb_method_entry_t *me = (rb_method_entry_t *) value;
1142
1143 if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
1144 VALUE klass = (VALUE)data;
1145 rb_clear_method_cache(klass, me->called_id);
1146 }
1147 // Refined method entries without an orig_me is going to stay in the method
1148 // table of klass, like before the move, so no need to clear the cache.
1149
1150 return ID_TABLE_CONTINUE;
1151}
1152
1153static void
1154ensure_origin(VALUE klass)
1155{
1156 VALUE origin = RCLASS_ORIGIN(klass);
1157 if (origin == klass) {
1158 origin = class_alloc(T_ICLASS, klass);
1159 RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
1160 RCLASS_SET_SUPER(klass, origin);
1161 RCLASS_SET_ORIGIN(klass, origin);
1163 RCLASS_M_TBL_INIT(klass);
1164 rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
1165 rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
1166 }
1167}
1168
1169void
1171{
1172 int changed = 0;
1173 bool klass_had_no_origin = RCLASS_ORIGIN(klass) == klass;
1174
1175 ensure_includable(klass, module);
1176 ensure_origin(klass);
1177 changed = include_modules_at(klass, klass, module, FALSE);
1178 if (changed < 0)
1179 rb_raise(rb_eArgError, "cyclic prepend detected");
1180 if (changed) {
1182 }
1183 if (RB_TYPE_P(klass, T_MODULE)) {
1184 rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
1185 VALUE klass_origin = RCLASS_ORIGIN(klass);
1186 struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
1187 struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
1188 while (iclass) {
1189 /* During lazy sweeping, iclass->klass could be a dead object that
1190 * has not yet been swept. */
1191 if (!rb_objspace_garbage_object_p(iclass->klass)) {
1192 if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) {
1193 // backfill an origin iclass to handle refinements and future prepends
1194 rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass);
1195 RCLASS_M_TBL(iclass->klass) = klass_m_tbl;
1196 VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass));
1197 RCLASS_SET_SUPER(iclass->klass, origin);
1198 RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass));
1199 RCLASS_SET_ORIGIN(iclass->klass, origin);
1200 RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
1201 }
1202 include_modules_at(iclass->klass, iclass->klass, module, FALSE);
1203 }
1204
1205 iclass = iclass->next;
1206 }
1207 }
1208}
1209
1210/*
1211 * call-seq:
1212 * mod.included_modules -> array
1213 *
1214 * Returns the list of modules included or prepended in <i>mod</i>
1215 * or one of <i>mod</i>'s ancestors.
1216 *
1217 * module Sub
1218 * end
1219 *
1220 * module Mixin
1221 * prepend Sub
1222 * end
1223 *
1224 * module Outer
1225 * include Mixin
1226 * end
1227 *
1228 * Mixin.included_modules #=> [Sub]
1229 * Outer.included_modules #=> [Sub, Mixin]
1230 */
1231
1232VALUE
1234{
1235 VALUE ary = rb_ary_new();
1236 VALUE p;
1238
1239 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
1240 if (p != origin && RCLASS_ORIGIN(p) == p && BUILTIN_TYPE(p) == T_ICLASS) {
1241 VALUE m = RBASIC(p)->klass;
1242 if (RB_TYPE_P(m, T_MODULE))
1243 rb_ary_push(ary, m);
1244 }
1245 }
1246 return ary;
1247}
1248
1249/*
1250 * call-seq:
1251 * mod.include?(module) -> true or false
1252 *
1253 * Returns <code>true</code> if <i>module</i> is included
1254 * or prepended in <i>mod</i> or one of <i>mod</i>'s ancestors.
1255 *
1256 * module A
1257 * end
1258 * class B
1259 * include A
1260 * end
1261 * class C < B
1262 * end
1263 * B.include?(A) #=> true
1264 * C.include?(A) #=> true
1265 * A.include?(A) #=> false
1266 */
1267
1268VALUE
1270{
1271 VALUE p;
1272
1273 Check_Type(mod2, T_MODULE);
1274 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
1275 if (BUILTIN_TYPE(p) == T_ICLASS && !FL_TEST(p, RICLASS_IS_ORIGIN)) {
1276 if (RBASIC(p)->klass == mod2) return Qtrue;
1277 }
1278 }
1279 return Qfalse;
1280}
1281
1282/*
1283 * call-seq:
1284 * mod.ancestors -> array
1285 *
1286 * Returns a list of modules included/prepended in <i>mod</i>
1287 * (including <i>mod</i> itself).
1288 *
1289 * module Mod
1290 * include Math
1291 * include Comparable
1292 * prepend Enumerable
1293 * end
1294 *
1295 * Mod.ancestors #=> [Enumerable, Mod, Comparable, Math]
1296 * Math.ancestors #=> [Math]
1297 * Enumerable.ancestors #=> [Enumerable]
1298 */
1299
1300VALUE
1302{
1303 VALUE p, ary = rb_ary_new();
1304
1305 for (p = mod; p; p = RCLASS_SUPER(p)) {
1306 if (p != RCLASS_ORIGIN(p)) continue;
1307 if (BUILTIN_TYPE(p) == T_ICLASS) {
1308 rb_ary_push(ary, RBASIC(p)->klass);
1309 }
1310 else {
1311 rb_ary_push(ary, p);
1312 }
1313 }
1314 return ary;
1315}
1316
1317static void
1318ins_methods_push(st_data_t name, st_data_t ary)
1319{
1320 rb_ary_push((VALUE)ary, ID2SYM((ID)name));
1321}
1322
1323static int
1324ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
1325{
1326 switch ((rb_method_visibility_t)type) {
1327 case METHOD_VISI_UNDEF:
1329 break;
1330 default: /* everything but private */
1331 ins_methods_push(name, ary);
1332 break;
1333 }
1334 return ST_CONTINUE;
1335}
1336
1337static int
1338ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
1339{
1341 ins_methods_push(name, ary);
1342 }
1343 return ST_CONTINUE;
1344}
1345
1346static int
1347ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
1348{
1350 ins_methods_push(name, ary);
1351 }
1352 return ST_CONTINUE;
1353}
1354
1355static int
1356ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
1357{
1359 ins_methods_push(name, ary);
1360 }
1361 return ST_CONTINUE;
1362}
1363
1367};
1368
1370method_entry_i(ID key, VALUE value, void *data)
1371{
1372 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
1373 struct method_entry_arg *arg = (struct method_entry_arg *)data;
1375
1376 if (me->def->type == VM_METHOD_TYPE_REFINED) {
1377 VALUE owner = me->owner;
1379 if (!me) return ID_TABLE_CONTINUE;
1380 if (!arg->recur && me->owner != owner) return ID_TABLE_CONTINUE;
1381 }
1382 if (!st_is_member(arg->list, key)) {
1383 if (UNDEFINED_METHOD_ENTRY_P(me)) {
1384 type = METHOD_VISI_UNDEF; /* none */
1385 }
1386 else {
1387 type = METHOD_ENTRY_VISI(me);
1388 }
1390 }
1391 return ID_TABLE_CONTINUE;
1392}
1393
1394static void
1395add_instance_method_list(VALUE mod, struct method_entry_arg *me_arg)
1396{
1397 struct rb_id_table *m_tbl = RCLASS_M_TBL(mod);
1398 if (!m_tbl) return;
1399 rb_id_table_foreach(m_tbl, method_entry_i, me_arg);
1400}
1401
1402static bool
1403particular_class_p(VALUE mod)
1404{
1405 if (!mod) return false;
1406 if (FL_TEST(mod, FL_SINGLETON)) return true;
1407 if (BUILTIN_TYPE(mod) == T_ICLASS) return true;
1408 return false;
1409}
1410
1411static VALUE
1412class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
1413{
1414 VALUE ary;
1415 int recur = TRUE, prepended = 0;
1416 struct method_entry_arg me_arg;
1417
1418 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
1419
1420 me_arg.list = st_init_numtable();
1421 me_arg.recur = recur;
1422
1423 if (obj) {
1424 for (; particular_class_p(mod); mod = RCLASS_SUPER(mod)) {
1425 add_instance_method_list(mod, &me_arg);
1426 }
1427 }
1428
1429 if (!recur && RCLASS_ORIGIN(mod) != mod) {
1431 prepended = 1;
1432 }
1433
1434 for (; mod; mod = RCLASS_SUPER(mod)) {
1435 add_instance_method_list(mod, &me_arg);
1436 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
1437 if (!recur) break;
1438 }
1439 ary = rb_ary_new2(me_arg.list->num_entries);
1440 st_foreach(me_arg.list, func, ary);
1441 st_free_table(me_arg.list);
1442
1443 return ary;
1444}
1445
1446/*
1447 * call-seq:
1448 * mod.instance_methods(include_super=true) -> array
1449 *
1450 * Returns an array containing the names of the public and protected instance
1451 * methods in the receiver. For a module, these are the public and protected methods;
1452 * for a class, they are the instance (not singleton) methods. If the optional
1453 * parameter is <code>false</code>, the methods of any ancestors are not included.
1454 *
1455 * module A
1456 * def method1() end
1457 * end
1458 * class B
1459 * include A
1460 * def method2() end
1461 * end
1462 * class C < B
1463 * def method3() end
1464 * end
1465 *
1466 * A.instance_methods(false) #=> [:method1]
1467 * B.instance_methods(false) #=> [:method2]
1468 * B.instance_methods(true).include?(:method1) #=> true
1469 * C.instance_methods(false) #=> [:method3]
1470 * C.instance_methods.include?(:method2) #=> true
1471 */
1472
1473VALUE
1475{
1476 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
1477}
1478
1479/*
1480 * call-seq:
1481 * mod.protected_instance_methods(include_super=true) -> array
1482 *
1483 * Returns a list of the protected instance methods defined in
1484 * <i>mod</i>. If the optional parameter is <code>false</code>, the
1485 * methods of any ancestors are not included.
1486 */
1487
1488VALUE
1490{
1491 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
1492}
1493
1494/*
1495 * call-seq:
1496 * mod.private_instance_methods(include_super=true) -> array
1497 *
1498 * Returns a list of the private instance methods defined in
1499 * <i>mod</i>. If the optional parameter is <code>false</code>, the
1500 * methods of any ancestors are not included.
1501 *
1502 * module Mod
1503 * def method1() end
1504 * private :method1
1505 * def method2() end
1506 * end
1507 * Mod.instance_methods #=> [:method2]
1508 * Mod.private_instance_methods #=> [:method1]
1509 */
1510
1511VALUE
1513{
1514 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
1515}
1516
1517/*
1518 * call-seq:
1519 * mod.public_instance_methods(include_super=true) -> array
1520 *
1521 * Returns a list of the public instance methods defined in <i>mod</i>.
1522 * If the optional parameter is <code>false</code>, the methods of
1523 * any ancestors are not included.
1524 */
1525
1526VALUE
1528{
1529 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
1530}
1531
1532/*
1533 * call-seq:
1534 * obj.methods(regular=true) -> array
1535 *
1536 * Returns a list of the names of public and protected methods of
1537 * <i>obj</i>. This will include all the methods accessible in
1538 * <i>obj</i>'s ancestors.
1539 * If the optional parameter is <code>false</code>, it
1540 * returns an array of <i>obj</i>'s public and protected singleton methods,
1541 * the array will not include methods in modules included in <i>obj</i>.
1542 *
1543 * class Klass
1544 * def klass_method()
1545 * end
1546 * end
1547 * k = Klass.new
1548 * k.methods[0..9] #=> [:klass_method, :nil?, :===,
1549 * # :==~, :!, :eql?
1550 * # :hash, :<=>, :class, :singleton_class]
1551 * k.methods.length #=> 56
1552 *
1553 * k.methods(false) #=> []
1554 * def k.singleton_method; end
1555 * k.methods(false) #=> [:singleton_method]
1556 *
1557 * module M123; def m123; end end
1558 * k.extend M123
1559 * k.methods(false) #=> [:singleton_method]
1560 */
1561
1562VALUE
1564{
1565 rb_check_arity(argc, 0, 1);
1566 if (argc > 0 && !RTEST(argv[0])) {
1567 return rb_obj_singleton_methods(argc, argv, obj);
1568 }
1569 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
1570}
1571
1572/*
1573 * call-seq:
1574 * obj.protected_methods(all=true) -> array
1575 *
1576 * Returns the list of protected methods accessible to <i>obj</i>. If
1577 * the <i>all</i> parameter is set to <code>false</code>, only those methods
1578 * in the receiver will be listed.
1579 */
1580
1581VALUE
1583{
1584 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
1585}
1586
1587/*
1588 * call-seq:
1589 * obj.private_methods(all=true) -> array
1590 *
1591 * Returns the list of private methods accessible to <i>obj</i>. If
1592 * the <i>all</i> parameter is set to <code>false</code>, only those methods
1593 * in the receiver will be listed.
1594 */
1595
1596VALUE
1598{
1599 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
1600}
1601
1602/*
1603 * call-seq:
1604 * obj.public_methods(all=true) -> array
1605 *
1606 * Returns the list of public methods accessible to <i>obj</i>. If
1607 * the <i>all</i> parameter is set to <code>false</code>, only those methods
1608 * in the receiver will be listed.
1609 */
1610
1611VALUE
1613{
1614 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
1615}
1616
1617/*
1618 * call-seq:
1619 * obj.singleton_methods(all=true) -> array
1620 *
1621 * Returns an array of the names of singleton methods for <i>obj</i>.
1622 * If the optional <i>all</i> parameter is true, the list will include
1623 * methods in modules included in <i>obj</i>.
1624 * Only public and protected singleton methods are returned.
1625 *
1626 * module Other
1627 * def three() end
1628 * end
1629 *
1630 * class Single
1631 * def Single.four() end
1632 * end
1633 *
1634 * a = Single.new
1635 *
1636 * def a.one()
1637 * end
1638 *
1639 * class << a
1640 * include Other
1641 * def two()
1642 * end
1643 * end
1644 *
1645 * Single.singleton_methods #=> [:four]
1646 * a.singleton_methods(false) #=> [:two, :one]
1647 * a.singleton_methods #=> [:two, :one, :three]
1648 */
1649
1650VALUE
1652{
1653 VALUE ary, klass, origin;
1654 struct method_entry_arg me_arg;
1655 struct rb_id_table *mtbl;
1656 int recur = TRUE;
1657
1658 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
1659 if (RB_TYPE_P(obj, T_CLASS) && FL_TEST(obj, FL_SINGLETON)) {
1660 rb_singleton_class(obj);
1661 }
1662 klass = CLASS_OF(obj);
1663 origin = RCLASS_ORIGIN(klass);
1664 me_arg.list = st_init_numtable();
1665 me_arg.recur = recur;
1666 if (klass && FL_TEST(klass, FL_SINGLETON)) {
1667 if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
1668 klass = RCLASS_SUPER(klass);
1669 }
1670 if (recur) {
1671 while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
1672 if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
1673 klass = RCLASS_SUPER(klass);
1674 }
1675 }
1676 ary = rb_ary_new2(me_arg.list->num_entries);
1677 st_foreach(me_arg.list, ins_methods_i, ary);
1678 st_free_table(me_arg.list);
1679
1680 return ary;
1681}
1682
1740#ifdef rb_define_method_id
1741#undef rb_define_method_id
1742#endif
1743void
1744rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
1745{
1746 rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC);
1747}
1748
1749#ifdef rb_define_method
1750#undef rb_define_method
1751#endif
1752void
1753rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
1754{
1756}
1757
1758#ifdef rb_define_protected_method
1759#undef rb_define_protected_method
1760#endif
1761void
1762rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
1763{
1765}
1766
1767#ifdef rb_define_private_method
1768#undef rb_define_private_method
1769#endif
1770void
1771rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
1772{
1774}
1775
1776void
1777rb_undef_method(VALUE klass, const char *name)
1778{
1780}
1781
1783undef_method_i(ID name, VALUE value, void *data)
1784{
1785 VALUE klass = (VALUE)data;
1787 return ID_TABLE_CONTINUE;
1788}
1789
1790void
1792{
1793 struct rb_id_table *mtbl = RCLASS_M_TBL(super);
1794 if (mtbl) {
1795 rb_id_table_foreach(mtbl, undef_method_i, (void *)klass);
1796 }
1797}
1798
1807static inline VALUE
1808special_singleton_class_of(VALUE obj)
1809{
1810 switch (obj) {
1811 case Qnil: return rb_cNilClass;
1812 case Qfalse: return rb_cFalseClass;
1813 case Qtrue: return rb_cTrueClass;
1814 default: return Qnil;
1815 }
1816}
1817
1818VALUE
1820{
1821 return special_singleton_class_of(obj);
1822}
1823
1833static VALUE
1834singleton_class_of(VALUE obj)
1835{
1836 VALUE klass;
1837
1838 switch (TYPE(obj)) {
1839 case T_FIXNUM:
1840 case T_BIGNUM:
1841 case T_FLOAT:
1842 case T_SYMBOL:
1843 rb_raise(rb_eTypeError, "can't define singleton");
1844
1845 case T_FALSE:
1846 case T_TRUE:
1847 case T_NIL:
1848 klass = special_singleton_class_of(obj);
1849 if (NIL_P(klass))
1850 rb_bug("unknown immediate %p", (void *)obj);
1851 return klass;
1852
1853 case T_STRING:
1854 if (FL_TEST_RAW(obj, RSTRING_FSTR)) {
1855 rb_raise(rb_eTypeError, "can't define singleton");
1856 }
1857 }
1858
1859 klass = RBASIC(obj)->klass;
1860 if (!(FL_TEST(klass, FL_SINGLETON) &&
1861 rb_attr_get(klass, id_attached) == obj)) {
1862 rb_serial_t serial = RCLASS_SERIAL(klass);
1863 klass = rb_make_metaclass(obj, klass);
1864 RCLASS_SERIAL(klass) = serial;
1865 }
1866
1867 RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
1868
1869 return klass;
1870}
1871
1872void
1874{
1875 /* should not propagate to meta-meta-class, and so on */
1876 if (!(RBASIC(x)->flags & FL_SINGLETON)) {
1877 VALUE klass = RBASIC_CLASS(x);
1878 if (klass && (klass = RCLASS_ORIGIN(klass)) != 0 &&
1880 OBJ_FREEZE_RAW(klass);
1881 }
1882 }
1883}
1884
1892VALUE
1894{
1895 VALUE klass;
1896
1897 if (SPECIAL_CONST_P(obj)) {
1898 return rb_special_singleton_class(obj);
1899 }
1900 klass = RBASIC(obj)->klass;
1901 if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
1902 if (rb_attr_get(klass, id_attached) != obj) return Qnil;
1903 return klass;
1904}
1905
1923VALUE
1925{
1926 VALUE klass = singleton_class_of(obj);
1927
1928 /* ensures an exposed class belongs to its own eigenclass */
1929 if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass);
1930
1931 return klass;
1932}
1933
1943#ifdef rb_define_singleton_method
1944#undef rb_define_singleton_method
1945#endif
1953void
1954rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
1955{
1956 rb_define_method(singleton_class_of(obj), name, func, argc);
1957}
1958
1959#ifdef rb_define_module_function
1960#undef rb_define_module_function
1961#endif
1969void
1970rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
1971{
1972 rb_define_private_method(module, name, func, argc);
1973 rb_define_singleton_method(module, name, func, argc);
1974}
1975
1976#ifdef rb_define_global_function
1977#undef rb_define_global_function
1978#endif
1985void
1987{
1989}
1990
1991
1998void
1999rb_define_alias(VALUE klass, const char *name1, const char *name2)
2000{
2001 rb_alias(klass, rb_intern(name1), rb_intern(name2));
2002}
2003
2011void
2012rb_define_attr(VALUE klass, const char *name, int read, int write)
2013{
2014 rb_attr(klass, rb_intern(name), read, write, FALSE);
2015}
2016
2019{
2020 long i = 0, len = RARRAY_LEN(keys);
2021 VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
2022
2023 if (len > 0) {
2024 rb_str_cat_cstr(error_message, ": ");
2025 while (1) {
2026 const VALUE k = RARRAY_AREF(keys, i);
2027 rb_str_append(error_message, rb_inspect(k));
2028 if (++i >= len) break;
2029 rb_str_cat_cstr(error_message, ", ");
2030 }
2031 }
2032
2033 return rb_exc_new_str(rb_eArgError, error_message);
2034}
2035
2036NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
2037static void
2038rb_keyword_error(const char *error, VALUE keys)
2039{
2041}
2042
2043NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
2044static void
2045unknown_keyword_error(VALUE hash, const ID *table, int keywords)
2046{
2047 int i;
2048 for (i = 0; i < keywords; i++) {
2049 st_data_t key = ID2SYM(table[i]);
2051 }
2052 rb_keyword_error("unknown", rb_hash_keys(hash));
2053}
2054
2055
2056static int
2057separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
2058{
2059 VALUE *kwdhash = (VALUE *)arg;
2060 if (!SYMBOL_P(key)) kwdhash++;
2061 if (!*kwdhash) *kwdhash = rb_hash_new();
2062 rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
2063 return ST_CONTINUE;
2064}
2065
2066VALUE
2068{
2069 VALUE parthash[2] = {0, 0};
2070 VALUE hash = *orighash;
2071
2072 if (RHASH_EMPTY_P(hash)) {
2073 *orighash = 0;
2074 return hash;
2075 }
2076 rb_hash_foreach(hash, separate_symbol, (st_data_t)&parthash);
2077 *orighash = parthash[1];
2078 if (parthash[1] && RBASIC_CLASS(hash) != rb_cHash) {
2079 RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
2080 }
2081 return parthash[0];
2082}
2083
2084int
2085rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
2086{
2087 int i = 0, j;
2088 int rest = 0;
2089 VALUE missing = Qnil;
2090 st_data_t key;
2091
2092#define extract_kwarg(keyword, val) \
2093 (key = (st_data_t)(keyword), values ? \
2094 (rb_hash_stlike_delete(keyword_hash, &key, &(val)) || ((val) = Qundef, 0)) : \
2095 rb_hash_stlike_lookup(keyword_hash, key, NULL))
2096
2097 if (NIL_P(keyword_hash)) keyword_hash = 0;
2098
2099 if (optional < 0) {
2100 rest = 1;
2101 optional = -1-optional;
2102 }
2103 if (required) {
2104 for (; i < required; i++) {
2105 VALUE keyword = ID2SYM(table[i]);
2106 if (keyword_hash) {
2107 if (extract_kwarg(keyword, values[i])) {
2108 continue;
2109 }
2110 }
2111 if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
2112 rb_ary_push(missing, keyword);
2113 }
2114 if (!NIL_P(missing)) {
2115 rb_keyword_error("missing", missing);
2116 }
2117 }
2118 j = i;
2119 if (optional && keyword_hash) {
2120 for (i = 0; i < optional; i++) {
2121 if (extract_kwarg(ID2SYM(table[required+i]), values[required+i])) {
2122 j++;
2123 }
2124 }
2125 }
2126 if (!rest && keyword_hash) {
2127 if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : j)) {
2128 unknown_keyword_error(keyword_hash, table, required+optional);
2129 }
2130 }
2131 if (values && !keyword_hash) {
2132 for (i = 0; i < required + optional; i++) {
2133 values[i] = Qundef;
2134 }
2135 }
2136 return j;
2137#undef extract_kwarg
2138}
2139
2145 bool f_var;
2148};
2149
2150static void
2151rb_scan_args_parse(int kw_flag, const char *fmt, struct rb_scan_args_t *arg)
2152{
2153 const char *p = fmt;
2154
2155 memset(arg, 0, sizeof(*arg));
2156 arg->kw_flag = kw_flag;
2157
2158 if (ISDIGIT(*p)) {
2159 arg->n_lead = *p - '0';
2160 p++;
2161 if (ISDIGIT(*p)) {
2162 arg->n_opt = *p - '0';
2163 p++;
2164 }
2165 }
2166 if (*p == '*') {
2167 arg->f_var = 1;
2168 p++;
2169 }
2170 if (ISDIGIT(*p)) {
2171 arg->n_trail = *p - '0';
2172 p++;
2173 }
2174 if (*p == ':') {
2175 arg->f_hash = 1;
2176 p++;
2177 }
2178 if (*p == '&') {
2179 arg->f_block = 1;
2180 p++;
2181 }
2182 if (*p != '\0') {
2183 rb_fatal("bad scan arg format: %s", fmt);
2184 }
2185}
2186
2187static int
2188rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *const argv, va_list vargs)
2189{
2190 int i, argi = 0;
2191 VALUE *var, hash = Qnil;
2192#define rb_scan_args_next_param() va_arg(vargs, VALUE *)
2193 const int kw_flag = arg->kw_flag;
2194 const int n_lead = arg->n_lead;
2195 const int n_opt = arg->n_opt;
2196 const int n_trail = arg->n_trail;
2197 const int n_mand = n_lead + n_trail;
2198 const bool f_var = arg->f_var;
2199 const bool f_hash = arg->f_hash;
2200 const bool f_block = arg->f_block;
2201
2202 /* capture an option hash - phase 1: pop from the argv */
2203 if (f_hash && argc > 0) {
2204 VALUE last = argv[argc - 1];
2205 if (rb_scan_args_keyword_p(kw_flag, last)) {
2206 hash = rb_hash_dup(last);
2207 argc--;
2208 }
2209 }
2210
2211 if (argc < n_mand) {
2212 goto argc_error;
2213 }
2214
2215 /* capture leading mandatory arguments */
2216 for (i = 0; i < n_lead; i++) {
2218 if (var) *var = argv[argi];
2219 argi++;
2220 }
2221 /* capture optional arguments */
2222 for (i = 0; i < n_opt; i++) {
2224 if (argi < argc - n_trail) {
2225 if (var) *var = argv[argi];
2226 argi++;
2227 }
2228 else {
2229 if (var) *var = Qnil;
2230 }
2231 }
2232 /* capture variable length arguments */
2233 if (f_var) {
2234 int n_var = argc - argi - n_trail;
2235
2237 if (0 < n_var) {
2238 if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
2239 argi += n_var;
2240 }
2241 else {
2242 if (var) *var = rb_ary_new();
2243 }
2244 }
2245 /* capture trailing mandatory arguments */
2246 for (i = 0; i < n_trail; i++) {
2248 if (var) *var = argv[argi];
2249 argi++;
2250 }
2251 /* capture an option hash - phase 2: assignment */
2252 if (f_hash) {
2254 if (var) *var = hash;
2255 }
2256 /* capture iterator block */
2257 if (f_block) {
2259 if (rb_block_given_p()) {
2260 *var = rb_block_proc();
2261 }
2262 else {
2263 *var = Qnil;
2264 }
2265 }
2266
2267 if (argi == argc) {
2268 return argc;
2269 }
2270
2271 argc_error:
2272 return -(argc + 1);
2273#undef rb_scan_args_next_param
2274}
2275
2276static int
2277rb_scan_args_result(const struct rb_scan_args_t *const arg, int argc)
2278{
2279 const int n_lead = arg->n_lead;
2280 const int n_opt = arg->n_opt;
2281 const int n_trail = arg->n_trail;
2282 const int n_mand = n_lead + n_trail;
2283 const bool f_var = arg->f_var;
2284
2285 if (argc >= 0) {
2286 return argc;
2287 }
2288
2289 argc = -argc - 1;
2290 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
2292}
2293
2294#undef rb_scan_args
2295int
2296rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
2297{
2298 va_list vargs;
2299 struct rb_scan_args_t arg;
2300 rb_scan_args_parse(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, fmt, &arg);
2301 va_start(vargs,fmt);
2302 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
2303 va_end(vargs);
2304 return rb_scan_args_result(&arg, argc);
2305}
2306
2307#undef rb_scan_args_kw
2308int
2309rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt, ...)
2310{
2311 va_list vargs;
2312 struct rb_scan_args_t arg;
2313 rb_scan_args_parse(kw_flag, fmt, &arg);
2314 va_start(vargs,fmt);
2315 argc = rb_scan_args_assign(&arg, argc, argv, vargs);
2316 va_end(vargs);
2317 return rb_scan_args_result(&arg, argc);
2318}
2319
2320int
2322{
2323 return rb_id_table_size(RCLASS_M_TBL(c)) == 0 ? FALSE : TRUE;
2324}
2325
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Definition: array.c:788
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
VALUE rb_ary_new(void)
Definition: array.c:749
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements.
Definition: array.c:2235
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:846
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:1314
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy iff RUBY_DEBUG is truthy.
Definition: assert.h:177
#define NORETURN(x)
Definition: attributes.h:152
#define UNREACHABLE_RETURN
Definition: assume.h:31
#define rb_scan_args_next_param()
#define extract_kwarg(keyword, val)
void rb_free_const_table(struct rb_id_table *tbl)
Definition: gc.c:2595
Our own, locale independent, character handling routines.
#define ISDIGIT
Definition: ctype.h:43
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
#define rb_define_method_id(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:656
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
#define rb_define_protected_method(klass, mid, func, arity)
Defines klass#mid and makes it protected.
Definition: cxxanyargs.hpp:664
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
Definition: cxxanyargs.hpp:672
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
Definition: cxxanyargs.hpp:660
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
Definition: cxxanyargs.hpp:678
#define mod(x, y)
Definition: date_strftime.c:28
#define recur(fmt)
#define MJIT_FUNC_EXPORTED
Definition: dllexport.h:55
uint8_t len
Definition: escape.c:17
#define FL_SINGLETON
Definition: fl_type.h:49
#define FL_WB_PROTECTED
Definition: fl_type.h:50
#define FL_PROMOTED1
Definition: fl_type.h:52
#define FL_FREEZE
Definition: fl_type.h:59
#define PRIsVALUE
Definition: function.c:10
int rb_objspace_garbage_object_p(VALUE obj)
Definition: gc.c:3933
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
Definition: gc.c:8022
#define CLASS_OF
Definition: globals.h:153
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod)
Definition: class.c:1489
#define SET_METACLASS_OF(k, cls)
Definition: class.c:45
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
Definition: class.c:125
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:962
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:748
VALUE rb_class_new(VALUE super)
Creates a new class.
Definition: class.c:253
VALUE rb_singleton_class_clone(VALUE obj)
Definition: class.c:459
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
Definition: class.c:1597
void rb_class_subclass_add(VALUE super, VALUE klass)
Definition: class.c:48
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
Definition: class.c:1563
void rb_prepend_module(VALUE klass, VALUE module)
Definition: class.c:1170
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1924
void rb_class_detach_subclasses(VALUE klass)
Definition: class.c:145
void Init_class_hierarchy(void)
Definition: class.c:648
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:797
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
Definition: class.c:466
#define METACLASS_OF(k)
Definition: class.c:44
VALUE rb_include_class_new(VALUE module, VALUE super)
Definition: class.c:923
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
Definition: class.c:1582
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
Definition: class.c:1651
VALUE rb_module_new(void)
Definition: class.c:856
#define META_CLASS_OF_CLASS_CLASS_P(k)
whether k is a meta^(n)-class of Class class
Definition: class.c:545
int rb_singleton_class_internal_p(VALUE sklass)
Definition: class.c:554
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
Definition: class.c:1474
void rb_check_inheritable(VALUE super)
Ensures a class can be derived from super.
Definition: class.c:231
#define id_attached
Definition: class.c:42
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
Definition: class.c:1527
VALUE rb_class_boot(VALUE super)
A utility function that wraps class_alloc.
Definition: class.c:213
VALUE rb_define_module(const char *name)
Definition: class.c:871
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
Definition: eval.c:477
void rb_class_detach_module_subclasses(VALUE klass)
Definition: class.c:157
VALUE rb_special_singleton_class(VALUE obj)
Definition: class.c:1819
VALUE rb_define_module_id_under(VALUE outer, ID id)
Definition: class.c:901
void rb_singleton_class_attached(VALUE klass, VALUE obj)
Attach a object to a singleton class.
Definition: class.c:530
void rb_freeze_singleton_class(VALUE x)
Definition: class.c:1873
VALUE rb_mod_included_modules(VALUE mod)
Definition: class.c:1233
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:820
VALUE rb_mod_ancestors(VALUE mod)
Definition: class.c:1301
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
Definition: class.c:722
VALUE rb_mod_include_p(VALUE mod, VALUE mod2)
Definition: class.c:1269
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod)
Definition: class.c:1512
#define ENSURE_EIGENCLASS(klass)
ensures klass belongs to its own eigenclass.
Definition: class.c:576
void rb_class_remove_from_module_subclasses(VALUE klass)
Definition: class.c:106
VALUE rb_mod_init_copy(VALUE clone, VALUE orig)
Definition: class.c:359
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:895
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:1893
VALUE rb_make_metaclass(VALUE obj, VALUE unused)
Definition: class.c:679
VALUE rb_define_module_id(ID id)
Definition: class.c:865
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
Definition: class.c:1612
VALUE rb_define_class_id(ID id, VALUE super)
Defines a new class.
Definition: class.c:701
void rb_class_remove_from_super_subclasses(VALUE klass)
Definition: class.c:88
VALUE rb_extract_keywords(VALUE *orighash)
Definition: class.c:2067
int rb_class_has_methods(VALUE c)
Definition: class.c:2321
void rb_define_attr(VALUE klass, const char *name, int read, int write)
Defines (a) public accessor method(s) for an attribute.
Definition: class.c:2012
VALUE rb_keyword_error_new(const char *error, VALUE keys)
Definition: class.c:2018
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1777
int rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2309
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1999
void rb_undef_methods_from(VALUE klass, VALUE super)
Definition: class.c:1791
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:935
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:2085
#define OBJ_FREEZE_RAW
Definition: fl_type.h:135
#define FL_TEST_RAW
Definition: fl_type.h:131
#define FL_SET
Definition: fl_type.h:128
#define FL_TEST
Definition: fl_type.h:130
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:712
void rb_bug(const char *fmt,...)
Definition: error.c:768
VALUE rb_eTypeError
Definition: error.c:1057
void rb_fatal(const char *fmt,...)
Definition: error.c:2968
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Definition: error.c:1107
VALUE rb_eArgError
Definition: error.c:1058
VALUE rb_cClass
Class class.
Definition: object.c:51
VALUE rb_mKernel
Kernel module.
Definition: object.c:48
VALUE rb_cObject
Object class.
Definition: object.c:49
VALUE rb_cNilClass
NilClass class.
Definition: object.c:53
VALUE rb_cFalseClass
FalseClass class.
Definition: object.c:55
VALUE rb_obj_class(VALUE)
Definition: object.c:245
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:585
VALUE rb_cBasicObject
BasicObject class.
Definition: object.c:47
VALUE rb_cModule
Module class.
Definition: object.c:50
VALUE rb_class_real(VALUE)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
Definition: object.c:235
VALUE rb_cTrueClass
TrueClass class.
Definition: object.c:54
void skip(file *in, unsigned n)
Definition: gzappend.c:202
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
Definition: hash.c:2293
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1498
VALUE rb_cHash
Definition: hash.c:106
VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:3549
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2901
VALUE rb_hash_dup(VALUE hash)
Definition: hash.c:1579
VALUE rb_hash_new(void)
Definition: hash.c:1538
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
Definition: id_table.c:257
size_t rb_id_table_size(const struct rb_id_table *tbl)
Definition: id_table.c:118
struct rb_id_table * rb_id_table_create(size_t capa)
Definition: id_table.c:96
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
Definition: id_table.c:292
rb_id_table_iterator_result
Definition: id_table.h:10
@ ID_TABLE_DELETE
Definition: id_table.h:13
@ ID_TABLE_CONTINUE
Definition: id_table.h:11
Thin wrapper to ruby/config.h.
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
#define rb_ary_new2
Definition: array.h:72
#define UNLIMITED_ARGUMENTS
Definition: error.h:29
void rb_error_arity(int, int, int)
#define rb_check_arity
Definition: error.h:34
#define OBJ_INIT_COPY(obj, orig)
Definition: object.h:31
VALUE rb_block_proc(void)
Definition: proc.c:826
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:3118
#define rb_str_cat_cstr(buf, str)
Definition: string.h:266
void rb_set_class_path_string(VALUE, VALUE, VALUE)
Definition: variable.c:214
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2624
int rb_const_defined_at(VALUE, ID)
Definition: variable.c:2934
VALUE rb_class_path(VALUE)
Definition: variable.c:169
VALUE rb_const_get_at(VALUE, ID)
Definition: variable.c:2630
void rb_const_set(VALUE, ID, VALUE)
Definition: variable.c:3003
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1242
int rb_const_defined(VALUE, ID)
Definition: variable.c:2928
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:1508
void rb_clear_constant_cache(void)
Definition: vm_method.c:127
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1926
#define ID2SYM
Definition: symbol.h:44
ID rb_intern(const char *)
Definition: symbol.c:785
#define CONST_ID
Definition: symbol.h:47
Internal header for Class.
#define RCLASS_SERIAL(c)
Definition: class.h:90
#define RCLASS_CLONED
Definition: class.h:97
#define RCLASS_INCLUDER(c)
Definition: class.h:94
#define RCLASS_IV_TBL(c)
Definition: class.h:77
#define RCLASS_ORIGIN(c)
Definition: class.h:87
#define RCLASS_CONST_TBL(c)
Definition: class.h:78
#define RCLASS_EXT(c)
Definition: class.h:76
#define RCLASS_M_TBL(c)
Definition: class.h:80
#define RCLASS_REFINED_CLASS(c)
Definition: class.h:88
#define RICLASS_IS_ORIGIN
Definition: class.h:96
Internal header for GC.
Internal header for Hash.
Internal header for Object.
Internal header for String.
#define rb_fstring_lit(str)
Definition: string.h:78
void rb_iv_tbl_copy(VALUE dst, VALUE src)
Definition: variable.c:3605
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value)
Definition: variable.c:3589
int rb_vm_add_root_module(VALUE module)
Definition: vm.c:2622
void rb_vm_check_redefinition_by_prepend(VALUE klass)
Definition: vm.c:1873
rb_serial_t rb_next_class_serial(void)
Definition: vm.c:366
voidpf uLong int origin
Definition: ioapi.h:144
#define T_MASK
Definition: md5.c:131
#define MEMCPY(p1, p2, type, n)
Definition: memory.h:129
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *me)
Definition: vm_method.c:606
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
Definition: vm_method.c:910
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
Definition: vm_method.c:1294
void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi)
Definition: vm_method.c:900
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
Definition: vm_method.c:655
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
Definition: vm_method.c:709
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me)
Definition: vm_method.c:286
rb_method_visibility_t
Definition: method.h:29
@ METHOD_VISI_PRIVATE
Definition: method.h:32
@ METHOD_VISI_PROTECTED
Definition: method.h:33
@ METHOD_VISI_PUBLIC
Definition: method.h:31
@ METHOD_VISI_UNDEF
Definition: method.h:30
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex)
Definition: vm_method.c:939
@ VM_METHOD_TYPE_ISEQ
Ruby method.
Definition: method.h:110
@ VM_METHOD_TYPE_REFINED
refinement
Definition: method.h:121
@ VM_METHOD_TYPE_UNDEF
Definition: method.h:117
void rb_clear_method_cache(VALUE klass_or_module, ID mid)
Definition: vm_method.c:236
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:198
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
Definition: vm_method.c:313
#define METHOD_ENTRY_VISI(me)
Definition: method.h:70
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
#define NEWOBJ_OF
Definition: newobj.h:35
const int id
Definition: nkf.c:209
const char * name
Definition: nkf.c:208
unsigned int last
Definition: nkf.c:4324
#define TRUE
Definition: nkf.h:175
#define FALSE
Definition: nkf.h:174
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
#define RARRAY_LEN
Definition: rarray.h:52
#define RBASIC(obj)
Definition: rbasic.h:34
#define RBASIC_CLASS
Definition: rbasic.h:35
#define RMODULE_INCLUDED_INTO_REFINEMENT
Definition: rclass.h:29
#define RMODULE_IS_REFINEMENT
Definition: rclass.h:28
#define RCLASS_SUPER
Definition: rclass.h:33
#define NULL
Definition: regenc.h:69
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:107
#define RGENGC_WB_PROTECTED_CLASS
Definition: rgengc.h:72
#define RB_OBJ_WRITTEN(a, oldv, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:114
#define RHASH_SIZE(h)
Definition: rhash.h:50
#define RHASH_EMPTY_P(h)
Definition: rhash.h:51
#define RSTRING_FSTR
Definition: rstring.h:40
int argc
Definition: ruby.c:240
char ** argv
Definition: ruby.c:241
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
Definition: scan_args.h:43
unsigned LONG_LONG rb_serial_t
Definition: serial.h:19
#define Qundef
#define SPECIAL_CONST_P
#define Qtrue
#define RTEST
#define Qnil
#define Qfalse
#define NIL_P
#define f
VALUE rb_sprintf(const char *,...)
Definition: sprintf.c:1203
@ ST_CONTINUE
Definition: st.h:99
unsigned long st_data_t
Definition: st.h:22
#define st_is_member(table, key)
Definition: st.h:97
#define st_foreach
Definition: st.h:142
#define st_init_numtable
Definition: st.h:106
#define st_add_direct
Definition: st.h:154
#define st_delete
Definition: st.h:118
#define st_free_table
Definition: st.h:156
#define ANYARGS
Definition: stdarg.h:42
Definition: class.h:60
VALUE klass
Definition: class.c:287
struct rb_id_table * tbl
Definition: class.c:288
VALUE old_klass
Definition: class.c:275
VALUE new_klass
Definition: class.c:274
Definition: class.c:1364
int recur
Definition: class.c:1366
st_table * list
Definition: class.c:1365
Definition: constant.h:33
VALUE value
Definition: constant.h:36
VALUE file
Definition: constant.h:37
CREF (Class REFerence)
Definition: method.h:44
rb_method_iseq_t iseq
Definition: method.h:179
union rb_method_definition_struct::@123 body
rb_method_refined_t refined
Definition: method.h:183
Definition: method.h:54
ID called_id
Definition: method.h:58
struct rb_method_definition_struct *const def
Definition: method.h:57
VALUE owner
Definition: method.h:59
rb_cref_t * cref
class reference, should be marked
Definition: method.h:136
rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
Definition: method.h:135
struct rb_method_entry_struct * orig_me
Definition: method.h:155
bool f_hash
Definition: class.c:2146
bool f_var
Definition: class.c:2145
bool f_block
Definition: class.c:2147
Definition: class.h:23
VALUE klass
Definition: class.h:24
struct rb_subclass_entry * next
Definition: class.h:25
Definition: st.h:79
st_index_t num_entries
Definition: st.h:86
void error(const char *msg)
Definition: untgz.c:593
#define ALLOC(size)
Definition: unzip.c:112
unsigned long VALUE
Definition: value.h:38
unsigned long ID
Definition: value.h:39
#define TYPE(_)
Definition: value_type.h:105
#define T_STRING
Definition: value_type.h:77
#define T_NIL
Definition: value_type.h:71
#define T_FLOAT
Definition: value_type.h:63
#define T_BIGNUM
Definition: value_type.h:56
#define T_FIXNUM
Definition: value_type.h:62
#define T_MODULE
Definition: value_type.h:69
#define T_TRUE
Definition: value_type.h:80
#define T_ICLASS
Definition: value_type.h:65
#define T_FALSE
Definition: value_type.h:60
#define T_SYMBOL
Definition: value_type.h:79
#define T_CLASS
Definition: value_type.h:57
#define BUILTIN_TYPE
Definition: value_type.h:84
#define SYMBOL_P
Definition: value_type.h:87
#define rb_id2str(id)
Definition: vm_backtrace.c:30
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
#define xfree
Definition: xmalloc.h:49
int write(ozstream &zs, const T *x, Items items)
Definition: zstream.h:264
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115
#define ZALLOC(strm, items, size)
Definition: zutil.h:266