1#ifndef RBIMPL_RTYPEDDATA_H
2#define RBIMPL_RTYPEDDATA_H
23#include "ruby/internal/config.h"
35#include "ruby/internal/cast.h"
52#define HAVE_TYPE_RB_DATA_TYPE_T 1
61#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
70#define HAVE_RB_DATA_TYPE_T_PARENT 1
81#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
88#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
96#define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj))
106#define RTYPEDDATA_DATA(v) (RTYPEDDATA(rbimpl_check_external_typeddata(v))->data)
109#define Check_TypedStruct(v, t) \
110 rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))
113#define RTYPEDDATA_P RTYPEDDATA_P
114#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
115#define TYPED_DATA_EMBEDDED ((VALUE)1)
116#define TYPED_DATA_PTR_MASK (~(TYPED_DATA_EMBEDDED))
122#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
123#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
124#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
125#define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE
126#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
135rbimpl_typeddata_flags {
165 RUBY_TYPED_EMBEDDABLE = 2,
285 void (*handle_weak_references)(
void *);
407#if !defined(__cplusplus) || __cplusplus >= 201103L
511# define RBIMPL_TYPEDDATA_PRECONDITION(obj, unreachable) \
512 while (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) { \
513 rb_unexpected_object_type(obj, "Data"); \
517# define RBIMPL_TYPEDDATA_PRECONDITION(obj, unreachable) \
518 RBIMPL_ASSERT_NOTHING
531#define TypedData_Wrap_Struct(klass,data_type,sval)\
532 rb_data_typed_object_wrap((klass),(sval),(data_type))
547#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
548 VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
549 (sval) = RBIMPL_CAST((type *)rbimpl_typeddata_get_data(result)); \
550 RBIMPL_CAST((void)(sval))
565#ifdef HAVE_STMT_AND_DECL_IN_EXPR
566#define TypedData_Make_Struct(klass, type, data_type, sval) \
567 RB_GNUC_EXTENSION({ \
568 TypedData_Make_Struct0( \
578#define TypedData_Make_Struct(klass, type, data_type, sval) \
579 rb_data_typed_object_make( \
582 RBIMPL_CAST((void **)&(sval)), \
587rbimpl_typeddata_embedded_p(
VALUE obj)
589 return (
RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
592RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY()
594RTYPEDDATA_EMBEDDED_P(
VALUE obj)
598 return rbimpl_typeddata_embedded_p(obj);
602rbimpl_typeddata_get_data(
VALUE obj)
605 return rbimpl_typeddata_embedded_p(obj) ?
611RTYPEDDATA_GET_DATA(
VALUE obj)
615 return rbimpl_typeddata_get_data(obj);
632rbimpl_rtypeddata_p(
VALUE obj)
634 return FL_TEST_RAW(obj, RUBY_TYPED_FL_IS_TYPED_DATA);
653rbimpl_obj_typeddata_p(
VALUE obj)
673 return rbimpl_rtypeddata_p(obj);
703 if (RB_LIKELY(child == parent))
return true;
704 }
while ((child = child->parent) != NULL);
707#define rb_typeddata_inherited_p rbimpl_typeddata_inherited_p_inline
714 if (RB_UNLIKELY(!rbimpl_obj_typeddata_p(obj)))
return false;
717#define rb_typeddata_is_kind_of rbimpl_typeddata_is_kind_of_inline
730 if (RB_UNLIKELY(!rbimpl_obj_typeddata_p(obj))) {
735 if (RB_UNLIKELY(!rb_typeddata_inherited_p(actual_type, expected_type))){
739 return RTYPEDDATA_GET_DATA(obj);
769#define TypedData_Get_Struct(obj,type,data_type,sval) \
770 ((sval) = RBIMPL_CAST((type *)rbimpl_check_typeddata((obj), (data_type))))
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
#define RBIMPL_ASSERT_OR_ASSUME(...)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Tweaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Defines enum ruby_fl_type.
@ RUBY_FL_USER2
User-defined flag.
@ RUBY_FL_USERPRIV0
This flag meaning is type dependent, currently only used by T_DATA.
@ RUBY_FL_SHAREABLE
This flag has something to do with Ractor.
Defines RBIMPL_ATTR_FLAG_ENUM.
#define RBIMPL_ATTR_FLAG_ENUM()
Wraps (or simulates) __attribute__((flag_enum)
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
void rb_unexpected_object_type(VALUE obj, const char *expected)
Fails with the given object's type incompatibility to the type.
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.
void rb_unexpected_typeddata(const rb_data_type_t *actual, const rb_data_type_t *expected)
Fails with the given object's type incompatibility to the type.
Defines RBIMPL_ATTR_NONNULL.
#define RBIMPL_ATTR_NONNULL(list)
Wraps (or simulates) __attribute__((nonnull))
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.
#define RBIMPL_ATTR_NORETURN()
Wraps (or simulates) [[noreturn]]
Defines RBIMPL_ATTR_PURE.
#define RBIMPL_ATTR_PURE()
Wraps (or simulates) __attribute__((pure))
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE if and only if.
void(* RUBY_DATA_FUNC)(void *)
This is the type of callbacks registered to RData.
#define RBIMPL_ATTR_RETURNS_NONNULL()
Wraps (or simulates) __attribute__((returns_nonnull))
static bool RTYPEDDATA_P(VALUE obj)
Checks whether the passed object is RTypedData or RData.
#define RTYPEDDATA_DATA(v)
Convenient getter macro.
static VALUE rbimpl_check_external_typeddata(VALUE obj)
This is an implementation detail of RTYPEDDATA_DATA().
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.
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...
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval)
This is an implementation detail of TypedData_Make_Struct.
#define RUBY_TYPED_FREE_IMMEDIATELY
Macros to see if each corresponding flag is defined.
static const rb_data_type_t * RTYPEDDATA_TYPE(VALUE obj)
Queries for the type of given object.
#define RTYPEDDATA(obj)
Convenient casting macro.
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...
Ruby object's base components.
const VALUE klass
Class of an object.
void * data
Pointer to the actual C level struct that you want to wrap.
const VALUE type
This is a const rb_data_type_t *const value, with the low bits set:
VALUE fields_obj
Direct reference to the slots that holds instance variables, if any.
struct RBasic basic
The part that all ruby objects have in common.
This is the struct that holds necessary info for a struct.
size_t(* dsize)(const void *)
This function is to query the size of the underlying memory regions.
const rb_data_type_t * parent
Parent of this class.
RUBY_DATA_FUNC dfree
This function is called when the object is no longer used.
RUBY_DATA_FUNC dcompact
This function is called when the object is relocated.
struct rb_data_type_struct::@57 function
Function pointers.
void * reserved[7]
This field is reserved for future extension.
const char * wrap_struct_name
Name of structs of this kind.
RUBY_DATA_FUNC dmark
This function is called when the object is experiencing GC marks.
void * data
Type-specific static data.
VALUE flags
Type-specific behavioural characteristics.
uintptr_t VALUE
Type that represents a Ruby object.
Defines enum ruby_value_type.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.