Ruby: include/ruby/internal/core/rtypeddata.h Source File

Ruby 4.0.6p0 (2026-07-14 revision 03b6d3f8898a28604fe6cb00eae3226b821168f4)

rtypeddata.h
Go to the documentation of this file.
1#ifndef RBIMPL_RTYPEDDATA_H /*-*-C++-*-vi:se ft=cpp:*/
2#define RBIMPL_RTYPEDDATA_H
23#include "ruby/internal/config.h"
24
25#ifdef STDC_HEADERS
26# include <stddef.h>
27#endif
28
29#include "ruby/internal/assume.h"
30#include "ruby/internal/attr/artificial.h"
31#include "ruby/internal/attr/flag_enum.h"
32#include "ruby/internal/attr/nonnull.h"
33#include "ruby/internal/attr/pure.h"
34#include "ruby/internal/cast.h"
35#include "ruby/internal/core/rbasic.h"
36#include "ruby/internal/core/rdata.h"
37#include "ruby/internal/dllexport.h"
38#include "ruby/internal/error.h"
39#include "ruby/internal/fl_type.h"
40#include "ruby/internal/static_assert.h"
41#include "ruby/internal/stdbool.h"
42#include "ruby/internal/value_type.h"
43
51#define HAVE_TYPE_RB_DATA_TYPE_T 1
52
60#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
61
69#define HAVE_RB_DATA_TYPE_T_PARENT 1
70
80#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
81
87#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
88
95#define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj))
96
103#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
104
106#define Check_TypedStruct(v, t) \
107 rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))
108
110#define RTYPEDDATA_P RTYPEDDATA_P
111#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
112#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
113#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
114#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
115#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
117
118#define TYPED_DATA_EMBEDDED ((VALUE)1)
119#define TYPED_DATA_PTR_MASK (~(TYPED_DATA_EMBEDDED))
120
126enum
127 RBIMPL_ATTR_FLAG_ENUM()
128rbimpl_typeddata_flags {
142 RUBY_TYPED_FREE_IMMEDIATELY = 1,
143
144 RUBY_TYPED_EMBEDDABLE = 2,
145
158 RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,
159
160 // experimental flag
161 // Similar to RUBY_TYPED_FROZEN_SHAREABLE, but doesn't make shareable
162 // reachable objects from this T_DATA object on the Ractor.make_shareable.
163 // If it refers to unshareable objects, simply raise an error.
164 // RUBY_TYPED_FROZEN_SHAREABLE_NO_REC = RUBY_FL_FINALIZE,
165
185 RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
186
190 RUBY_TYPED_FL_IS_TYPED_DATA = RUBY_FL_USERPRIV0,
191
197 RUBY_TYPED_DECL_MARKING = RUBY_FL_USER2
198};
199
205 typedef struct rb_data_type_struct rb_data_type_t;
206
208 struct rb_data_type_struct {
209
215 const char *wrap_struct_name;
216
218 struct {
219
229 RUBY_DATA_FUNC dmark;
230
238 RUBY_DATA_FUNC dfree;
239
248 size_t (*dsize)(const void *);
249
259 RUBY_DATA_FUNC dcompact;
260
265 void *reserved[1]; /* For future extension.
266 This array *must* be filled with ZERO. */
267 } function;
268
298 const rb_data_type_t *parent;
299
304 void *data; /* This area can be used for any purpose
305 by a programmer who define the type. */
306
317 VALUE flags; /* RUBY_FL_WB_PROTECTED */
318};
319
358 struct RTypedData {
359
361 struct RBasic basic;
362
364 VALUE fields_obj;
365
375 const VALUE type;
376
378 void *data;
379};
380
381#if !defined(__cplusplus) || __cplusplus >= 201103L
382 RBIMPL_STATIC_ASSERT(data_in_rtypeddata, offsetof(struct RData, data) == offsetof(struct RTypedData, data));
383#endif
384
385 RBIMPL_SYMBOL_EXPORT_BEGIN()
386 RBIMPL_ATTR_NONNULL((3))
397 VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type);
398
412 VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
413
426int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
427
436int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
437
448void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
449 RBIMPL_SYMBOL_EXPORT_END()
450
461#define TypedData_Wrap_Struct(klass,data_type,sval)\
462 rb_data_typed_object_wrap((klass),(sval),(data_type))
463
477#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
478 VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
479 (sval) = (type *)RTYPEDDATA_GET_DATA(result); \
480 RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
481
495#ifdef HAVE_STMT_AND_DECL_IN_EXPR
496#define TypedData_Make_Struct(klass, type, data_type, sval) \
497 RB_GNUC_EXTENSION({ \
498 TypedData_Make_Struct0( \
499 data_struct_obj, \
500 klass, \
501 type, \
502 sizeof(type), \
503 data_type, \
504 sval); \
505 data_struct_obj; \
506 })
507#else
508#define TypedData_Make_Struct(klass, type, data_type, sval) \
509 rb_data_typed_object_make( \
510 (klass), \
511 (data_type), \
512 RBIMPL_CAST((void **)&(sval)), \
513 sizeof(type))
514#endif
515
516static inline bool
517RTYPEDDATA_EMBEDDED_P(VALUE obj)
518{
519#if RUBY_DEBUG
520 if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
521 Check_Type(obj, RUBY_T_DATA);
522 RBIMPL_UNREACHABLE_RETURN(false);
523 }
524#endif
525
526 return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
527}
528
529static inline void *
530RTYPEDDATA_GET_DATA(VALUE obj)
531{
532#if RUBY_DEBUG
533 if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
534 Check_Type(obj, RUBY_T_DATA);
535 RBIMPL_UNREACHABLE_RETURN(false);
536 }
537#endif
538
539 /* We reuse the data pointer in embedded TypedData. */
540 return RTYPEDDATA_EMBEDDED_P(obj) ?
541 RBIMPL_CAST((void *)&(RTYPEDDATA(obj)->data)) :
542 RTYPEDDATA(obj)->data;
543}
544
545 RBIMPL_ATTR_PURE()
546 RBIMPL_ATTR_ARTIFICIAL()
558static inline bool
559rbimpl_rtypeddata_p(VALUE obj)
560{
561 return FL_TEST_RAW(obj, RUBY_TYPED_FL_IS_TYPED_DATA);
562}
563
564 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
565 RBIMPL_ATTR_ARTIFICIAL()
574static inline bool
575RTYPEDDATA_P(VALUE obj)
576{
577#if RUBY_DEBUG
578 if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
579 Check_Type(obj, RUBY_T_DATA);
580 RBIMPL_UNREACHABLE_RETURN(false);
581 }
582#endif
583
584 return rbimpl_rtypeddata_p(obj);
585}
586
587 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
588 RBIMPL_ATTR_ARTIFICIAL()
589/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
597static inline const struct rb_data_type_struct *
598RTYPEDDATA_TYPE(VALUE obj)
599{
600#if RUBY_DEBUG
601 if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
602 rb_unexpected_type(obj, RUBY_T_DATA);
603 RBIMPL_UNREACHABLE_RETURN(NULL);
604 }
605#endif
606
607 return (const struct rb_data_type_struct *)(RTYPEDDATA(obj)->type & TYPED_DATA_PTR_MASK);
608}
609
610 RBIMPL_ATTR_ARTIFICIAL()
617static inline void *
618rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *expected_type)
619{
620 if (RB_LIKELY(RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj))) {
621 const rb_data_type_t *actual_type = RTYPEDDATA_TYPE(obj);
622 void *data = RTYPEDDATA_GET_DATA(obj);
623 if (RB_LIKELY(actual_type == expected_type)) {
624 return data;
625 }
626
627 while (actual_type) {
628 actual_type = actual_type->parent;
629 if (actual_type == expected_type) {
630 return data;
631 }
632 }
633 }
634
635 return rb_check_typeddata(obj, expected_type);
636}
637
638
649#define TypedData_Get_Struct(obj,type,data_type,sval) \
650 ((sval) = RBIMPL_CAST((type *)rbimpl_check_typeddata((obj), (data_type))))
651
666static inline VALUE
667rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
668{
669 TypedData_Make_Struct0(result, klass, void, size, type, *datap);
670 return result;
671}
672
673 RBIMPL_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
675static inline VALUE
676rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
677{
678 return rb_data_typed_object_wrap(klass, datap, type);
679}
680
681#endif /* RBIMPL_RTYPEDDATA_H */
artificial.h
Defines RBIMPL_ATTR_ARTIFICIAL.
RBIMPL_ATTR_ARTIFICIAL
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial)).
Definition artificial.h:43
RBIMPL_ATTR_DEPRECATED
#define RBIMPL_ATTR_DEPRECATED(msg)
Wraps (or simulates) [[deprecated]].
Definition deprecated.h:64
dllexport.h
Tweaking visibility of C variables/functions.
RBIMPL_SYMBOL_EXPORT_END
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition dllexport.h:74
RBIMPL_SYMBOL_EXPORT_BEGIN
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition dllexport.h:65
fl_type.h
Defines enum ruby_fl_type.
RUBY_FL_WB_PROTECTED
@ RUBY_FL_WB_PROTECTED
Definition fl_type.h:198
RUBY_FL_USER2
@ RUBY_FL_USER2
User-defined flag.
Definition fl_type.h:326
RUBY_FL_USERPRIV0
@ RUBY_FL_USERPRIV0
This flag meaning is type dependent, currently only used by T_DATA.
Definition fl_type.h:224
RUBY_FL_SHAREABLE
@ RUBY_FL_SHAREABLE
This flag has something to do with Ractor.
Definition fl_type.h:280
flag_enum.h
Defines RBIMPL_ATTR_FLAG_ENUM.
RBIMPL_ATTR_FLAG_ENUM
#define RBIMPL_ATTR_FLAG_ENUM()
Wraps (or simulates) __attribute__((flag_enum).
Definition flag_enum.h:30
T_DATA
#define T_DATA
Old name of RUBY_T_DATA.
Definition value_type.h:60
FL_TEST_RAW
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:131
rb_typeddata_inherited_p
int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
Checks for the domestic relationship between the two.
Definition error.c:1371
rb_typeddata_is_kind_of
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Checks if the given object is of given kind.
Definition error.c:1381
rb_check_typeddata
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Identical to rb_typeddata_is_kind_of(), except it raises exceptions instead of returning false.
Definition error.c:1398
rb_unexpected_type
void rb_unexpected_type(VALUE x, int t)
Fails with the given object's type incompatibility to the type.
Definition error.c:1361
error.h
Declares rb_raise().
static_assert.h
Defines RBIMPL_STATIC_ASSERT.
RBIMPL_STATIC_ASSERT
#define RBIMPL_STATIC_ASSERT
Wraps (or simulates) static_assert.
Definition static_assert.h:67
assume.h
Defines RBIMPL_ASSUME / RBIMPL_UNREACHABLE.
RBIMPL_UNREACHABLE_RETURN
#define RBIMPL_UNREACHABLE_RETURN(_)
Wraps (or simulates) __builtin_unreachable.
Definition assume.h:48
nonnull.h
Defines RBIMPL_ATTR_NONNULL.
RBIMPL_ATTR_NONNULL
#define RBIMPL_ATTR_NONNULL(list)
Wraps (or simulates) __attribute__((nonnull)).
Definition nonnull.h:30
inline
#define inline
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition defines.h:91
pure.h
Defines RBIMPL_ATTR_PURE.
RBIMPL_ATTR_PURE
#define RBIMPL_ATTR_PURE()
Wraps (or simulates) __attribute__((pure)).
Definition pure.h:33
RBIMPL_ATTR_PURE_UNLESS_DEBUG
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE if and only if.
Definition pure.h:38
rbasic.h
Defines struct RBasic.
rdata.h
Defines struct RData.
RUBY_DATA_FUNC
void(* RUBY_DATA_FUNC)(void *)
This is the type of callbacks registered to RData.
Definition rdata.h:104
RTYPEDDATA_P
static bool RTYPEDDATA_P(VALUE obj)
Checks whether the passed object is RTypedData or RData.
Definition rtypeddata.h:575
rb_data_typed_object_wrap
VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type)
This is the primitive way to wrap an existing C struct into RTypedData.
Definition gc.c:1105
TypedData_Make_Struct0
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval)
This is an implementation detail of TypedData_Make_Struct.
Definition rtypeddata.h:477
rb_data_type_t
struct rb_data_type_struct rb_data_type_t
This is the struct that holds necessary info for a struct.
Definition rtypeddata.h:205
RTYPEDDATA
#define RTYPEDDATA(obj)
Convenient casting macro.
Definition rtypeddata.h:95
rb_data_typed_object_make
static VALUE rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
While we don't stop you from using this function, it seems to be an implementation detail of TypedDat...
Definition rtypeddata.h:667
RTYPEDDATA_TYPE
static const struct rb_data_type_struct * RTYPEDDATA_TYPE(VALUE obj)
Queries for the type of given object.
Definition rtypeddata.h:598
stdbool.h
C99 shim for <stdbool.h>.
RBasic
Ruby object's base components.
Definition rbasic.h:69
RBasic::klass
const VALUE klass
Class of an object.
Definition rbasic.h:92
RData
Definition rdata.h:120
RTypedData
"Typed" user data.
Definition rtypeddata.h:358
RTypedData::data
void * data
Pointer to the actual C level struct that you want to wrap.
Definition rtypeddata.h:378
RTypedData::type
const VALUE type
This is a const rb_data_type_t *const value, with the low bits set:
Definition rtypeddata.h:375
RTypedData::fields_obj
VALUE fields_obj
Direct reference to the slots that holds instance variables, if any.
Definition rtypeddata.h:364
RTypedData::basic
struct RBasic basic
The part that all ruby objects have in common.
Definition rtypeddata.h:361
rb_data_type_struct
This is the struct that holds necessary info for a struct.
Definition rtypeddata.h:208
rb_data_type_struct::dsize
size_t(* dsize)(const void *)
This function is to query the size of the underlying memory regions.
Definition rtypeddata.h:248
rb_data_type_struct::function
struct rb_data_type_struct::@006053276242002167166045007236206132153037024024 function
Function pointers.
rb_data_type_struct::parent
const rb_data_type_t * parent
Parent of this class.
Definition rtypeddata.h:298
rb_data_type_struct::dfree
RUBY_DATA_FUNC dfree
This function is called when the object is no longer used.
Definition rtypeddata.h:238
rb_data_type_struct::reserved
void * reserved[1]
This field is reserved for future extension.
Definition rtypeddata.h:265
rb_data_type_struct::dcompact
RUBY_DATA_FUNC dcompact
This function is called when the object is relocated.
Definition rtypeddata.h:259
rb_data_type_struct::wrap_struct_name
const char * wrap_struct_name
Name of structs of this kind.
Definition rtypeddata.h:215
rb_data_type_struct::dmark
RUBY_DATA_FUNC dmark
This function is called when the object is experiencing GC marks.
Definition rtypeddata.h:229
rb_data_type_struct::data
void * data
Type-specific static data.
Definition rtypeddata.h:304
rb_data_type_struct::flags
VALUE flags
Type-specific behavioural characteristics.
Definition rtypeddata.h:317
VALUE
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
value_type.h
Defines enum ruby_value_type.
Check_Type
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
Definition value_type.h:433
RB_TYPE_P
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition value_type.h:376
RUBY_T_DATA
@ RUBY_T_DATA
Definition value_type.h:127