Ruby  3.4.0dev (2024-11-22 revision 37a72b0150ec36b4ea27175039afc28c62207b0c)
rarray.h
Go to the documentation of this file.
1 #ifndef RBIMPL_RARRAY_H /*-*-C++-*-vi:se ft=cpp:*/
2 #define RBIMPL_RARRAY_H
28 #include "ruby/internal/cast.h"
31 #include "ruby/internal/fl_type.h"
32 #include "ruby/internal/gc.h"
33 #include "ruby/internal/stdbool.h"
34 #include "ruby/internal/value.h"
36 #include "ruby/assert.h"
37 
44 #define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
46 #define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
47 #define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
48 #define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
49 #define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
51 #define RARRAY_LEN rb_array_len
52 #define RARRAY_CONST_PTR rb_array_const_ptr
55 #if defined(__fcc__) || defined(__fcc_version) || \
56  defined(__FCC__) || defined(__FCC_VERSION)
57 /* workaround for old version of Fujitsu C Compiler (fcc) */
58 # define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
59 #else
60 # define FIX_CONST_VALUE_PTR(x) (x)
61 #endif
62 
63 #define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
64 #define RARRAY_LENINT RARRAY_LENINT
65 #define RARRAY_ASET RARRAY_ASET
66 #define RARRAY_PTR RARRAY_PTR
82 enum ruby_rarray_flags {
83  /* RUBY_FL_USER0 is for ELTS_SHARED */
84 
102  RARRAY_EMBED_FLAG = RUBY_FL_USER1,
103 
114  RARRAY_EMBED_LEN_MASK = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
116 };
117 
125 };
126 
128 struct RArray {
129 
131  struct RBasic basic;
132 
134  union {
135 
140  struct {
141 
143  long len;
144 
146  union {
147 
153  long capa;
154 
161 #if defined(__clang__) /* <- clang++ is sane */ || \
162  !defined(__cplusplus) /* <- C99 is sane */ || \
163  (__cplusplus > 199711L) /* <- C++11 is sane */
164  const
165 #endif
167  } aux;
168 
175  const VALUE *ptr;
176  } heap;
177 
183  /* This is a length 1 array because:
184  * 1. GCC has a bug that does not optimize C flexible array members
185  * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
186  * 2. Zero length arrays are not supported by all compilers
187  */
188  const VALUE ary[1];
189  } as;
190 };
191 
202 VALUE *rb_ary_ptr_use_start(VALUE ary);
203 
213 void rb_ary_ptr_use_end(VALUE a);
214 
216 
234 static inline long
236 {
237  RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
238  RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
239 
240  VALUE f = RBASIC(ary)->flags;
241  f &= RARRAY_EMBED_LEN_MASK;
243  return RBIMPL_CAST((long)f);
244 }
245 
254 static inline long
256 {
257  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
258 
259  if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
260  return RARRAY_EMBED_LEN(a);
261  }
262  else {
263  return RARRAY(a)->as.heap.len;
264  }
265 }
266 
280 static inline int
282 {
283  return rb_long2int(RARRAY_LEN(ary));
284 }
285 
296 static inline const VALUE *
297 rb_array_const_ptr(VALUE a)
298 {
299  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
300 
301  if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
302  return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
303  }
304  else {
305  return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
306  }
307 }
308 
315 #define RBIMPL_RARRAY_STMT(ary, var, expr) do { \
316  RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
317  const VALUE rbimpl_ary = (ary); \
318  VALUE *var = rb_ary_ptr_use_start(rbimpl_ary); \
319  expr; \
320  rb_ary_ptr_use_end(rbimpl_ary); \
321 } while (0)
322 
348 #define RARRAY_PTR_USE(ary, ptr_name, expr) \
349  RBIMPL_RARRAY_STMT(ary, ptr_name, expr)
350 
365 static inline VALUE *
367 {
368  RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
369 
370  VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
371  return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
372 }
373 
385 static inline void
386 RARRAY_ASET(VALUE ary, long i, VALUE v)
387 {
388  RARRAY_PTR_USE(ary, ptr,
389  RB_OBJ_WRITE(ary, &ptr[i], v));
390 }
391 
403 #define RARRAY_AREF(a, i) RARRAY_CONST_PTR(a)[i]
404 
405 #endif /* RBIMPL_RARRAY_H */
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition: artificial.h:41
#define RBIMPL_ASSERT_OR_ASSUME(...)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition: assert.h:311
RBIMPL_ATTR_CONSTEXPR.
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_USHIFT
Number of bits in ruby_fl_type that are not open to users.
Definition: fl_type.h:159
static bool RB_FL_ANY_RAW(VALUE obj, VALUE flags)
This is an implementation detail of RB_FL_ANY().
Definition: fl_type.h:518
@ RUBY_FL_USER9
User-defined flag.
Definition: fl_type.h:337
@ RUBY_FL_USER8
User-defined flag.
Definition: fl_type.h:336
@ RUBY_FL_USER5
User-defined flag.
Definition: fl_type.h:333
@ RUBY_FL_USER3
User-defined flag.
Definition: fl_type.h:331
@ RUBY_FL_USER7
User-defined flag.
Definition: fl_type.h:335
@ RUBY_FL_USER6
User-defined flag.
Definition: fl_type.h:334
@ RUBY_FL_USER4
User-defined flag.
Definition: fl_type.h:332
@ RUBY_FL_USER1
User-defined flag.
Definition: fl_type.h:329
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition: gc.h:603
Registering values to the GC.
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj)
Identical to RB_OBJ_WB_UNPROTECT(), except it can also assert that the given object is of given type.
Definition: gc.h:643
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
Definition: io.h:2
Arithmetic conversion between C's long and Ruby's.
#define rb_long2int
Just another name of rb_long2int_inline.
Definition: long.h:62
Defines RBIMPL_ATTR_MAYBE_UNUSED.
#define inline
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition: defines.h:88
Defines RBIMPL_ATTR_PURE.
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE if and only if.
Definition: pure.h:38
static VALUE * RARRAY_PTR(VALUE ary)
Wild use of a C pointer.
Definition: rarray.h:366
#define RARRAY_LEN
Just another name of rb_array_len.
Definition: rarray.h:51
static long RARRAY_EMBED_LEN(VALUE ary)
Queries the length of the array.
Definition: rarray.h:235
static long rb_array_len(VALUE a)
Queries the length of the array.
Definition: rarray.h:255
#define RARRAY(obj)
Convenient casting macro.
Definition: rarray.h:44
static int RARRAY_LENINT(VALUE ary)
Identical to rb_array_len(), except it differs for the return type.
Definition: rarray.h:281
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
Definition: rarray.h:386
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
Definition: rarray.h:348
ruby_rarray_consts
This is an enum because GDB wants it (rather than a macro).
Definition: rarray.h:122
@ RARRAY_EMBED_LEN_SHIFT
Where ::RARRAY_EMBED_LEN_MASK resides.
Definition: rarray.h:124
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
Definition: rarray.h:52
Defines struct RBasic.
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
C99 shim for <stdbool.h>
Ruby's array.
Definition: rarray.h:128
struct RArray::@43::@44 heap
Arrays that use separated memory region for elements use this pattern.
struct RBasic basic
Basic part, including flags and class.
Definition: rarray.h:131
const VALUE shared_root
Parent of the array.
Definition: rarray.h:166
union RArray::@43::@44::@45 aux
Auxiliary info.
const VALUE ary[1]
Embedded elements.
Definition: rarray.h:188
long capa
Capacity of *ptr.
Definition: rarray.h:153
long len
Number of elements of the array.
Definition: rarray.h:143
union RArray::@43 as
Array's specific fields.
const VALUE * ptr
Pointer to the C array that holds the elements of the array.
Definition: rarray.h:175
Ruby object's base components.
Definition: rbasic.h:63
Defines VALUE and ID.
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40
Defines enum ruby_value_type.
@ RUBY_T_ARRAY
Definition: value_type.h:122