1#ifndef INTERNAL_CLASS_H
2#define INTERNAL_CLASS_H
13#include "internal/box.h"
14#include "internal/serial.h"
15#include "internal/static_assert.h"
16#include "internal/variable.h"
21#include "ruby_assert.h"
39 return box_sub->refcount;
53 if (box_sub->refcount == 0) {
54 st_free_table(box_sub->tbl);
74 rb_serial_t global_cvar_state;
110 const VALUE refined_class;
116 VALUE attached_object;
119 const VALUE includer;
122 attr_index_t max_iv_count;
123 uint16_t superclass_depth;
124 unsigned char variation_count;
125 bool permanent_classpath : 1;
127 bool shared_const_tbl : 1;
128 bool iclass_is_origin : 1;
129 bool iclass_origin_shared_mtbl : 1;
130 bool superclasses_with_self : 1;
135STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (
sizeof(((
rb_classext_t *)0)->variation_count) * CHAR_BIT)));
151#if SIZEOF_VALUE >= SIZEOF_LONG_LONG
162static const uint16_t RCLASS_MAX_SUPERCLASS_DEPTH = ((uint16_t)-1);
164static inline bool RCLASS_SINGLETON_P(
VALUE klass);
166static inline bool RCLASS_PRIME_CLASSEXT_READABLE_P(
VALUE obj);
167static inline bool RCLASS_PRIME_CLASSEXT_WRITABLE_P(
VALUE obj);
168static inline void RCLASS_SET_PRIME_CLASSEXT_WRITABLE(
VALUE obj,
bool writable);
170#define RCLASS_EXT_PRIME(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
171#define RCLASS_EXT_PRIME_P(ext, c) (&((struct RClass_and_rb_classext_t*)(c))->classext == ext)
179#define RCLASSEXT_BOX(ext) (ext->box)
180#define RCLASSEXT_SUPER(ext) (ext->super)
181#define RCLASSEXT_FIELDS(ext) (ext->fields_obj ? ROBJECT_FIELDS(ext->fields_obj) : NULL)
182#define RCLASSEXT_FIELDS_OBJ(ext) (ext->fields_obj)
183#define RCLASSEXT_M_TBL(ext) (ext->m_tbl)
184#define RCLASSEXT_CONST_TBL(ext) (ext->const_tbl)
185#define RCLASSEXT_CALLABLE_M_TBL(ext) (ext->callable_m_tbl)
186#define RCLASSEXT_CC_TBL(ext) (ext->cc_tbl)
187#define RCLASSEXT_CVC_TBL(ext) (ext->cvc_tbl)
188#define RCLASSEXT_SUPERCLASS_DEPTH(ext) (ext->superclass_depth)
189#define RCLASSEXT_SUPERCLASSES(ext) (ext->superclasses)
190#define RCLASSEXT_SUBCLASSES(ext) (ext->subclasses)
191#define RCLASSEXT_BOX_SUPER_SUBCLASSES(ext) (ext->box_super_subclasses)
192#define RCLASSEXT_BOX_MODULE_SUBCLASSES(ext) (ext->box_module_subclasses)
193#define RCLASSEXT_ORIGIN(ext) (ext->origin_)
194#define RCLASSEXT_REFINED_CLASS(ext) (ext->refined_class)
196#define RCLASSEXT_INCLUDER(ext) (ext->as.iclass.includer)
197#define RCLASSEXT_PERMANENT_CLASSPATH(ext) (ext->permanent_classpath)
198#define RCLASSEXT_CLONED(ext) (ext->cloned)
199#define RCLASSEXT_SHARED_CONST_TBL(ext) (ext->shared_const_tbl)
200#define RCLASSEXT_ICLASS_IS_ORIGIN(ext) (ext->iclass_is_origin)
201#define RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) (ext->iclass_origin_shared_mtbl)
202#define RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) (ext->superclasses_with_self)
203#define RCLASSEXT_CLASSPATH(ext) (ext->classpath)
209#define RCLASS_PRIME_BOX(c) (RCLASS_EXT_PRIME(c)->box)
212#define RCLASS_PRIME_FIELDS_OBJ(c) (RCLASS_EXT_PRIME(c)->fields_obj)
213#define RCLASS_PRIME_M_TBL(c) (RCLASS_EXT_PRIME(c)->m_tbl)
214#define RCLASS_PRIME_CONST_TBL(c) (RCLASS_EXT_PRIME(c)->const_tbl)
215#define RCLASS_PRIME_CALLABLE_M_TBL(c) (RCLASS_EXT_PRIME(c)->callable_m_tbl)
216#define RCLASS_PRIME_CC_TBL(c) (RCLASS_EXT_PRIME(c)->cc_tbl)
217#define RCLASS_M_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT_PRIME(c)->m_tbl != tbl)
218#define RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT_PRIME(c)->callable_m_tbl != tbl)
219#define RCLASS_CC_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT_PRIME(c)->cc_tbl != tbl)
222#define RCLASS_SUPER(c) (RCLASS_EXT_READABLE(c)->super)
223#define RCLASS_M_TBL(c) (RCLASS_EXT_READABLE(c)->m_tbl)
224#define RCLASS_CONST_TBL(c) (RCLASS_EXT_READABLE(c)->const_tbl)
229#define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl)
230#define RCLASS_SUBCLASSES_X(c) (RCLASS_EXT_READABLE(c)->subclasses)
231#define RCLASS_SUBCLASSES_FIRST(c) (RCLASS_EXT_READABLE(c)->subclasses->head->next)
232#define RCLASS_ORIGIN(c) (RCLASS_EXT_READABLE(c)->origin_)
233#define RICLASS_IS_ORIGIN_P(c) (RCLASS_EXT_READABLE(c)->iclass_is_origin)
234#define RCLASS_PERMANENT_CLASSPATH_P(c) (RCLASS_EXT_READABLE(c)->permanent_classpath)
235#define RCLASS_CLONED_P(c) (RCLASS_EXT_READABLE(c)->cloned)
236#define RCLASS_CLASSPATH(c) (RCLASS_EXT_READABLE(c)->classpath)
239#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_PRIME(c)->superclass_depth)
240#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_PRIME(c)->superclasses)
241#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_PRIME(c)->superclasses_with_self)
244#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT_PRIME(c)->refined_class)
245#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT_PRIME(c)->as.singleton_class.attached_object)
246#define RCLASS_INCLUDER(c) (RCLASS_EXT_PRIME(c)->as.iclass.includer)
249#define RCLASS_MAX_IV_COUNT(ext) (RCLASS_EXT_PRIME(ext)->max_iv_count)
250#define RCLASS_VARIATION_COUNT(ext) (RCLASS_EXT_PRIME(ext)->variation_count)
253#define RCLASS_WRITABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->m_tbl)
254#define RCLASS_WRITABLE_CONST_TBL(c) (RCLASS_EXT_WRITABLE(c)->const_tbl)
255#define RCLASS_WRITABLE_CALLABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->callable_m_tbl)
256#define RCLASS_WRITABLE_CC_TBL(c) (RCLASS_EXT_WRITABLE(c)->cc_tbl)
257#define RCLASS_WRITABLE_CVC_TBL(c) (RCLASS_EXT_WRITABLE(c)->cvc_tbl)
258#define RCLASS_WRITABLE_SUBCLASSES(c) (RCLASS_EXT_WRITABLE(c)->subclasses)
260static inline void RCLASS_SET_SUPER(
VALUE klass,
VALUE super);
261static inline void RCLASS_WRITE_SUPER(
VALUE klass,
VALUE super);
262static inline void RCLASS_SET_CONST_TBL(
VALUE klass,
struct rb_id_table *table,
bool shared);
263static inline void RCLASS_WRITE_CONST_TBL(
VALUE klass,
struct rb_id_table *table,
bool shared);
264static inline void RCLASS_WRITE_CALLABLE_M_TBL(
VALUE klass,
struct rb_id_table *table);
265static inline void RCLASS_WRITE_CC_TBL(
VALUE klass,
VALUE table);
266static inline void RCLASS_SET_CVC_TBL(
VALUE klass,
struct rb_id_table *table);
267static inline void RCLASS_WRITE_CVC_TBL(
VALUE klass,
struct rb_id_table *table);
269static inline void RCLASS_WRITE_SUPERCLASSES(
VALUE klass,
size_t depth,
VALUE *superclasses,
bool with_self);
274static inline void RCLASS_SET_ORIGIN(
VALUE klass,
VALUE origin);
275static inline void RCLASS_WRITE_ORIGIN(
VALUE klass,
VALUE origin);
276static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(
VALUE iclass);
277static inline void RICLASS_WRITE_ORIGIN_SHARED_MTBL(
VALUE iclass);
278static inline bool RICLASS_OWNS_M_TBL_P(
VALUE iclass);
280static inline void RCLASS_SET_REFINED_CLASS(
VALUE klass,
VALUE refined);
283static inline VALUE RCLASS_SET_ATTACHED_OBJECT(
VALUE klass,
VALUE attached_object);
285static inline void RCLASS_SET_INCLUDER(
VALUE iclass,
VALUE klass);
286static inline void RCLASS_SET_MAX_IV_COUNT(
VALUE klass, attr_index_t count);
287static inline void RCLASS_SET_CLONED(
VALUE klass,
bool cloned);
288static inline void RCLASS_SET_CLASSPATH(
VALUE klass,
VALUE classpath,
bool permanent);
289static inline void RCLASS_WRITE_CLASSPATH(
VALUE klass,
VALUE classpath,
bool permanent);
291#define RCLASS_IS_ROOT FL_USER0
293#define RCLASS_PRIME_CLASSEXT_WRITABLE FL_USER2
294#define RCLASS_IS_INITIALIZED FL_USER3
296#define RCLASS_BOXABLE FL_USER4
299RCLASS_CLASSEXT_TBL(
VALUE klass)
303 return box_klass->box_classext_tbl;
313 box_klass->box_classext_tbl = tbl;
318void rb_class_ensure_writable(
VALUE obj);
326 st_table *tbl = RCLASS_CLASSEXT_TBL(obj);
327 VM_ASSERT(BOX_USER_P(box));
328 VM_ASSERT(box->box_object);
329 VM_ASSERT(RCLASSEXT_BOX(ext) == box);
331 tbl = st_init_numtable_with_size(1);
332 RCLASS_SET_CLASSEXT_TBL(obj, tbl);
334 if (rb_st_table_size(tbl) == 0) {
338 rb_class_set_box_classext(obj, box, ext);
343#define VM_ASSERT_BOXABLE_TYPE(klass) \
344 VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS), "%s is not boxable type", rb_type_str(BUILTIN_TYPE(klass)))
347RCLASS_PRIME_CLASSEXT_READABLE_P(
VALUE klass)
349 VM_ASSERT(klass != 0,
"klass should be a valid object");
350 VM_ASSERT_BOXABLE_TYPE(klass);
352 return !
FL_TEST_RAW(klass, RCLASS_BOXABLE) || RCLASS_CLASSEXT_TBL(klass) == NULL;
356RCLASS_PRIME_CLASSEXT_WRITABLE_P(
VALUE klass)
358 VM_ASSERT(klass != 0,
"klass should be a valid object");
359 VM_ASSERT_BOXABLE_TYPE(klass);
360 return FL_TEST(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
364RCLASS_SET_PRIME_CLASSEXT_WRITABLE(
VALUE klass,
bool writable)
366 VM_ASSERT(klass != 0,
"klass should be a valid object");
367 VM_ASSERT_BOXABLE_TYPE(klass);
369 FL_SET(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
372 FL_UNSET(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
377RCLASS_EXT_TABLE_LOOKUP_INTERNAL(
VALUE obj,
const rb_box_t *box)
379 st_data_t classext_ptr;
380 st_table *classext_tbl = RCLASS_CLASSEXT_TBL(obj);
382 if (rb_st_lookup(classext_tbl, (st_data_t)box->box_object, &classext_ptr)) {
392 rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, box);
396 return RCLASS_EXT_PRIME(obj);
403 || RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
404 return RCLASS_EXT_PRIME(obj);
406 return RCLASS_EXT_READABLE_LOOKUP(obj, box);
410RCLASS_EXT_READABLE(
VALUE obj)
413 if (RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
414 return RCLASS_EXT_PRIME(obj);
417 box = rb_current_box();
418 if (BOX_ROOT_P(box)) {
419 return RCLASS_EXT_PRIME(obj);
421 return RCLASS_EXT_READABLE_LOOKUP(obj, box);
430 ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, box);
436 ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, box);
438 ext = rb_class_duplicate_classext(RCLASS_EXT_PRIME(obj), obj, box);
439 first_set = RCLASS_SET_BOX_CLASSEXT(obj, box, ext);
442 RCLASS_SET_PRIME_CLASSEXT_WRITABLE(obj,
false);
453 || RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj)) {
454 return RCLASS_EXT_PRIME(obj);
456 return RCLASS_EXT_WRITABLE_LOOKUP(obj, box);
460RCLASS_EXT_WRITABLE(
VALUE obj)
463 if (LIKELY(RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj))) {
464 return RCLASS_EXT_PRIME(obj);
467 box = rb_current_box();
468 if (BOX_ROOT_P(box)) {
469 return RCLASS_EXT_PRIME(obj);
471 return RCLASS_EXT_WRITABLE_LOOKUP(obj, box);
484 RB_OBJ_WRITE(klass, &(RCLASSEXT_INCLUDER(ext)), includer);
488typedef void rb_class_classext_foreach_callback_func(
rb_classext_t *classext,
bool is_prime,
VALUE box_value,
void *arg);
489void rb_class_classext_foreach(
VALUE klass, rb_class_classext_foreach_callback_func *func,
void *arg);
490void rb_class_subclass_add(
VALUE super,
VALUE klass);
493void rb_class_update_superclasses(
VALUE);
494int rb_singleton_class_internal_p(
VALUE sklass);
499void rb_class_set_initialized(
VALUE klass);
500void rb_module_check_initializable(
VALUE module);
508VALUE rb_class_undefined_instance_methods(
VALUE mod);
512void rb_undef_methods_from(
VALUE klass,
VALUE super);
514VALUE rb_keyword_error_new(
const char *,
VALUE);
520RUBY_SYMBOL_EXPORT_BEGIN
525unsigned char rb_class_variation_count(
VALUE klass);
527RUBY_SYMBOL_EXPORT_END
530RCLASS_SINGLETON_P(
VALUE klass)
538 RB_OBJ_WRITE(klass, &RCLASSEXT_SUPER(RCLASS_EXT_PRIME(klass)), super);
544 RB_OBJ_WRITE(klass, &RCLASSEXT_SUPER(RCLASS_EXT_WRITABLE(klass)), super);
548RCLASS_WRITABLE_ENSURE_FIELDS_OBJ(
VALUE obj)
552 if (!ext->fields_obj) {
553 RB_OBJ_WRITE(obj, &ext->fields_obj, rb_imemo_fields_new(obj, 1,
true));
555 return ext->fields_obj;
559RCLASS_WRITABLE_FIELDS_OBJ(
VALUE obj)
562 return RCLASSEXT_FIELDS_OBJ(RCLASS_EXT_WRITABLE(obj));
570 RB_OBJ_ATOMIC_WRITE(obj, &ext->fields_obj, fields_obj);
574RCLASS_WRITABLE_SET_FIELDS_OBJ(
VALUE obj,
VALUE fields_obj)
578 RCLASSEXT_SET_FIELDS_OBJ(obj, RCLASS_EXT_WRITABLE(obj), fields_obj);
581static inline uint32_t
582RCLASS_FIELDS_COUNT(
VALUE obj)
586 VALUE fields_obj = RCLASS_WRITABLE_FIELDS_OBJ(obj);
588 if (rb_shape_obj_too_complex_p(fields_obj)) {
589 return (uint32_t)rb_st_table_size(rb_imemo_fields_complex_tbl(fields_obj));
592 return RSHAPE_LEN(RBASIC_SHAPE_ID(fields_obj));
601 RCLASSEXT_M_TBL(RCLASS_EXT_PRIME(klass)) = table;
607 RCLASSEXT_M_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
614 RCLASSEXT_CONST_TBL(ext) = table;
616 RCLASSEXT_SHARED_CONST_TBL(ext) =
true;
623 RCLASSEXT_CONST_TBL(ext) = table;
625 RCLASSEXT_SHARED_CONST_TBL(ext) =
true;
631 RCLASSEXT_CALLABLE_M_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
637 RB_OBJ_ATOMIC_WRITE(klass, &RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)), table);
643 RCLASSEXT_CVC_TBL(RCLASS_EXT_PRIME(klass)) = table;
649 RCLASSEXT_CVC_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
653RCLASS_SET_REFINED_CLASS(
VALUE klass,
VALUE refined)
655 RB_OBJ_WRITE(klass, &RCLASSEXT_REFINED_CLASS(RCLASS_EXT_PRIME(klass)), refined);
659RCLASS_ALLOCATOR(
VALUE klass)
665 return RCLASS_EXT_PRIME(klass)->as.class.allocator;
673 RCLASS_EXT_PRIME(klass)->as.class.allocator = allocator;
681 if (klass != origin) RCLASSEXT_ICLASS_IS_ORIGIN(RCLASS_EXT_WRITABLE(origin)) =
true;
689 if (klass != origin) RCLASSEXT_ICLASS_IS_ORIGIN(RCLASS_EXT_WRITABLE(origin)) =
true;
693RICLASS_SET_ORIGIN_SHARED_MTBL(
VALUE iclass)
695 RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(RCLASS_EXT_PRIME(iclass)) =
true;
699RICLASS_WRITE_ORIGIN_SHARED_MTBL(
VALUE iclass)
701 RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(RCLASS_EXT_WRITABLE(iclass)) =
true;
705RICLASS_OWNS_M_TBL_P(
VALUE iclass)
708 return RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext);
719RCLASS_WRITE_SUPERCLASSES(
VALUE klass,
size_t depth,
VALUE *superclasses,
bool with_self)
724 RCLASSEXT_SUPERCLASS_DEPTH(ext) = depth;
725 RCLASSEXT_SUPERCLASSES(ext) = superclasses;
726 RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) = with_self;
733 RCLASSEXT_SUBCLASSES(ext) = anchor;
740 if (RCLASSEXT_BOX_SUPER_SUBCLASSES(ext))
741 rb_box_subclasses_ref_dec(RCLASSEXT_BOX_SUPER_SUBCLASSES(ext));
742 RCLASSEXT_BOX_SUPER_SUBCLASSES(ext) = rb_box_subclasses_ref_inc(box_subclasses);
749 if (RCLASSEXT_BOX_MODULE_SUBCLASSES(ext))
750 rb_box_subclasses_ref_dec(RCLASSEXT_BOX_MODULE_SUBCLASSES(ext));
751 RCLASSEXT_BOX_MODULE_SUBCLASSES(ext) = rb_box_subclasses_ref_inc(box_subclasses);
755RCLASS_SET_CLASSPATH(
VALUE klass,
VALUE classpath,
bool permanent)
762 RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
763 RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
767RCLASS_WRITE_CLASSPATH(
VALUE klass,
VALUE classpath,
bool permanent)
774 RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
775 RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
779RCLASS_SET_ATTACHED_OBJECT(
VALUE klass,
VALUE attached_object)
781 assert(RCLASS_SINGLETON_P(klass));
783 RB_OBJ_WRITE(klass, &RCLASS_EXT_PRIME(klass)->as.singleton_class.attached_object, attached_object);
784 return attached_object;
788RCLASS_SET_MAX_IV_COUNT(
VALUE klass, attr_index_t count)
790 RCLASS_MAX_IV_COUNT(klass) = count;
794RCLASS_SET_CLONED(
VALUE klass,
bool cloned)
796 RCLASSEXT_CLONED(RCLASS_EXT_PRIME(klass)) = cloned;
800RCLASS_INITIALIZED_P(
VALUE klass)
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
static bool RB_FL_ABLE(VALUE obj)
Checks if the object is flaggable.
@ RUBY_FL_SHAREABLE
This flag has something to do with Ractor.
VALUE rb_class_boot(VALUE)
A utility function that wraps class_alloc.
VALUE rb_class_inherited(VALUE, VALUE)
Calls Class::inherited.
VALUE rb_singleton_class_get(VALUE obj)
Returns the singleton class of obj, or nil if obj is not a singleton object.
#define FL_SINGLETON
Old name of RUBY_FL_SINGLETON.
#define T_STRING
Old name of RUBY_T_STRING.
#define xfree
Old name of ruby_xfree.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
#define FL_SET
Old name of RB_FL_SET.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define FL_TEST
Old name of RB_FL_TEST.
#define FL_UNSET
Old name of RB_FL_UNSET.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
VALUE(* rb_alloc_func_t)(VALUE klass)
This is the type of functions that ruby calls when trying to allocate an object.
Ruby object's base components.
Internal header for Ruby Box.
Internal header for Class.
struct rb_subclass_anchor * subclasses
The head of subclasses is a blank (w/o klass) entry to be referred from anchor (and be never deleted)...
rb_box_subclasses_t * box_super_subclasses
The box_super_subclasses points the box_subclasses struct to retreive the subclasses of the super cla...
rb_box_subclasses_t * box_module_subclasses
In the case that this is an ICLASS, box_module_subclasses points to the link in the module's subclass...
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.