Ruby 3.5.0dev (2025-08-15 revision 42c08e458d0df2588dba96190fd1122d4b1170ff)
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
34#include "ruby/internal/cast.h"
38#include "ruby/internal/error.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
118#define IS_TYPED_DATA ((VALUE)1)
119#define TYPED_DATA_EMBEDDED ((VALUE)2)
120#define TYPED_DATA_PTR_FLAGS ((VALUE)3)
121#define TYPED_DATA_PTR_MASK (~TYPED_DATA_PTR_FLAGS)
122
128enum
130rbimpl_typeddata_flags {
144 RUBY_TYPED_FREE_IMMEDIATELY = 1,
145
146 RUBY_TYPED_EMBEDDABLE = 2,
147
160 RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,
161
181 RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
182
186 RUBY_TYPED_UNUSED = RUBY_FL_UNUSED6,
187
193 RUBY_TYPED_DECL_MARKING = RUBY_FL_USER2
194};
195
202
205
211 const char *wrap_struct_name;
212
214 struct {
215
226
235
244 size_t (*dsize)(const void *);
245
256
261 void *reserved[1]; /* For future extension.
262 This array *must* be filled with ZERO. */
264
295
300 void *data; /* This area can be used for any purpose
301 by a programmer who define the type. */
302
313 VALUE flags; /* RUBY_FL_WB_PROTECTED */
314};
315
355
357 struct RBasic basic;
358
361
372 const VALUE type;
373
375 void *data;
376};
377
378#if !defined(__cplusplus) || __cplusplus >= 201103L
379RBIMPL_STATIC_ASSERT(data_in_rtypeddata, offsetof(struct RData, data) == offsetof(struct RTypedData, data));
380#endif
381
394VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type);
395
410
423int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
424
433int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
434
445void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
447
458#define TypedData_Wrap_Struct(klass,data_type,sval)\
459 rb_data_typed_object_wrap((klass),(sval),(data_type))
460
474#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
475 VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
476 (sval) = (type *)RTYPEDDATA_GET_DATA(result); \
477 RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
478
492#ifdef HAVE_STMT_AND_DECL_IN_EXPR
493#define TypedData_Make_Struct(klass, type, data_type, sval) \
494 RB_GNUC_EXTENSION({ \
495 TypedData_Make_Struct0( \
496 data_struct_obj, \
497 klass, \
498 type, \
499 sizeof(type), \
500 data_type, \
501 sval); \
502 data_struct_obj; \
503 })
504#else
505#define TypedData_Make_Struct(klass, type, data_type, sval) \
506 rb_data_typed_object_make( \
507 (klass), \
508 (data_type), \
509 RBIMPL_CAST((void **)&(sval)), \
510 sizeof(type))
511#endif
512
523#define TypedData_Get_Struct(obj,type,data_type,sval) \
524 ((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))
525
526static inline bool
527RTYPEDDATA_EMBEDDED_P(VALUE obj)
528{
529#if RUBY_DEBUG
530 if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
533 }
534#endif
535
536 return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
537}
538
539static inline void *
540RTYPEDDATA_GET_DATA(VALUE obj)
541{
542#if RUBY_DEBUG
543 if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
546 }
547#endif
548
549 /* We reuse the data pointer in embedded TypedData. We can't use offsetof
550 * since RTypedData a non-POD type in C++. */
551 const size_t embedded_typed_data_size = sizeof(struct RTypedData) - sizeof(void *);
552
553 return RTYPEDDATA_EMBEDDED_P(obj) ? (char *)obj + embedded_typed_data_size : RTYPEDDATA(obj)->data;
554}
555
569static inline bool
570rbimpl_rtypeddata_p(VALUE obj)
571{
572 return RTYPEDDATA(obj)->type & IS_TYPED_DATA;
573}
574
585static inline bool
587{
588#if RUBY_DEBUG
589 if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
592 }
593#endif
594
595 return rbimpl_rtypeddata_p(obj);
596}
597
600/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
608static inline const struct rb_data_type_struct *
610{
611#if RUBY_DEBUG
612 if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
615 }
616#endif
617
618 return (const struct rb_data_type_struct *)(RTYPEDDATA(obj)->type & TYPED_DATA_PTR_MASK);
619}
620
635static inline VALUE
636rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
637{
638 TypedData_Make_Struct0(result, klass, void, size, type, *datap);
639 return result;
640}
641
642RBIMPL_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
644static inline VALUE
645rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
646{
647 return rb_data_typed_object_wrap(klass, datap, type);
648}
649
650#endif /* RBIMPL_RTYPEDDATA_H */
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition artificial.h:43
#define RBIMPL_ATTR_DEPRECATED(msg)
Wraps (or simulates) [[deprecated]]
Definition deprecated.h:64
Tweaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition dllexport.h:74
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition dllexport.h:65
Defines enum ruby_fl_type.
@ RUBY_FL_WB_PROTECTED
Definition fl_type.h:198
@ RUBY_FL_UNUSED6
This flag is no longer in use.
Definition fl_type.h:224
@ RUBY_FL_USER2
User-defined flag.
Definition fl_type.h:326
@ RUBY_FL_SHAREABLE
This flag has something to do with Ractor.
Definition fl_type.h:280
Defines RBIMPL_ATTR_FLAG_ENUM.
#define RBIMPL_ATTR_FLAG_ENUM()
Wraps (or simulates) __attribute__((flag_enum)
Definition flag_enum.h:30
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:1370
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:1380
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:1397
void rb_unexpected_type(VALUE x, int t)
Fails with the given object's type incompatibility to the type.
Definition error.c:1360
Declares rb_raise().
Defines RBIMPL_STATIC_ASSERT.
#define RBIMPL_STATIC_ASSERT
Wraps (or simulates) static_assert
Defines RBIMPL_ASSUME / RBIMPL_UNREACHABLE.
#define RBIMPL_UNREACHABLE_RETURN(_)
Wraps (or simulates) __builtin_unreachable.
Definition assume.h:48
Defines RBIMPL_ATTR_NONNULL.
#define RBIMPL_ATTR_NONNULL(list)
Wraps (or simulates) __attribute__((nonnull))
Definition nonnull.h:30
#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
Defines RBIMPL_ATTR_PURE.
#define RBIMPL_ATTR_PURE()
Wraps (or simulates) __attribute__((pure))
Definition pure.h:33
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE if and only if.
Definition pure.h:38
Defines struct RBasic.
Defines struct RData.
void(* RUBY_DATA_FUNC)(void *)
This is the type of callbacks registered to RData.
Definition rdata.h:104
static bool RTYPEDDATA_P(VALUE obj)
Checks whether the passed object is RTypedData or RData.
Definition rtypeddata.h:586
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:1071
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type)
Identical to rb_data_typed_object_wrap(), except it allocates a new data region internally instead of...
Definition gc.c:1081
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval)
This is an implementation detail of TypedData_Make_Struct.
Definition rtypeddata.h:474
#define RTYPEDDATA(obj)
Convenient casting macro.
Definition rtypeddata.h:95
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:636
static const struct rb_data_type_struct * RTYPEDDATA_TYPE(VALUE obj)
Queries for the type of given object.
Definition rtypeddata.h:609
C99 shim for <stdbool.h>
Ruby object's base components.
Definition rbasic.h:69
const VALUE klass
Class of an object.
Definition rbasic.h:92
Definition rdata.h:120
"Typed" user data.
Definition rtypeddata.h:354
void * data
Pointer to the actual C level struct that you want to wrap.
Definition rtypeddata.h:375
const VALUE type
This is a const rb_data_type_t *const value, with the low bits set:
Definition rtypeddata.h:372
VALUE fields_obj
Direct reference to the slots that holds instance variables, if any.
Definition rtypeddata.h:360
struct RBasic basic
The part that all ruby objects have in common.
Definition rtypeddata.h:357
This is the struct that holds necessary info for a struct.
Definition rtypeddata.h:204
size_t(* dsize)(const void *)
This function is to query the size of the underlying memory regions.
Definition rtypeddata.h:244
const rb_data_type_t * parent
Parent of this class.
Definition rtypeddata.h:294
RUBY_DATA_FUNC dfree
This function is called when the object is no longer used.
Definition rtypeddata.h:234
void * reserved[1]
This field is reserved for future extension.
Definition rtypeddata.h:261
RUBY_DATA_FUNC dcompact
This function is called when the object is relocated.
Definition rtypeddata.h:255
struct rb_data_type_struct::@54 function
Function pointers.
const char * wrap_struct_name
Name of structs of this kind.
Definition rtypeddata.h:211
RUBY_DATA_FUNC dmark
This function is called when the object is experiencing GC marks.
Definition rtypeddata.h:225
void * data
Type-specific static data.
Definition rtypeddata.h:300
VALUE flags
Type-specific behavioural characteristics.
Definition rtypeddata.h:313
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
Defines enum ruby_value_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
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
Definition value_type.h:127