Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 25 additions & 28 deletions include/ruby/internal/core/rtypeddata.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,17 @@ RBIMPL_ATTR_NONNULL(())
void rb_unexpected_typeddata(const rb_data_type_t *actual, const rb_data_type_t *expected);
RBIMPL_SYMBOL_EXPORT_END()

#if RUBY_DEBUG
# define RBIMPL_TYPEDDATA_PRECONDITION(obj, unreachable) \
while (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) { \
rb_unexpected_object_type(obj, "Data"); \
unreachable; \
}
#else
# define RBIMPL_TYPEDDATA_PRECONDITION(obj, unreachable) \
RBIMPL_ASSERT_NOTHING
#endif

/**
* Converts sval, a pointer to your struct, into a Ruby object.
*
Expand Down Expand Up @@ -513,7 +524,7 @@ RBIMPL_SYMBOL_EXPORT_END()
*/
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
(sval) = RBIMPL_CAST((type *)RTYPEDDATA_GET_DATA(result)); \
(sval) = RBIMPL_CAST((type *)rbimpl_typeddata_get_data(result)); \
RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))

/**
Expand Down Expand Up @@ -553,39 +564,35 @@ RBIMPL_SYMBOL_EXPORT_END()
static inline bool
rbimpl_typeddata_embedded_p(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
Check_Type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(false);
}
#endif

return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED;
}

RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY()
static inline bool
RTYPEDDATA_EMBEDDED_P(VALUE obj)
{
RBIMPL_TYPEDDATA_PRECONDITION(obj, RBIMPL_UNREACHABLE_RETURN(false));

return rbimpl_typeddata_embedded_p(obj);
}

static inline void *
RTYPEDDATA_GET_DATA(VALUE obj)
rbimpl_typeddata_get_data(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
Check_Type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(NULL);
}
#endif

/* We reuse the data pointer in embedded TypedData. */
return rbimpl_typeddata_embedded_p(obj) ?
RBIMPL_CAST((void *)&RTYPEDDATA_DATA(obj)) :
RTYPEDDATA_DATA(obj);
}

static inline void *
RTYPEDDATA_GET_DATA(VALUE obj)
{
RBIMPL_TYPEDDATA_PRECONDITION(obj, RBIMPL_UNREACHABLE_RETURN(NULL));

return rbimpl_typeddata_get_data(obj);
}

RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
Expand Down Expand Up @@ -639,12 +646,7 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline bool
RTYPEDDATA_P(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
Check_Type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(false);
}
#endif
RBIMPL_TYPEDDATA_PRECONDITION(obj, RBIMPL_UNREACHABLE_RETURN(false));

return rbimpl_rtypeddata_p(obj);
}
Expand All @@ -662,12 +664,7 @@ RBIMPL_ATTR_RETURNS_NONNULL()
static inline const rb_data_type_t *
RTYPEDDATA_TYPE(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
rb_unexpected_type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(NULL);
}
#endif
RBIMPL_TYPEDDATA_PRECONDITION(obj, RBIMPL_UNREACHABLE_RETURN(NULL));

VALUE type = RTYPEDDATA(obj)->type & TYPED_DATA_PTR_MASK;
const rb_data_type_t *ptr = RBIMPL_CAST((const rb_data_type_t *)type);
Expand Down
4 changes: 2 additions & 2 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -1960,8 +1960,8 @@ str_duplicate_setup_heap(VALUE klass, VALUE str, VALUE dup)
RUBY_ASSERT(RB_OBJ_FROZEN_RAW(root));

RSTRING(dup)->as.heap.ptr = RSTRING_PTR(str);
FL_SET(root, STR_SHARED_ROOT);
RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, root);
FL_SET_RAW(dup, RSTRING_NOEMBED);
STR_SET_SHARED(dup, root);
flags |= RSTRING_NOEMBED | STR_SHARED;

STR_SET_LEN(dup, RSTRING_LEN(str));
Expand Down