summaryrefslogtreecommitdiff
path: root/include/ruby/3/core
diff options
context:
space:
mode:
Diffstat (limited to 'include/ruby/3/core')
-rw-r--r--include/ruby/3/core/rarray.h275
-rw-r--r--include/ruby/3/core/rbasic.h85
-rw-r--r--include/ruby/3/core/rbignum.h51
-rw-r--r--include/ruby/3/core/rclass.h47
-rw-r--r--include/ruby/3/core/rdata.h174
-rw-r--r--include/ruby/3/core/rfile.h36
-rw-r--r--include/ruby/3/core/rhash.h62
-rw-r--r--include/ruby/3/core/rmatch.h73
-rw-r--r--include/ruby/3/core/robject.h97
-rw-r--r--include/ruby/3/core/rregexp.h84
-rw-r--r--include/ruby/3/core/rstring.h207
-rw-r--r--include/ruby/3/core/rstruct.h73
-rw-r--r--include/ruby/3/core/rtypeddata.h184
13 files changed, 1448 insertions, 0 deletions
diff --git a/include/ruby/3/core/rarray.h b/include/ruby/3/core/rarray.h
new file mode 100644
index 0000000000..ddc50117ef
--- /dev/null
+++ b/include/ruby/3/core/rarray.h
@@ -0,0 +1,275 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RArray.
+ */
+#ifndef RUBY3_RARRAY_H
+#define RUBY3_RARRAY_H
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/attr/maybe_unused.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/fl_type.h"
+#include "ruby/3/rgengc.h"
+#include "ruby/3/stdbool.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+#include "ruby/assert.h"
+
+#ifndef USE_TRANSIENT_HEAP
+# define USE_TRANSIENT_HEAP 1
+#endif
+
+#define RARRAY(obj) RUBY3_CAST((struct RArray *)(obj))
+#define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
+#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
+#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
+#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
+#if USE_TRANSIENT_HEAP
+# define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
+#else
+# define RARRAY_TRANSIENT_FLAG 0
+#endif
+#define RARRAY_LEN rb_array_len
+#define RARRAY_CONST_PTR rb_array_const_ptr
+#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient
+
+/** @cond INTERNAL_MACRO */
+#if defined(__fcc__) || defined(__fcc_version) || \
+ defined(__FCC__) || defined(__FCC_VERSION)
+/* workaround for old version of Fujitsu C Compiler (fcc) */
+# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
+#else
+# define FIX_CONST_VALUE_PTR(x) (x)
+#endif
+
+#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
+#define RARRAY_LENINT RARRAY_LENINT
+#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
+#define RARRAY_ASET RARRAY_ASET
+#define RARRAY_PTR RARRAY_PTR
+/** @endcond */
+
+enum ruby_rarray_flags {
+ RARRAY_EMBED_FLAG = RUBY_FL_USER1,
+ /* RUBY_FL_USER2 is for ELTS_SHARED */
+ RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
+#if USE_TRANSIENT_HEAP
+ ,
+ RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
+#endif
+};
+
+enum {
+ RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3,
+ RARRAY_EMBED_LEN_MAX = RUBY3_EMBED_LEN_MAX_OF(VALUE)
+};
+
+struct RArray {
+ struct RBasic basic;
+ union {
+ struct {
+ long len;
+ union {
+ long capa;
+#if defined(__clang__) /* <- clang++ is sane */ || \
+ !defined(__cplusplus) /* <- C99 is sane */ || \
+ (__cplusplus > 199711L) /* <- C++11 is sane */
+ const
+#endif
+ VALUE shared_root;
+ } aux;
+ const VALUE *ptr;
+ } heap;
+ const VALUE ary[RARRAY_EMBED_LEN_MAX];
+ } as;
+};
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE *rb_ary_ptr_use_start(VALUE ary);
+void rb_ary_ptr_use_end(VALUE a);
+#if USE_TRANSIENT_HEAP
+void rb_ary_detransient(VALUE a);
+#endif
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline long
+RARRAY_EMBED_LEN(VALUE ary)
+{
+ RUBY3_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+ RUBY3_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
+
+ VALUE f = RBASIC(ary)->flags;
+ f &= RARRAY_EMBED_LEN_MASK;
+ f >>= RARRAY_EMBED_LEN_SHIFT;
+ return f;
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+static inline long
+rb_array_len(VALUE a)
+{
+ RUBY3_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+ if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
+ return RARRAY_EMBED_LEN(a);
+ }
+ else {
+ return RARRAY(a)->as.heap.len;
+ }
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline int
+RARRAY_LENINT(VALUE ary)
+{
+ return rb_long2int(RARRAY_LEN(ary));
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline bool
+RARRAY_TRANSIENT_P(VALUE ary)
+{
+ RUBY3_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+/* internal function. do not use this function */
+static inline const VALUE *
+rb_array_const_ptr_transient(VALUE a)
+{
+ RUBY3_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+ if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
+ return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
+ }
+ else {
+ return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
+ }
+}
+
+#if ! USE_TRANSIENT_HEAP
+RUBY3_ATTR_PURE_ON_NDEBUG()
+#endif
+/* internal function. do not use this function */
+static inline const VALUE *
+rb_array_const_ptr(VALUE a)
+{
+ RUBY3_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+#endif
+ return rb_array_const_ptr_transient(a);
+}
+
+/* internal function. do not use this function */
+static inline VALUE *
+rb_array_ptr_use_start(VALUE a,
+ RUBY3_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RUBY3_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (!allow_transient) {
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+ }
+#endif
+
+ return rb_ary_ptr_use_start(a);
+}
+
+/* internal function. do not use this function */
+static inline void
+rb_array_ptr_use_end(VALUE a,
+ RUBY3_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RUBY3_ASSERT_TYPE(a, RUBY_T_ARRAY);
+ rb_ary_ptr_use_end(a);
+}
+
+#define RUBY3_RARRAY_STMT(flag, ary, var, expr) do { \
+ RUBY3_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
+ const VALUE ruby3_ary = (ary); \
+ VALUE *var = rb_array_ptr_use_start(ruby3_ary, (flag)); \
+ expr; \
+ rb_array_ptr_use_end(ruby3_ary, (flag)); \
+} while (0)
+
+#define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
+#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
+#define RARRAY_PTR_USE(ary, ptr_name, expr) \
+ RUBY3_RARRAY_STMT(0, ary, ptr_name, expr)
+
+#define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
+#define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
+#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
+ RUBY3_RARRAY_STMT(1, ary, ptr_name, expr)
+
+static inline VALUE *
+RARRAY_PTR(VALUE ary)
+{
+ RUBY3_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+ VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
+ return RUBY3_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
+}
+
+static inline void
+RARRAY_ASET(VALUE ary, long i, VALUE v)
+{
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
+ RB_OBJ_WRITE(ary, &ptr[i], v));
+}
+
+/* RARRAY_AREF is used as a lvalue. Cannot be a function. */
+#if 0
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RARRAY_AREF(VALUE ary, long i)
+{
+ RUBY3_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+ return RARRAY_CONST_PTR_TRANSIENT(ary)[i];
+}
+#else
+# undef RARRAY_AREF
+# define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
+#endif
+
+#endif /* RUBY3_RARRAY_H */
diff --git a/include/ruby/3/core/rbasic.h b/include/ruby/3/core/rbasic.h
new file mode 100644
index 0000000000..510dd38da6
--- /dev/null
+++ b/include/ruby/3/core/rbasic.h
@@ -0,0 +1,85 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RBasic.
+ */
+#ifndef RUBY3_RBASIC_H
+#define RUBY3_RBASIC_H
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/attr/forceinline.h"
+#include "ruby/3/attr/noalias.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/special_consts.h"
+#include "ruby/3/value.h"
+#include "ruby/assert.h"
+
+#define RBASIC(obj) RUBY3_CAST((struct RBasic *)(obj))
+#define RBASIC_CLASS RBASIC_CLASS
+#define RVALUE_EMBED_LEN_MAX RVALUE_EMBED_LEN_MAX
+
+/** @cond INTERNAL_MACRO */
+#define RUBY3_EMBED_LEN_MAX_OF(T) \
+ RUBY3_CAST((int)(sizeof(VALUE[RVALUE_EMBED_LEN_MAX]) / sizeof(T)))
+/** @endcond */
+
+enum ruby_rvalue_flags { RVALUE_EMBED_LEN_MAX = 3 };
+
+struct
+RUBY_ALIGNAS(SIZEOF_VALUE)
+RBasic {
+ VALUE flags; /**< @see enum ::ruby_fl_type. */
+ const VALUE klass;
+
+#ifdef __cplusplus
+ public:
+ RUBY3_ATTR_CONSTEXPR(CXX11)
+ RUBY3_ATTR_ARTIFICIAL()
+ RUBY3_ATTR_FORCEINLINE()
+ RUBY3_ATTR_NOALIAS()
+ /**
+ * We need to define this explicit constructor because the field `klass` is
+ * const-qualified above, which effectively defines the implicit default
+ * constructor as "deleted" (as of C++11) -- No way but to define one by
+ * ourselves.
+ */
+ RBasic() :
+ flags(RUBY3_VALUE_NULL),
+ klass(RUBY3_VALUE_NULL)
+ {
+ }
+#endif
+};
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_obj_hide(VALUE obj);
+VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RBASIC_CLASS(VALUE obj)
+{
+ RUBY3_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+ return RBASIC(obj)->klass;
+}
+
+#endif /* RUBY3_RBASIC_H */
diff --git a/include/ruby/3/core/rbignum.h b/include/ruby/3/core/rbignum.h
new file mode 100644
index 0000000000..c1183e3ea6
--- /dev/null
+++ b/include/ruby/3/core/rbignum.h
@@ -0,0 +1,51 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RBignum.
+ */
+#ifndef RUBY3_RBIGNUM_H
+#define RUBY3_RBIGNUM_H
+#include "ruby/3/dllexport.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+#include "ruby/3/stdbool.h"
+
+#define RBIGNUM_SIGN rb_big_sign
+
+/** @cond INTERNAL_MACRO */
+#define RBIGNUM_POSITIVE_P RBIGNUM_POSITIVE_P
+#define RBIGNUM_NEGATIVE_P RBIGNUM_NEGATIVE_P
+/** @endcond */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+int rb_big_sign(VALUE num);
+RUBY3_SYMBOL_EXPORT_END()
+
+static inline bool
+RBIGNUM_POSITIVE_P(VALUE b) {
+ RUBY3_ASSERT_TYPE(b, RUBY_T_BIGNUM);
+ return RBIGNUM_SIGN(b);
+}
+
+static inline bool
+RBIGNUM_NEGATIVE_P(VALUE b) {
+ RUBY3_ASSERT_TYPE(b, RUBY_T_BIGNUM);
+ return ! RBIGNUM_POSITIVE_P(b);
+}
+
+#endif /* RUBY3_RBIGNUM_H */
diff --git a/include/ruby/3/core/rclass.h b/include/ruby/3/core/rclass.h
new file mode 100644
index 0000000000..a54b34f5ba
--- /dev/null
+++ b/include/ruby/3/core/rclass.h
@@ -0,0 +1,47 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RClass.
+ */
+#ifndef RUBY3_RCLASS_H
+#define RUBY3_RCLASS_H
+#include "ruby/3/dllexport.h"
+#include "ruby/3/value.h"
+#include "ruby/3/cast.h"
+
+#define RMODULE_IS_OVERLAID RMODULE_IS_OVERLAID
+#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
+#define RMODULE_INCLUDED_INTO_REFINEMENT RMODULE_INCLUDED_INTO_REFINEMENT
+
+#define RCLASS(obj) RUBY3_CAST((struct RClass *)(obj))
+#define RMODULE RCLASS
+#define RCLASS_SUPER rb_class_get_superclass
+
+enum ruby_rmodule_flags {
+ RMODULE_IS_OVERLAID = RUBY_FL_USER2,
+ RMODULE_IS_REFINEMENT = RUBY_FL_USER3,
+ RMODULE_INCLUDED_INTO_REFINEMENT = RUBY_FL_USER4
+};
+
+struct RClass; /* Opaque, declared here for RCLASS() macro. */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_class_get_superclass(VALUE);
+RUBY3_SYMBOL_EXPORT_END()
+
+#endif /* RUBY3_RCLASS_H */
diff --git a/include/ruby/3/core/rdata.h b/include/ruby/3/core/rdata.h
new file mode 100644
index 0000000000..d39a01b52f
--- /dev/null
+++ b/include/ruby/3/core/rdata.h
@@ -0,0 +1,174 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RData.
+ */
+#ifndef RUBY3_RDATA_H
+#define RUBY3_RDATA_H
+#include "ruby/3/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/3/attr/deprecated.h"
+#include "ruby/3/attr/warning.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/fl_type.h"
+#include "ruby/3/token_paste.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+#include "ruby/defines.h"
+
+#ifdef RUBY_UNTYPED_DATA_WARNING
+# /* Take that. */
+#elif defined(RUBY_EXPORT)
+# define RUBY_UNTYPED_DATA_WARNING 1
+#else
+# define RUBY_UNTYPED_DATA_WARNING 0
+#endif
+
+/** @cond INTERNAL_MACRO */
+#define RUBY3_DATA_FUNC(f) RUBY3_CAST((void (*)(void *))(f))
+#define RUBY3_ATTRSET_UNTYPED_DATA_FUNC() \
+ RUBY3_ATTR_WARNING(("untyped Data is unsafe; use TypedData instead")) \
+ RUBY3_ATTR_DEPRECATED(("by TypedData"))
+/** @endcond */
+
+#define RDATA(obj) RUBY3_CAST((struct RData *)(obj))
+#define DATA_PTR(obj) RDATA(obj)->data
+#define RUBY_MACRO_SELECT RUBY3_TOKEN_PASTE
+#define RUBY_DEFAULT_FREE RUBY3_DATA_FUNC(-1)
+#define RUBY_NEVER_FREE RUBY3_DATA_FUNC(0)
+#define RUBY_UNTYPED_DATA_FUNC(f) f RUBY3_ATTRSET_UNTYPED_DATA_FUNC()
+
+/*
+#define RUBY_DATA_FUNC(func) ((void (*)(void*))(func))
+*/
+typedef void (*RUBY_DATA_FUNC)(void*);
+
+struct RData {
+ struct RBasic basic;
+ RUBY_DATA_FUNC dmark;
+ RUBY_DATA_FUNC dfree;
+ void *data;
+};
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
+VALUE rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
+RUBY3_SYMBOL_EXPORT_END()
+
+#define Data_Wrap_Struct(klass, mark, free, sval) \
+ rb_data_object_wrap( \
+ (klass), \
+ (sval), \
+ RUBY3_DATA_FUNC(mark), \
+ RUBY3_DATA_FUNC(free))
+
+#define Data_Make_Struct0(result, klass, type, size, mark, free, sval) \
+ VALUE result = rb_data_object_zalloc( \
+ (klass), \
+ (size), \
+ RUBY3_DATA_FUNC(mark), \
+ RUBY3_DATA_FUNC(free)); \
+ (sval) = RUBY3_CAST((type *)DATA_PTR(result)); \
+ RUBY3_CAST(/*suppress unused variable warnings*/(void)(sval))
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+#define Data_Make_Struct(klass, type, mark, free, sval) \
+ RB_GNUC_EXTENSION({ \
+ Data_Make_Struct0( \
+ data_struct_obj, \
+ klass, \
+ type, \
+ sizeof(type), \
+ mark, \
+ free, \
+ sval); \
+ data_struct_obj; \
+ })
+#else
+#define Data_Make_Struct(klass, type, mark, free, sval) \
+ rb_data_object_make( \
+ (klass), \
+ RUBY3_DATA_FUNC(mark), \
+ RUBY3_DATA_FUNC(free), \
+ RUBY3_CAST((void **)&(sval)), \
+ sizeof(type))
+#endif
+
+#define Data_Get_Struct(obj, type, sval) \
+ ((sval) = RUBY3_CAST((type*)rb_data_object_get(obj)))
+
+RUBY3_ATTRSET_UNTYPED_DATA_FUNC()
+static inline VALUE
+rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
+{
+ return rb_data_object_wrap(klass, ptr, mark, free);
+}
+
+static inline void *
+rb_data_object_get(VALUE obj)
+{
+ Check_Type(obj, RUBY_T_DATA);
+ return DATA_PTR(obj);
+}
+
+RUBY3_ATTRSET_UNTYPED_DATA_FUNC()
+static inline void *
+rb_data_object_get_warning(VALUE obj)
+{
+ return rb_data_object_get(obj);
+}
+
+#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# define rb_data_object_wrap_warning(klass, ptr, mark, free) \
+ RB_GNUC_EXTENSION( \
+ __builtin_choose_expr( \
+ __builtin_constant_p(klass) && !(klass), \
+ rb_data_object_wrap(klass, ptr, mark, free), \
+ (rb_data_object_wrap_warning)(klass, ptr, mark, free)))
+#endif
+
+static inline VALUE
+rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
+{
+ Data_Make_Struct0(result, klass, void, size, mark_func, free_func, *datap);
+ return result;
+}
+
+RUBY3_ATTR_DEPRECATED(("by: rb_data_object_wrap"))
+static inline VALUE
+rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
+{
+ return rb_data_object_wrap(klass, data, dmark, dfree);
+}
+
+#define rb_data_object_wrap_0 rb_data_object_wrap
+#define rb_data_object_wrap_1 rb_data_object_wrap_warning
+#define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_, RUBY_UNTYPED_DATA_WARNING)
+#define rb_data_object_get_0 rb_data_object_get
+#define rb_data_object_get_1 rb_data_object_get_warning
+#define rb_data_object_get RUBY_MACRO_SELECT(rb_data_object_get_, RUBY_UNTYPED_DATA_WARNING)
+#define rb_data_object_make_0 rb_data_object_make
+#define rb_data_object_make_1 rb_data_object_make_warning
+#define rb_data_object_make RUBY_MACRO_SELECT(rb_data_object_make_, RUBY_UNTYPED_DATA_WARNING)
+#endif /* RUBY3_RDATA_H */
diff --git a/include/ruby/3/core/rfile.h b/include/ruby/3/core/rfile.h
new file mode 100644
index 0000000000..2b80a96e40
--- /dev/null
+++ b/include/ruby/3/core/rfile.h
@@ -0,0 +1,36 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RFile.
+ */
+#ifndef RUBY3_RFILE_H
+#define RUBY3_RFILE_H
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/cast.h"
+
+/* rb_io_t is in ruby/io.h. The header file has historically not been included
+ * into ruby/ruby.h. We follow that tradition. */
+struct rb_io_t;
+
+struct RFile {
+ struct RBasic basic;
+ struct rb_io_t *fptr;
+};
+
+#define RFILE(obj) RUBY3_CAST((struct RFile *)(obj))
+#endif /* RUBY3_RFILE_H */
diff --git a/include/ruby/3/core/rhash.h b/include/ruby/3/core/rhash.h
new file mode 100644
index 0000000000..3778130141
--- /dev/null
+++ b/include/ruby/3/core/rhash.h
@@ -0,0 +1,62 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RHash.
+ *
+ * Shyouhei really suffered agnish over placement of macros in this file. They
+ * are half-brken. The situation (as of wriring) is:
+ *
+ * - #RHASH_TBL: works.
+ * - #RHASH_ITER_LEV: compile-time error.
+ * - #RHASH_IFNONE: compile-time error.
+ * - #RHASH_SIZE: works.
+ * - #RHASH_EMPTY_P: works.
+ * - #RHASH_SET_IFNONE: works (why... given you cannot query).
+ *
+ * Shyouhei stopped thinking. Let them be as is.
+ */
+#ifndef RUBY3_RHASH_H
+#define RUBY3_RHASH_H
+#include "ruby/3/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/3/dllexport.h"
+#include "ruby/3/value.h"
+#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
+# include "ruby/backward.h"
+#endif
+
+#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)
+#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
+#define RHASH_IFNONE(h) rb_hash_ifnone(h)
+#define RHASH_SIZE(h) rb_hash_size_num(h)
+#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
+#define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
+
+struct st_table; /* in ruby/st.h */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+size_t rb_hash_size_num(VALUE hash);
+struct st_table *rb_hash_tbl(VALUE, const char *file, int line);
+VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
+RUBY3_SYMBOL_EXPORT_END()
+
+#endif /* RUBY3_RHASH_H */
diff --git a/include/ruby/3/core/rmatch.h b/include/ruby/3/core/rmatch.h
new file mode 100644
index 0000000000..fff62f1473
--- /dev/null
+++ b/include/ruby/3/core/rmatch.h
@@ -0,0 +1,73 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RMatch.
+ */
+#ifndef RUBY3_RMATCH_H
+#define RUBY3_RMATCH_H
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/attr/returns_nonnull.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+#include "ruby/assert.h"
+
+#define RMATCH(obj) RUBY3_CAST((struct RMatch *)(obj))
+/** @cond INTERNAL_MACRO */
+#define RMATCH_REGS RMATCH_REGS
+/** @endcond */
+
+struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
+struct re_registers; /* Also in onigmo.h */
+
+/* @shyouhei wonders: is anyone actively using this typedef ...? */
+typedef struct re_pattern_buffer Regexp;
+
+struct rmatch_offset {
+ long beg;
+ long end;
+};
+
+struct rmatch {
+ struct re_registers regs;
+
+ struct rmatch_offset *char_offset;
+ int char_offset_num_allocated;
+};
+
+struct RMatch {
+ struct RBasic basic;
+ VALUE str;
+ struct rmatch *rmatch;
+ VALUE regexp; /* RRegexp */
+};
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_RETURNS_NONNULL()
+RUBY3_ATTR_ARTIFICIAL()
+static inline struct re_registers *
+RMATCH_REGS(VALUE match)
+{
+ RUBY3_ASSERT_TYPE(match, RUBY_T_MATCH);
+ RUBY3_ASSERT_OR_ASSUME(RMATCH(match)->rmatch != NULL);
+ return &RMATCH(match)->rmatch->regs;
+}
+
+#endif /* RUBY3_RMATCH_H */
diff --git a/include/ruby/3/core/robject.h b/include/ruby/3/core/robject.h
new file mode 100644
index 0000000000..82887a8c51
--- /dev/null
+++ b/include/ruby/3/core/robject.h
@@ -0,0 +1,97 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RObject.
+ */
+#ifndef RUBY3_ROBJECT_H
+#define RUBY3_ROBJECT_H
+#include "ruby/3/config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/fl_type.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+
+#define ROBJECT(obj) RUBY3_CAST((struct RObject *)(obj))
+#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
+#define ROBJECT_EMBED ROBJECT_EMBED
+/** @cond INTERNAL_MACRO */
+#define ROBJECT_NUMIV ROBJECT_NUMIV
+#define ROBJECT_IVPTR ROBJECT_IVPTR
+/** @endcond */
+
+enum ruby_robject_flags { ROBJECT_EMBED = RUBY_FL_USER1 };
+
+enum { ROBJECT_EMBED_LEN_MAX = RUBY3_EMBED_LEN_MAX_OF(VALUE) };
+
+struct RObject {
+ struct RBasic basic;
+ union {
+ struct {
+ uint32_t numiv;
+ VALUE *ivptr;
+ void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
+ } heap;
+ VALUE ary[ROBJECT_EMBED_LEN_MAX];
+ } as;
+};
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline uint32_t
+ROBJECT_NUMIV(VALUE obj)
+{
+ RUBY3_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+
+ if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
+ return ROBJECT_EMBED_LEN_MAX;
+ }
+ else {
+ return ROBJECT(obj)->as.heap.numiv;
+ }
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE *
+ROBJECT_IVPTR(VALUE obj)
+{
+ RUBY3_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+
+ struct RObject *const ptr = ROBJECT(obj);
+
+ if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
+ return ptr->as.ary;
+ }
+ else {
+ return ptr->as.heap.ivptr;
+ }
+}
+
+#define ROBJECT_IV_INDEX_TBL(o) \
+ ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
+ RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
+ ROBJECT(o)->as.heap.iv_index_tbl)
+
+#endif /* RUBY3_ROBJECT_H */
diff --git a/include/ruby/3/core/rregexp.h b/include/ruby/3/core/rregexp.h
new file mode 100644
index 0000000000..1f30808e8a
--- /dev/null
+++ b/include/ruby/3/core/rregexp.h
@@ -0,0 +1,84 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RRegexp.
+ */
+#ifndef RUBY3_RREGEXP_H
+#define RUBY3_RREGEXP_H
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/core/rstring.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+
+#define RREGEXP(obj) RUBY3_CAST((struct RRegexp *)(obj))
+#define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr)
+/** @cond INTERNAL_MACRO */
+#define RREGEXP_SRC RREGEXP_SRC
+#define RREGEXP_SRC_PTR RREGEXP_SRC_PTR
+#define RREGEXP_SRC_LEN RREGEXP_SRC_LEN
+#define RREGEXP_SRC_END RREGEXP_SRC_END
+/** @endcond */
+
+struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
+
+struct RRegexp {
+ struct RBasic basic;
+ struct re_pattern_buffer *ptr;
+ const VALUE src;
+ unsigned long usecnt;
+};
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RREGEXP_SRC(VALUE rexp)
+{
+ RUBY3_ASSERT_TYPE(rexp, RUBY_T_REGEXP);
+ VALUE ret = RREGEXP(rexp)->src;
+ RUBY3_ASSERT_TYPE(ret, RUBY_T_STRING);
+ return ret;
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline char *
+RREGEXP_SRC_PTR(VALUE rexp)
+{
+ return RSTRING_PTR(RREGEXP_SRC(rexp));
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline long
+RREGEXP_SRC_LEN(VALUE rexp)
+{
+ return RSTRING_LEN(RREGEXP_SRC(rexp));
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline char *
+RREGEXP_SRC_END(VALUE rexp)
+{
+ return RSTRING_END(RREGEXP_SRC(rexp));
+}
+
+#endif /* RUBY3_RREGEXP_H */
diff --git a/include/ruby/3/core/rstring.h b/include/ruby/3/core/rstring.h
new file mode 100644
index 0000000000..266edca9b6
--- /dev/null
+++ b/include/ruby/3/core/rstring.h
@@ -0,0 +1,207 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RString.
+ */
+#ifndef RUBY3_RSTRING_H
+#define RUBY3_RSTRING_H
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/fl_type.h"
+#include "ruby/3/value_type.h"
+#include "ruby/assert.h"
+
+#define RSTRING(obj) RUBY3_CAST((struct RString *)(obj))
+#define RSTRING_NOEMBED RSTRING_NOEMBED
+#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
+#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
+#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
+#define RSTRING_FSTR RSTRING_FSTR
+
+/** @cond INTERNAL_MACRO */
+#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
+#define RSTRING_LEN RSTRING_LEN
+#define RSTRING_LENINT RSTRING_LENINT
+#define RSTRING_PTR RSTRING_PTR
+#define RSTRING_END RSTRING_END
+/** @endcond */
+
+#define StringValue(v) rb_string_value(&(v))
+#define StringValuePtr(v) rb_string_value_ptr(&(v))
+#define StringValueCStr(v) rb_string_value_cstr(&(v))
+#define SafeStringValue(v) StringValue(v)
+#define ExportStringValue(v) do { \
+ StringValue(v); \
+ (v) = rb_str_export(v); \
+} while (0)
+
+enum ruby_rstring_flags {
+ RSTRING_NOEMBED = RUBY_FL_USER1,
+ RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
+ RUBY_FL_USER5 | RUBY_FL_USER6,
+ /* Actually, string encodings are also encoded into the flags, using
+ * remaining bits.*/
+ RSTRING_FSTR = RUBY_FL_USER17
+};
+
+enum {
+ RSTRING_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 2,
+ RSTRING_EMBED_LEN_MAX = RUBY3_EMBED_LEN_MAX_OF(char) - 1
+};
+
+struct RString {
+ struct RBasic basic;
+ union {
+ struct {
+ long len;
+ char *ptr;
+ union {
+ long capa;
+ VALUE shared;
+ } aux;
+ } heap;
+ char ary[RSTRING_EMBED_LEN_MAX + 1];
+ } as;
+};
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_str_to_str(VALUE);
+VALUE rb_string_value(volatile VALUE*);
+char *rb_string_value_ptr(volatile VALUE*);
+char *rb_string_value_cstr(volatile VALUE*);
+VALUE rb_str_export(VALUE);
+VALUE rb_str_export_locale(VALUE);
+
+RUBY3_ATTR_ERROR(("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead"))
+void rb_check_safe_str(VALUE);
+#define Check_SafeStr(v) rb_check_safe_str(RUBY3_CAST((VALUE)(v)))
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline long
+RSTRING_EMBED_LEN(VALUE str)
+{
+ RUBY3_ASSERT_TYPE(str, RUBY_T_STRING);
+ RUBY3_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
+
+ VALUE f = RBASIC(str)->flags;
+ f &= RSTRING_EMBED_LEN_MASK;
+ f >>= RSTRING_EMBED_LEN_SHIFT;
+ return f;
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline struct RString
+ruby3_rstring_getmem(VALUE str)
+{
+ RUBY3_ASSERT_TYPE(str, RUBY_T_STRING);
+
+ if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
+ return *RSTRING(str);
+ }
+ else {
+ /* Expecting compilers to optimize this on-stack struct away. */
+ struct RString retval;
+ retval.as.heap.len = RSTRING_EMBED_LEN(str);
+ retval.as.heap.ptr = RSTRING(str)->as.ary;
+ return retval;
+ }
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline long
+RSTRING_LEN(VALUE str)
+{
+ return ruby3_rstring_getmem(str).as.heap.len;
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline char *
+RSTRING_PTR(VALUE str)
+{
+ char *ptr = ruby3_rstring_getmem(str).as.heap.ptr;
+
+ if (RB_UNLIKELY(! ptr)) {
+ /* :BEWARE: @shyouhei thinks that currently, there are rooms for this
+ * function to return NULL. In the 20th century that was a pointless
+ * concern. However struct RString can hold fake strings nowadays. It
+ * seems no check against NULL are exercised around handling of them
+ * (one of such usages is located in marshal.c, which scares
+ * @shyouhei). Better check here for maximum safety.
+ *
+ * Also, this is not rb_warn() because RSTRING_PTR() can be called
+ * during GC (see what obj_info() does). rb_warn() needs to allocate
+ * Ruby objects. That is not possible at this moment. */
+ fprintf(stderr, "%s\n",
+ "RSTRING_PTR is returning NULL!! "
+ "SIGSEGV is highly expected to follow immediately. "
+ "If you could reproduce, attach your debugger here, "
+ "and look at the passed string."
+ );
+ }
+
+ return ptr;
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline char *
+RSTRING_END(VALUE str)
+{
+ struct RString buf = ruby3_rstring_getmem(str);
+
+ if (RB_UNLIKELY(! buf.as.heap.ptr)) {
+ /* Ditto. */
+ fprintf(stderr, "%s\n",
+ "RSTRING_END is returning NULL!! "
+ "SIGSEGV is highly expected to follow immediately. "
+ "If you could reproduce, attach your debugger here, "
+ "and look at the passed string."
+ );
+ }
+
+ return &buf.as.heap.ptr[buf.as.heap.len];
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline int
+RSTRING_LENINT(VALUE str)
+{
+ return rb_long2int(RSTRING_LEN(str));
+}
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+# define RSTRING_GETMEM(str, ptrvar, lenvar) \
+ __extension__ ({ \
+ struct RString ruby3_str = ruby3_rstring_getmem(str); \
+ (ptrvar) = ruby3_str.as.heap.ptr; \
+ (lenvar) = ruby3_str.as.heap.len; \
+ })
+#else
+# define RSTRING_GETMEM(str, ptrvar, lenvar) \
+ ((ptrvar) = RSTRING_PTR(str), \
+ (lenvar) = RSTRING_LEN(str))
+#endif /* HAVE_STMT_AND_DECL_IN_EXPR */
+#endif /* RUBY3_RSTRING_H */
diff --git a/include/ruby/3/core/rstruct.h b/include/ruby/3/core/rstruct.h
new file mode 100644
index 0000000000..55db1b3fc0
--- /dev/null
+++ b/include/ruby/3/core/rstruct.h
@@ -0,0 +1,73 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RStruct.
+ */
+#ifndef RUBY3_RSTRUCT_H
+#define RUBY3_RSTRUCT_H
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/value.h"
+#include "ruby/3/value_type.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/arithmetic/int.h"
+#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
+# include "ruby/backward.h"
+#endif
+
+#define RSTRUCT_PTR(st) rb_struct_ptr(st)
+/** @cond INTERNAL_MACRO */
+#define RSTRUCT_LEN RSTRUCT_LEN
+#define RSTRUCT_SET RSTRUCT_SET
+#define RSTRUCT_GET RSTRUCT_GET
+/** @endcond */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_struct_size(VALUE s);
+VALUE rb_struct_aref(VALUE, VALUE);
+VALUE rb_struct_aset(VALUE, VALUE, VALUE);
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline long
+RSTRUCT_LEN(VALUE st)
+{
+ RUBY3_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return RB_NUM2LONG(rb_struct_size(st));
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RSTRUCT_SET(VALUE st, int k, VALUE v)
+{
+ RUBY3_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return rb_struct_aset(st, INT2NUM(k), (v));
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RSTRUCT_GET(VALUE st, int k)
+{
+ RUBY3_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return rb_struct_aref(st, INT2NUM(k));
+}
+
+#endif /* RUBY3_RSTRUCT_H */
diff --git a/include/ruby/3/core/rtypeddata.h b/include/ruby/3/core/rtypeddata.h
new file mode 100644
index 0000000000..cc00fa2500
--- /dev/null
+++ b/include/ruby/3/core/rtypeddata.h
@@ -0,0 +1,184 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RTypedData.
+ */
+#ifndef RUBY3_RTYPEDDATA_H
+#define RUBY3_RTYPEDDATA_H
+#include "ruby/3/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/3/assume.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rbasic.h"
+#include "ruby/3/core/rdata.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/error.h"
+#include "ruby/3/fl_type.h"
+#include "ruby/3/stdbool.h"
+#include "ruby/3/value_type.h"
+
+#define HAVE_TYPE_RB_DATA_TYPE_T 1
+#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
+#define HAVE_RB_DATA_TYPE_T_PARENT 1
+#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
+#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
+#define RTYPEDDATA(obj) RUBY3_CAST((struct RTypedData *)(obj))
+#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
+#define Check_TypedStruct(v, t) \
+ rb_check_typeddata(RUBY3_CAST((VALUE)(v)), (t))
+
+/** @cond INTERNAL_MACRO */
+#define RTYPEDDATA_P RTYPEDDATA_P
+#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
+#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
+#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
+#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
+/** @endcond */
+
+/* bits for rb_data_type_struct::flags */
+enum ruby3_typeddata_flags {
+ RUBY_TYPED_FREE_IMMEDIATELY = 1,
+ RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
+ RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
+};
+
+typedef struct rb_data_type_struct rb_data_type_t;
+
+struct rb_data_type_struct {
+ const char *wrap_struct_name;
+ struct {
+ RUBY_DATA_FUNC dmark;
+ RUBY_DATA_FUNC dfree;
+ size_t (*dsize)(const void *);
+ RUBY_DATA_FUNC dcompact;
+ void *reserved[1]; /* For future extension.
+ This array *must* be filled with ZERO. */
+ } function;
+ const rb_data_type_t *parent;
+ void *data; /* This area can be used for any purpose
+ by a programmer who define the type. */
+ VALUE flags; /* RUBY_FL_WB_PROTECTED */
+};
+
+struct RTypedData {
+ struct RBasic basic;
+ const rb_data_type_t *type;
+ VALUE typed_flag; /* 1 or not */
+ void *data;
+};
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *);
+VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
+int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
+int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
+void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
+RUBY3_SYMBOL_EXPORT_END()
+
+#define TypedData_Wrap_Struct(klass,data_type,sval)\
+ rb_data_typed_object_wrap((klass),(sval),(data_type))
+
+#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
+ VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
+ (sval) = RUBY3_CAST((type *)RTYPEDDATA_DATA(result)); \
+ RUBY3_CAST(/*suppress unused variable warnings*/(void)(sval))
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+#define TypedData_Make_Struct(klass, type, data_type, sval) \
+ RB_GNUC_EXTENSION({ \
+ TypedData_Make_Struct0( \
+ data_struct_obj, \
+ klass, \
+ type, \
+ sizeof(type), \
+ data_type, \
+ sval); \
+ data_struct_obj; \
+ })
+#else
+#define TypedData_Make_Struct(klass, type, data_type, sval) \
+ rb_data_typed_object_make( \
+ (klass), \
+ (data_type), \
+ RUBY3_CAST((void **)&(sval)), \
+ sizeof(type))
+#endif
+
+#define TypedData_Get_Struct(obj,type,data_type,sval) \
+ ((sval) = RUBY3_CAST((type *)rb_check_typeddata((obj), (data_type))))
+
+RUBY3_ATTR_PURE()
+RUBY3_ATTR_ARTIFICIAL()
+static inline bool
+ruby3_rtypeddata_p(VALUE obj)
+{
+ return RTYPEDDATA(obj)->typed_flag == 1;
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+static inline bool
+RTYPEDDATA_P(VALUE obj)
+{
+#if ! RUBY_NDEBUG
+ if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
+ Check_Type(obj, RUBY_T_DATA);
+ RUBY3_UNREACHABLE_RETURN(false);
+ }
+#endif
+
+ return ruby3_rtypeddata_p(obj);
+}
+
+RUBY3_ATTR_PURE_ON_NDEBUG()
+RUBY3_ATTR_ARTIFICIAL()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline const struct rb_data_type_struct *
+RTYPEDDATA_TYPE(VALUE obj)
+{
+#if ! RUBY_NDEBUG
+ if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
+ rb_unexpected_type(obj, RUBY_T_DATA);
+ RUBY3_UNREACHABLE_RETURN(NULL);
+ }
+#endif
+
+ return RTYPEDDATA(obj)->type;
+}
+
+static inline VALUE
+rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
+{
+ TypedData_Make_Struct0(result, klass, void, size, type, *datap);
+ return result;
+}
+
+RUBY3_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
+static inline VALUE
+rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
+{
+ return rb_data_typed_object_wrap(klass, datap, type);
+}
+
+#endif /* RUBY3_RTYPEDDATA_H */