92e018f75998fa65eec07dffe90b777ec431b2e5
[ruby.git] / internal / class.h
blob92e018f75998fa65eec07dffe90b777ec431b2e5
1 #ifndef INTERNAL_CLASS_H /*-*-C-*-vi:se ft=c:*/
2 #define INTERNAL_CLASS_H
3 /**
4 * @author Ruby developers <ruby-core@ruby-lang.org>
5 * @copyright This file is a part of the programming language Ruby.
6 * Permission is hereby granted, to either redistribute and/or
7 * modify this file, provided that the conditions mentioned in the
8 * file COPYING are met. Consult the file for details.
9 * @brief Internal header for Class.
11 #include "id_table.h" /* for struct rb_id_table */
12 #include "internal/gc.h" /* for RB_OBJ_WRITE */
13 #include "internal/serial.h" /* for rb_serial_t */
14 #include "internal/static_assert.h"
15 #include "ruby/internal/stdbool.h" /* for bool */
16 #include "ruby/intern.h" /* for rb_alloc_func_t */
17 #include "ruby/ruby.h" /* for struct RBasic */
18 #include "shape.h"
20 #ifdef RCLASS_SUPER
21 # undef RCLASS_SUPER
22 #endif
24 struct rb_subclass_entry {
25 VALUE klass;
26 struct rb_subclass_entry *next;
27 struct rb_subclass_entry *prev;
29 typedef struct rb_subclass_entry rb_subclass_entry_t;
31 struct rb_cvar_class_tbl_entry {
32 uint32_t index;
33 rb_serial_t global_cvar_state;
34 VALUE class_value;
37 struct rb_classext_struct {
38 VALUE *iv_ptr;
39 struct rb_id_table *const_tbl;
40 struct rb_id_table *callable_m_tbl;
41 struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
42 struct rb_id_table *cvc_tbl;
43 size_t superclass_depth;
44 VALUE *superclasses;
45 struct rb_subclass_entry *subclasses;
46 struct rb_subclass_entry *subclass_entry;
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_subclass_entry;
53 const VALUE origin_;
54 const VALUE refined_class;
55 rb_alloc_func_t allocator;
56 const VALUE includer;
57 #if !SHAPE_IN_BASIC_FLAGS
58 shape_id_t shape_id;
59 #endif
60 uint32_t max_iv_count;
61 unsigned char variation_count;
62 bool permanent_classpath;
63 VALUE classpath;
65 typedef struct rb_classext_struct rb_classext_t;
67 STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_classext_t *)0)->variation_count) * CHAR_BIT)));
69 struct RClass {
70 struct RBasic basic;
71 VALUE super;
72 struct rb_id_table *m_tbl;
73 #if SIZE_POOL_COUNT == 1
74 struct rb_classext_struct *ptr;
75 #endif
78 #if RCLASS_EXT_EMBEDDED
79 // Assert that classes can be embedded in size_pools[2] (which has 160B slot size)
80 STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
81 #endif
83 #if RCLASS_EXT_EMBEDDED
84 # define RCLASS_EXT(c) ((rb_classext_t *)((char *)(c) + sizeof(struct RClass)))
85 #else
86 # define RCLASS_EXT(c) (RCLASS(c)->ptr)
87 #endif
88 #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
89 #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
90 #define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
91 #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
92 #define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
93 #define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
94 #define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
95 #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
96 #define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
97 #define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
98 #define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
99 #define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator)
100 #define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
101 #define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
102 #define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
104 #define RICLASS_IS_ORIGIN FL_USER0
105 #define RCLASS_CLONED FL_USER1
106 #define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
107 #define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
109 /* class.c */
110 void rb_class_subclass_add(VALUE super, VALUE klass);
111 void rb_class_remove_from_super_subclasses(VALUE);
112 void rb_class_update_superclasses(VALUE);
113 size_t rb_class_superclasses_memsize(VALUE);
114 void rb_class_remove_subclass_head(VALUE);
115 int rb_singleton_class_internal_p(VALUE sklass);
116 VALUE rb_class_boot(VALUE);
117 VALUE rb_class_s_alloc(VALUE klass);
118 VALUE rb_module_s_alloc(VALUE klass);
119 void rb_module_set_initialized(VALUE module);
120 void rb_module_check_initializable(VALUE module);
121 VALUE rb_make_metaclass(VALUE, VALUE);
122 VALUE rb_include_class_new(VALUE, VALUE);
123 void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
124 void rb_class_detach_subclasses(VALUE);
125 void rb_class_detach_module_subclasses(VALUE);
126 void rb_class_remove_from_module_subclasses(VALUE);
127 VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
128 VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
129 VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
130 VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
131 VALUE rb_class_undefined_instance_methods(VALUE mod);
132 VALUE rb_special_singleton_class(VALUE);
133 VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
134 VALUE rb_singleton_class_get(VALUE obj);
135 void rb_undef_methods_from(VALUE klass, VALUE super);
137 static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
138 static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
139 static inline VALUE RCLASS_SUPER(VALUE klass);
140 static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
141 static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
143 MJIT_SYMBOL_EXPORT_BEGIN
144 VALUE rb_class_inherited(VALUE, VALUE);
145 VALUE rb_keyword_error_new(const char *, VALUE);
146 MJIT_SYMBOL_EXPORT_END
148 static inline void
149 RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
151 RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
152 if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
155 static inline void
156 RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
158 FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL);
161 static inline bool
162 RICLASS_OWNS_M_TBL_P(VALUE iclass)
164 return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN;
167 static inline void
168 RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
170 RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
173 static inline VALUE
174 RCLASS_SUPER(VALUE klass)
176 return RCLASS(klass)->super;
179 static inline VALUE
180 RCLASS_SET_SUPER(VALUE klass, VALUE super)
182 if (super) {
183 rb_class_remove_from_super_subclasses(klass);
184 rb_class_subclass_add(super, klass);
186 RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
187 rb_class_update_superclasses(klass);
188 return super;
191 static inline void
192 RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
194 assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
195 assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
197 RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath);
198 RCLASS_EXT(klass)->permanent_classpath = permanent;
201 #endif /* INTERNAL_CLASS_H */