1 #ifndef INTERNAL_CLASS_H /*-*-C-*-vi:se ft=c:*/
2 #define INTERNAL_CLASS_H
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/serial.h" /* for rb_serial_t */
13 #include "internal/static_assert.h"
14 #include "ruby/internal/stdbool.h" /* for bool */
15 #include "ruby/intern.h" /* for rb_alloc_func_t */
16 #include "ruby/ruby.h" /* for struct RBasic */
23 struct rb_subclass_entry
{
25 struct rb_subclass_entry
*next
;
26 struct rb_subclass_entry
*prev
;
28 typedef struct rb_subclass_entry rb_subclass_entry_t
;
30 struct rb_cvar_class_tbl_entry
{
32 rb_serial_t global_cvar_state
;
36 struct rb_classext_struct
{
38 struct rb_id_table
*const_tbl
;
39 struct rb_id_table
*callable_m_tbl
;
40 struct rb_id_table
*cc_tbl
; /* ID -> [[ci, cc1], cc2, ...] */
41 struct rb_id_table
*cvc_tbl
;
42 size_t superclass_depth
;
44 struct rb_subclass_entry
*subclasses
;
45 struct rb_subclass_entry
*subclass_entry
;
47 * In the case that this is an `ICLASS`, `module_subclasses` points to the link
48 * in the module's `subclasses` list that indicates that the klass has been
49 * included. Hopefully that makes sense.
51 struct rb_subclass_entry
*module_subclass_entry
;
53 const VALUE refined_class
;
54 rb_alloc_func_t allocator
;
56 #if !SHAPE_IN_BASIC_FLAGS
59 uint32_t max_iv_count
;
60 unsigned char variation_count
;
61 bool permanent_classpath
;
64 typedef struct rb_classext_struct rb_classext_t
;
66 STATIC_ASSERT(shape_max_variations
, SHAPE_MAX_VARIATIONS
< (1 << (sizeof(((rb_classext_t
*)0)->variation_count
) * CHAR_BIT
)));
71 struct rb_id_table
*m_tbl
;
72 #if SIZE_POOL_COUNT == 1
73 struct rb_classext_struct
*ptr
;
77 #if RCLASS_EXT_EMBEDDED
78 // Assert that classes can be embedded in size_pools[2] (which has 160B slot size)
79 STATIC_ASSERT(sizeof_rb_classext_t
, sizeof(struct RClass
) + sizeof(rb_classext_t
) <= 4 * RVALUE_SIZE
);
82 #if RCLASS_EXT_EMBEDDED
83 # define RCLASS_EXT(c) ((rb_classext_t *)((char *)(c) + sizeof(struct RClass)))
85 # define RCLASS_EXT(c) (RCLASS(c)->ptr)
87 #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
88 #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
89 #define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
90 #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
91 #define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
92 #define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
93 #define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
94 #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
95 #define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
96 #define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
97 #define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
98 #define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator)
99 #define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
100 #define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
101 #define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
103 #define RICLASS_IS_ORIGIN FL_USER0
104 #define RCLASS_CLONED FL_USER1
105 #define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
106 #define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
109 void rb_class_subclass_add(VALUE super
, VALUE klass
);
110 void rb_class_remove_from_super_subclasses(VALUE
);
111 void rb_class_update_superclasses(VALUE
);
112 size_t rb_class_superclasses_memsize(VALUE
);
113 void rb_class_remove_subclass_head(VALUE
);
114 int rb_singleton_class_internal_p(VALUE sklass
);
115 VALUE
rb_class_boot(VALUE
);
116 VALUE
rb_class_s_alloc(VALUE klass
);
117 VALUE
rb_module_s_alloc(VALUE klass
);
118 void rb_module_set_initialized(VALUE module
);
119 void rb_module_check_initializable(VALUE module
);
120 VALUE
rb_make_metaclass(VALUE
, VALUE
);
121 VALUE
rb_include_class_new(VALUE
, VALUE
);
122 void rb_class_foreach_subclass(VALUE klass
, void (*f
)(VALUE
, VALUE
), VALUE
);
123 void rb_class_detach_subclasses(VALUE
);
124 void rb_class_detach_module_subclasses(VALUE
);
125 void rb_class_remove_from_module_subclasses(VALUE
);
126 VALUE
rb_obj_methods(int argc
, const VALUE
*argv
, VALUE obj
);
127 VALUE
rb_obj_protected_methods(int argc
, const VALUE
*argv
, VALUE obj
);
128 VALUE
rb_obj_private_methods(int argc
, const VALUE
*argv
, VALUE obj
);
129 VALUE
rb_obj_public_methods(int argc
, const VALUE
*argv
, VALUE obj
);
130 VALUE
rb_class_undefined_instance_methods(VALUE mod
);
131 VALUE
rb_special_singleton_class(VALUE
);
132 VALUE
rb_singleton_class_clone_and_attach(VALUE obj
, VALUE attach
);
133 VALUE
rb_singleton_class_get(VALUE obj
);
134 void rb_undef_methods_from(VALUE klass
, VALUE super
);
136 static inline void RCLASS_SET_ORIGIN(VALUE klass
, VALUE origin
);
137 static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass
);
138 static inline VALUE
RCLASS_SUPER(VALUE klass
);
139 static inline VALUE
RCLASS_SET_SUPER(VALUE klass
, VALUE super
);
140 static inline void RCLASS_SET_INCLUDER(VALUE iclass
, VALUE klass
);
142 MJIT_SYMBOL_EXPORT_BEGIN
143 VALUE
rb_class_inherited(VALUE
, VALUE
);
144 VALUE
rb_keyword_error_new(const char *, VALUE
);
145 MJIT_SYMBOL_EXPORT_END
148 RCLASS_SET_ORIGIN(VALUE klass
, VALUE origin
)
150 RB_OBJ_WRITE(klass
, &RCLASS_ORIGIN(klass
), origin
);
151 if (klass
!= origin
) FL_SET(origin
, RICLASS_IS_ORIGIN
);
155 RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass
)
157 FL_SET(iclass
, RICLASS_ORIGIN_SHARED_MTBL
);
161 RICLASS_OWNS_M_TBL_P(VALUE iclass
)
163 return FL_TEST_RAW(iclass
, RICLASS_IS_ORIGIN
| RICLASS_ORIGIN_SHARED_MTBL
) == RICLASS_IS_ORIGIN
;
167 RCLASS_SET_INCLUDER(VALUE iclass
, VALUE klass
)
169 RB_OBJ_WRITE(iclass
, &RCLASS_INCLUDER(iclass
), klass
);
173 RCLASS_SUPER(VALUE klass
)
175 return RCLASS(klass
)->super
;
179 RCLASS_SET_SUPER(VALUE klass
, VALUE super
)
182 rb_class_remove_from_super_subclasses(klass
);
183 rb_class_subclass_add(super
, klass
);
185 RB_OBJ_WRITE(klass
, &RCLASS(klass
)->super
, super
);
186 rb_class_update_superclasses(klass
);
191 RCLASS_SET_CLASSPATH(VALUE klass
, VALUE classpath
, bool permanent
)
193 assert(BUILTIN_TYPE(klass
) == T_CLASS
|| BUILTIN_TYPE(klass
) == T_MODULE
);
194 assert(classpath
== 0 || BUILTIN_TYPE(classpath
) == T_STRING
);
196 RB_OBJ_WRITE(klass
, &(RCLASS_EXT(klass
)->classpath
), classpath
);
197 RCLASS_EXT(klass
)->permanent_classpath
= permanent
;
200 #endif /* INTERNAL_CLASS_H */