summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ruby/atomic.h26
-rw-r--r--include/ruby/internal/anyargs.h22
-rw-r--r--include/ruby/internal/attr/nonstring.h38
-rw-r--r--include/ruby/internal/core/rdata.h9
-rw-r--r--include/ruby/internal/core/rtypeddata.h26
5 files changed, 105 insertions, 16 deletions
diff --git a/include/ruby/atomic.h b/include/ruby/atomic.h
index e0977d21aa..2f5090e62f 100644
--- a/include/ruby/atomic.h
+++ b/include/ruby/atomic.h
@@ -302,6 +302,19 @@ typedef unsigned int rb_atomic_t;
RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))
/**
+* Identical to #RUBY_ATOMIC_SET, except it expects its arguments are
+* `void*`. There are cases where ::rb_atomic_t is 32bit while ::VALUE is
+* 64bit. This should be used for pointer related operations to support such
+* platforms.
+*
+* @param var A variable of `void*`.
+* @param val Value to set.
+* @post `var` holds `val`.
+*/
+#define RUBY_ATOMIC_PTR_SET(var, val) \
+ rbimpl_atomic_ptr_set((volatile void **)&(var), (val))
+
+/**
* Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.
* There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit. This
* should be used for size related operations to support such platforms.
@@ -791,6 +804,19 @@ rbimpl_atomic_ptr_exchange(void *volatile *ptr, const void *val)
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
+static inline void
+rbimpl_atomic_ptr_set(volatile void **ptr, void *val)
+{
+ RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t));
+
+ const size_t sval = RBIMPL_CAST((size_t)val);
+ volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
+ rbimpl_atomic_size_set(sptr, sval);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
{
diff --git a/include/ruby/internal/anyargs.h b/include/ruby/internal/anyargs.h
index e3e1b6166d..e4c6d155cc 100644
--- a/include/ruby/internal/anyargs.h
+++ b/include/ruby/internal/anyargs.h
@@ -84,12 +84,15 @@
#elif defined(_WIN32) || defined(__CYGWIN__)
# /* Skip due to [Bug #16134] */
+# define RBIMPL_CAST_FN_PTR 1
#elif ! RBIMPL_HAS_ATTRIBUTE(transparent_union)
# /* :TODO: improve here, please find a way to support. */
+# define RBIMPL_CAST_FN_PTR 1
#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* :TODO: improve here, please find a way to support. */
+# define RBIMPL_CAST_FN_PTR 1
#else
# /** @cond INTERNAL_MACRO */
@@ -348,6 +351,25 @@ RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
#endif /* __cplusplus */
+#if defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus)
+/* In C23, K&R style prototypes are gone and so `void foo(ANYARGS)` became
+ * equivalent to `void foo(void)` unlike in earlier versions. This is a problem
+ * for rb_define_* functions since that makes all valid functions one can pass
+ * trip -Wincompatible-pointer-types, which we treat as errors. This is mostly
+ * not a problem for the __builtin_choose_expr path, but outside of that we
+ * need to add a cast for compatibility.
+ */
+#define rb_define_method(klass, mid, func, arity) rb_define_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_method_id(klass, mid, func, arity) rb_define_method_id((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_singleton_method(obj, mid, func, arity) rb_define_singleton_method((obj), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_protected_method(klass, mid, func, arity) rb_define_protected_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_private_method(klass, mid, func, arity) rb_define_private_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_module_function(mod, mid, func, arity) rb_define_module_function((mod), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_global_function(mid, func, arity) rb_define_global_function((mid), (VALUE (*)(ANYARGS))(func), (arity))
+
+#undef RBIMPL_CAST_FN_PTR
+#endif /* defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus) */
+
/**
* This macro is to properly cast a function parameter of *_define_method
* family. It has been around since 1.x era so you can maximise backwards
diff --git a/include/ruby/internal/attr/nonstring.h b/include/ruby/internal/attr/nonstring.h
new file mode 100644
index 0000000000..9a66180e19
--- /dev/null
+++ b/include/ruby/internal/attr/nonstring.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_ATTR_NONSTRING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NONSTRING_H
+/**
+ * @file
+ * @author Ruby developers <[email protected]>
+ * @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 `RBIMPL` or `rbimpl` 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 #RBIMPL_ATTR_NONSTRING.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((nonstring))` */
+#if RBIMPL_HAS_ATTRIBUTE(nonstring)
+# define RBIMPL_ATTR_NONSTRING() __attribute__((nonstring))
+# if RBIMPL_COMPILER_SINCE(GCC, 15, 0, 0)
+# define RBIMPL_ATTR_NONSTRING_ARRAY() RBIMPL_ATTR_NONSTRING()
+# else
+# define RBIMPL_ATTR_NONSTRING_ARRAY() /* void */
+# endif
+#else
+# define RBIMPL_ATTR_NONSTRING() /* void */
+# define RBIMPL_ATTR_NONSTRING_ARRAY() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NONSTRING_H */
diff --git a/include/ruby/internal/core/rdata.h b/include/ruby/internal/core/rdata.h
index e4c146a716..cab412af72 100644
--- a/include/ruby/internal/core/rdata.h
+++ b/include/ruby/internal/core/rdata.h
@@ -133,6 +133,12 @@ struct RData {
*/
RUBY_DATA_FUNC dmark;
+ /** Pointer to the actual C level struct that you want to wrap.
+ * This is in between dmark and dfree to allow DATA_PTR to continue
+ * to work for both RData and non-embedded RTypedData.
+ */
+ void *data;
+
/**
* This function is called when the object is no longer used. You need to
* do whatever necessary to avoid memory leaks.
@@ -141,9 +147,6 @@ struct RData {
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dfree;
-
- /** Pointer to the actual C level struct that you want to wrap. */
- void *data;
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h
index 6c19576c20..b576be779f 100644
--- a/include/ruby/internal/core/rtypeddata.h
+++ b/include/ruby/internal/core/rtypeddata.h
@@ -114,7 +114,10 @@
#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
/** @endcond */
-#define TYPED_DATA_EMBEDDED 2
+#define IS_TYPED_DATA ((VALUE)1)
+#define TYPED_DATA_EMBEDDED ((VALUE)2)
+#define TYPED_DATA_PTR_FLAGS ((VALUE)3)
+#define TYPED_DATA_PTR_MASK (~TYPED_DATA_PTR_FLAGS)
/**
* @private
@@ -353,18 +356,16 @@ struct RTypedData {
struct RBasic basic;
/**
+ * This is a `const rb_data_type_t *const` value, with the low bits set:
+ *
+ * 1: Always set, to differentiate RTypedData from RData.
+ * 2: Set if object is embedded.
+ *
* This field stores various information about how Ruby should handle a
* data. This roughly resembles a Ruby level class (apart from method
* definition etc.)
*/
- const rb_data_type_t *const type;
-
- /**
- * This has to be always 1.
- *
- * @internal
- */
- const VALUE typed_flag;
+ const VALUE type;
/** Pointer to the actual C level struct that you want to wrap. */
void *data;
@@ -525,7 +526,7 @@ RTYPEDDATA_EMBEDDED_P(VALUE obj)
}
#endif
- return RTYPEDDATA(obj)->typed_flag & TYPED_DATA_EMBEDDED;
+ return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
}
static inline void *
@@ -561,8 +562,7 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline bool
rbimpl_rtypeddata_p(VALUE obj)
{
- VALUE typed_flag = RTYPEDDATA(obj)->typed_flag;
- return typed_flag != 0 && typed_flag <= 3;
+ return RTYPEDDATA(obj)->type & IS_TYPED_DATA;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
@@ -608,7 +608,7 @@ RTYPEDDATA_TYPE(VALUE obj)
}
#endif
- return RTYPEDDATA(obj)->type;
+ return (const struct rb_data_type_struct *)(RTYPEDDATA(obj)->type & TYPED_DATA_PTR_MASK);
}
/**