Merge pull request #2991 from shyouhei/ruby.h
[ruby.git] / internal / class.h
blobf5df0a6a70234cb5e506eae1a56a5a5572cc2066
1 /** \noop-*-C-*-vi:ft=c
2 * @file
3 * @author Ruby developers <ruby-core@ruby-lang.org>
4 * @copyright This file is a part of the programming language Ruby.
5 * Permission is hereby granted, to either redistribute and/or
6 * modify this file, provided that the conditions mentioned in the
7 * file COPYING are met. Consult the file for details.
8 * @brief Internal header for Class.
9 */
10 #ifndef INTERNAL_CLASS_H
11 #define INTERNAL_CLASS_H
12 #include "id_table.h" /* for struct rb_id_table */
13 #include "internal/gc.h" /* for RB_OBJ_WRITE */
14 #include "internal/serial.h" /* for rb_serial_t */
15 #include "ruby/3/stdbool.h" /* for bool */
16 #include "ruby/intern.h" /* for rb_alloc_func_t */
17 #include "ruby/ruby.h" /* for struct RBasic */
19 #ifdef RClass
20 # undef RClass /* See also include/ruby/backward.h */
21 #endif
23 #ifdef RCLASS_SUPER
24 # undef RCLASS_SUPER
25 #endif
27 struct rb_deprecated_classext_struct {
28 char conflict[sizeof(VALUE) * 3];
31 struct rb_subclass_entry {
32 VALUE klass;
33 struct rb_subclass_entry *next;
36 struct rb_classext_struct {
37 struct st_table *iv_index_tbl;
38 struct st_table *iv_tbl;
39 #if SIZEOF_SERIAL_T == SIZEOF_VALUE /* otherwise m_tbl is in struct RClass */
40 struct rb_id_table *m_tbl;
41 #endif
42 struct rb_id_table *const_tbl;
43 struct rb_id_table *callable_m_tbl;
44 struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
45 struct rb_subclass_entry *subclasses;
46 struct rb_subclass_entry **parent_subclasses;
47 /**
48 * In the case that this is an `ICLASS`, `module_subclasses` points to the link
49 * in the module's `subclasses` list that indicates that the klass has been
50 * included. Hopefully that makes sense.
52 struct rb_subclass_entry **module_subclasses;
53 #if SIZEOF_SERIAL_T != SIZEOF_VALUE /* otherwise class_serial is in struct RClass */
54 rb_serial_t class_serial;
55 #endif
56 const VALUE origin_;
57 const VALUE refined_class;
58 rb_alloc_func_t allocator;
59 const VALUE includer;
62 struct RClass {
63 struct RBasic basic;
64 VALUE super;
65 struct rb_classext_struct *ptr;
66 #if SIZEOF_SERIAL_T == SIZEOF_VALUE
67 /* Class serial is as wide as VALUE. Place it here. */
68 rb_serial_t class_serial;
69 #else
70 /* Class serial does not fit into struct RClass. Place m_tbl instead. */
71 struct rb_id_table *m_tbl;
72 #endif
75 typedef struct rb_subclass_entry rb_subclass_entry_t;
76 typedef struct rb_classext_struct rb_classext_t;
78 #define RCLASS_EXT(c) (RCLASS(c)->ptr)
79 #define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
80 #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
81 #if SIZEOF_SERIAL_T == SIZEOF_VALUE
82 # define RCLASS_M_TBL(c) (RCLASS_EXT(c)->m_tbl)
83 #else
84 # define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
85 #endif
86 #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
87 #define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
88 #define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
89 #define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
90 #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
91 #if SIZEOF_SERIAL_T == SIZEOF_VALUE
92 # define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
93 #else
94 # define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
95 #endif
96 #define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
98 #define RCLASS_CLONED FL_USER6
99 #define RICLASS_IS_ORIGIN FL_USER5
100 #define RCLASS_REFINED_BY_ANY FL_USER7
102 /* class.c */
103 void rb_class_subclass_add(VALUE super, VALUE klass);
104 void rb_class_remove_from_super_subclasses(VALUE);
105 int rb_singleton_class_internal_p(VALUE sklass);
106 VALUE rb_class_boot(VALUE);
107 VALUE rb_make_metaclass(VALUE, VALUE);
108 VALUE rb_include_class_new(VALUE, VALUE);
109 void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
110 void rb_class_detach_subclasses(VALUE);
111 void rb_class_detach_module_subclasses(VALUE);
112 void rb_class_remove_from_module_subclasses(VALUE);
113 VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
114 VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
115 VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
116 VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
117 VALUE rb_special_singleton_class(VALUE);
118 VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
119 VALUE rb_singleton_class_get(VALUE obj);
120 int rb_class_has_methods(VALUE c);
121 void rb_undef_methods_from(VALUE klass, VALUE super);
122 static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
123 static inline VALUE RCLASS_SUPER(VALUE klass);
124 static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
125 static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
127 MJIT_SYMBOL_EXPORT_BEGIN
128 VALUE rb_class_inherited(VALUE, VALUE);
129 VALUE rb_keyword_error_new(const char *, VALUE);
130 MJIT_SYMBOL_EXPORT_END
132 static inline void
133 RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
135 RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
136 if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
139 static inline void
140 RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
142 RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
145 static inline VALUE
146 RCLASS_SUPER(VALUE klass)
148 return RCLASS(klass)->super;
151 static inline VALUE
152 RCLASS_SET_SUPER(VALUE klass, VALUE super)
154 if (super) {
155 rb_class_remove_from_super_subclasses(klass);
156 rb_class_subclass_add(super, klass);
158 RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
159 return super;
162 #endif /* INTERNAL_CLASS_H */