Ruby  3.1.4p223 (2023-03-30 revision HEAD)
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/rgengc.h"
33 #include "ruby/internal/stdbool.h"
34 #include "ruby/internal/value.h"
36 #include "ruby/assert.h"
37 
46 #ifndef USE_TRANSIENT_HEAP
47 # define USE_TRANSIENT_HEAP 1
48 #endif
49 
56 #define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
58 #define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
59 #define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
60 #define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
61 #define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
62 #if USE_TRANSIENT_HEAP
63 # define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
64 #else
65 # define RARRAY_TRANSIENT_FLAG 0
66 #endif
68 #define RARRAY_LEN rb_array_len
69 #define RARRAY_CONST_PTR rb_array_const_ptr
70 #define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient
73 #if defined(__fcc__) || defined(__fcc_version) || \
74  defined(__FCC__) || defined(__FCC_VERSION)
75 /* workaround for old version of Fujitsu C Compiler (fcc) */
76 # define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
77 #else
78 # define FIX_CONST_VALUE_PTR(x) (x)
79 #endif
80 
81 #define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
82 #define RARRAY_LENINT RARRAY_LENINT
83 #define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
84 #define RARRAY_ASET RARRAY_ASET
85 #define RARRAY_PTR RARRAY_PTR
101 enum ruby_rarray_flags {
119  RARRAY_EMBED_FLAG = RUBY_FL_USER1,
120 
121  /* RUBY_FL_USER2 is for ELTS_SHARED */
122 
133  RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
134 #if USE_TRANSIENT_HEAP
135  ,
136 
149  RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
150 #endif
151 };
152 
160 
162  RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
163 };
164 
166 struct RArray {
167 
169  struct RBasic basic;
170 
172  union {
173 
178  struct {
179 
181  long len;
182 
184  union {
185 
191  long capa;
192 
199 #if defined(__clang__) /* <- clang++ is sane */ || \
200  !defined(__cplusplus) /* <- C99 is sane */ || \
201  (__cplusplus > 199711L) /* <- C++11 is sane */
202  const
203 #endif
205  } aux;
206 
213  const VALUE *ptr;
214  } heap;
215 
222  } as;
223 };
224 
235 VALUE *rb_ary_ptr_use_start(VALUE ary);
236 
246 void rb_ary_ptr_use_end(VALUE a);
247 
248 #if USE_TRANSIENT_HEAP
256 void rb_ary_detransient(VALUE a);
257 #endif
259 
277 static inline long
279 {
280  RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
281  RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
282 
283  VALUE f = RBASIC(ary)->flags;
284  f &= RARRAY_EMBED_LEN_MASK;
286  return RBIMPL_CAST((long)f);
287 }
288 
297 static inline long
299 {
300  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
301 
302  if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
303  return RARRAY_EMBED_LEN(a);
304  }
305  else {
306  return RARRAY(a)->as.heap.len;
307  }
308 }
309 
323 static inline int
325 {
326  return rb_long2int(RARRAY_LEN(ary));
327 }
328 
344 static inline bool
346 {
347  RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
348 
349 #if USE_TRANSIENT_HEAP
350  return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
351 #else
352  return false;
353 #endif
354 }
355 
366 static inline const VALUE *
367 rb_array_const_ptr_transient(VALUE a)
368 {
369  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
370 
371  if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
372  return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
373  }
374  else {
375  return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
376  }
377 }
378 
379 #if ! USE_TRANSIENT_HEAP
381 #endif
392 static inline const VALUE *
393 rb_array_const_ptr(VALUE a)
394 {
395  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
396 
397 #if USE_TRANSIENT_HEAP
398  if (RARRAY_TRANSIENT_P(a)) {
400  }
401 #endif
402  return rb_array_const_ptr_transient(a);
403 }
404 
416 static inline VALUE *
417 rb_array_ptr_use_start(VALUE a,
419  int allow_transient)
420 {
421  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
422 
423 #if USE_TRANSIENT_HEAP
424  if (!allow_transient) {
425  if (RARRAY_TRANSIENT_P(a)) {
427  }
428  }
429 #endif
430 
431  return rb_ary_ptr_use_start(a);
432 }
433 
443 static inline void
444 rb_array_ptr_use_end(VALUE a,
446  int allow_transient)
447 {
448  RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
449  rb_ary_ptr_use_end(a);
450 }
451 
458 #define RBIMPL_RARRAY_STMT(flag, ary, var, expr) do { \
459  RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
460  const VALUE rbimpl_ary = (ary); \
461  VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); \
462  expr; \
463  rb_array_ptr_use_end(rbimpl_ary, (flag)); \
464 } while (0)
465 
472 #define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
473 
480 #define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
481 
507 #define RARRAY_PTR_USE(ary, ptr_name, expr) \
508  RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
509 
516 #define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
517 
524 #define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
525 
533 #define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
534  RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
535 
550 static inline VALUE *
552 {
553  RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
554 
555  VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
556  return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
557 }
558 
570 static inline void
571 RARRAY_ASET(VALUE ary, long i, VALUE v)
572 {
573  RARRAY_PTR_USE_TRANSIENT(ary, ptr,
574  RB_OBJ_WRITE(ary, &ptr[i], v));
575 }
576 
588 #define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
589 
590 #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(expr)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition: assert.h:229
RBIMPL_ATTR_CONSTEXPR.
Tweaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition: dllexport.h:106
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition: dllexport.h:97
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:167
static bool RB_FL_ANY_RAW(VALUE obj, VALUE flags)
This is an implenentation detail of RB_FL_ANY().
Definition: fl_type.h:556
@ RUBY_FL_USER3
User-defined flag.
Definition: fl_type.h:363
@ RUBY_FL_USER4
User-defined flag.
Definition: fl_type.h:364
@ RUBY_FL_USER1
User-defined flag.
Definition: fl_type.h:361
@ RUBY_FL_USER13
User-defined flag.
Definition: fl_type.h:373
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition: rgengc.h:220
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 RBIMPL_ATTR_MAYBE_UNUSED()
Wraps (or simulates) [[maybe_unused]]
Definition: maybe_unused.h:33
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:551
#define RARRAY_LEN
Just another name of rb_array_len.
Definition: rarray.h:68
static long RARRAY_EMBED_LEN(VALUE ary)
Queries the length of the array.
Definition: rarray.h:278
void rb_ary_detransient(VALUE a)
Destructively converts an array of transient backend into ordinal one.
Definition: array.c:429
static long rb_array_len(VALUE a)
Queries the length of the array.
Definition: rarray.h:298
#define RARRAY(obj)
Convenient casting macro.
Definition: rarray.h:56
static bool RARRAY_TRANSIENT_P(VALUE ary)
Queries if the array is a transient array.
Definition: rarray.h:345
static int RARRAY_LENINT(VALUE ary)
Identical to rb_array_len(), except it differs for the return type.
Definition: rarray.h:324
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
Definition: rarray.h:571
ruby_rarray_consts
This is an enum because GDB wants it (rather than a macro).
Definition: rarray.h:157
@ RARRAY_EMBED_LEN_MAX
Max possible number elements that can be embedded.
Definition: rarray.h:162
@ RARRAY_EMBED_LEN_SHIFT
Where ::RARRAY_EMBED_LEN_MASK resides.
Definition: rarray.h:159
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Identical to RARRAY_PTR_USE, except the pointer can be a transient one.
Definition: rarray.h:533
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
Definition: rarray.h:69
Defines struct RBasic.
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
RGENGC write-barrier APIs.
#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: rgengc.h:260
C99 shim for <stdbool.h>
Ruby's array.
Definition: rarray.h:166
struct RArray::@42::@43 heap
Arrays that use separated memory region for elements use this pattern.
struct RBasic basic
Basic part, including flags and class.
Definition: rarray.h:169
const VALUE shared_root
Parent of the array.
Definition: rarray.h:204
const VALUE ary[RARRAY_EMBED_LEN_MAX]
Embedded elements.
Definition: rarray.h:221
union RArray::@42::@43::@44 aux
Auxiliary info.
long capa
Capacity of *ptr.
Definition: rarray.h:191
long len
Number of elements of the array.
Definition: rarray.h:181
const VALUE * ptr
Pointer to the C array that holds the elements of the array.
Definition: rarray.h:213
union RArray::@42 as
Array's specific fields.
Ruby's object's, base components.
Definition: rbasic.h:64
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:121