Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
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"
34#include "ruby/internal/value.h"
36#include "ruby/assert.h"
37
38#ifndef USE_TRANSIENT_HEAP
39# define USE_TRANSIENT_HEAP 1
40#endif
41
42#define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
43#define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
44#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
45#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
46#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
47#if USE_TRANSIENT_HEAP
48# define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
49#else
50# define RARRAY_TRANSIENT_FLAG 0
51#endif
52#define RARRAY_LEN rb_array_len
53#define RARRAY_CONST_PTR rb_array_const_ptr
54#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient
55
57#if defined(__fcc__) || defined(__fcc_version) || \
58 defined(__FCC__) || defined(__FCC_VERSION)
59/* workaround for old version of Fujitsu C Compiler (fcc) */
60# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
61#else
62# define FIX_CONST_VALUE_PTR(x) (x)
63#endif
64
65#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
66#define RARRAY_LENINT RARRAY_LENINT
67#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
68#define RARRAY_ASET RARRAY_ASET
69#define RARRAY_PTR RARRAY_PTR
73 RARRAY_EMBED_FLAG = RUBY_FL_USER1,
74 /* RUBY_FL_USER2 is for ELTS_SHARED */
75 RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
76#if USE_TRANSIENT_HEAP
77 ,
78 RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
79#endif
80};
81
84 RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
85};
86
87struct RArray {
88 struct RBasic basic;
89 union {
90 struct {
91 long len;
92 union {
93 long capa;
94#if defined(__clang__) /* <- clang++ is sane */ || \
95 !defined(__cplusplus) /* <- C99 is sane */ || \
96 (__cplusplus > 199711L) /* <- C++11 is sane */
97 const
98#endif
100 } aux;
101 const VALUE *ptr;
102 } heap;
104 } as;
105};
106
110#if USE_TRANSIENT_HEAP
112#endif
114
117static inline long
118RARRAY_EMBED_LEN(VALUE ary)
119{
120 RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
121 RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
122
123 VALUE f = RBASIC(ary)->flags;
126 return RBIMPL_CAST((long)f);
127}
128
130static inline long
131rb_array_len(VALUE a)
132{
133 RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
134
135 if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
136 return RARRAY_EMBED_LEN(a);
137 }
138 else {
139 return RARRAY(a)->as.heap.len;
140 }
141}
142
144static inline int
145RARRAY_LENINT(VALUE ary)
146{
147 return rb_long2int(RARRAY_LEN(ary));
148}
149
152static inline bool
153RARRAY_TRANSIENT_P(VALUE ary)
154{
155 RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
156
157#if USE_TRANSIENT_HEAP
158 return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
159#else
160 return false;
161#endif
162}
163
165/* internal function. do not use this function */
166static inline const VALUE *
167rb_array_const_ptr_transient(VALUE a)
168{
169 RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
170
171 if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
172 return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
173 }
174 else {
175 return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
176 }
177}
178
179#if ! USE_TRANSIENT_HEAP
181#endif
182/* internal function. do not use this function */
183static inline const VALUE *
184rb_array_const_ptr(VALUE a)
185{
186 RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
187
188#if USE_TRANSIENT_HEAP
189 if (RARRAY_TRANSIENT_P(a)) {
191 }
192#endif
193 return rb_array_const_ptr_transient(a);
194}
195
196/* internal function. do not use this function */
197static inline VALUE *
198rb_array_ptr_use_start(VALUE a,
200 int allow_transient)
201{
202 RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
203
204#if USE_TRANSIENT_HEAP
205 if (!allow_transient) {
206 if (RARRAY_TRANSIENT_P(a)) {
208 }
209 }
210#endif
211
212 return rb_ary_ptr_use_start(a);
213}
214
215/* internal function. do not use this function */
216static inline void
217rb_array_ptr_use_end(VALUE a,
219 int allow_transient)
220{
221 RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
223}
224
225#define RBIMPL_RARRAY_STMT(flag, ary, var, expr) do { \
226 RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
227 const VALUE rbimpl_ary = (ary); \
228 VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); \
229 expr; \
230 rb_array_ptr_use_end(rbimpl_ary, (flag)); \
231} while (0)
232
233#define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
234#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
235#define RARRAY_PTR_USE(ary, ptr_name, expr) \
236 RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
237
238#define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
239#define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
240#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
241 RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
242
243static inline VALUE *
244RARRAY_PTR(VALUE ary)
245{
246 RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
247
248 VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
249 return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
250}
251
252static inline void
253RARRAY_ASET(VALUE ary, long i, VALUE v)
254{
256 RB_OBJ_WRITE(ary, &ptr[i], v));
257}
258
259/*
260 * :FIXME: we want to convert RARRAY_AREF into an inline function (to add rooms
261 * for more sanity checks). However there were situations where the address of
262 * this macro is taken i.e. &RARRAY_AREF(...). They cannot be possible if this
263 * is not a macro. Such usages are abuse, and we eliminated them internally.
264 * However we are afraid of similar things to remain in the wild. This macro
265 * remains as it is due to that. If we could warn such usages we can set a
266 * transition path, but currently no way is found to do so.
267 */
268#define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
269
270#endif /* RBIMPL_RARRAY_H */
void rb_ary_detransient(VALUE ary)
Definition: array.c:432
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition: artificial.h:43
#define RBIMPL_ASSERT_OR_ASSUME(expr)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition: assert.h:229
#define FIX_CONST_VALUE_PTR(x)
Definition: bigdecimal.h:116
Defines RBIMPL_CAST.
RBIMPL_ATTR_CONSTEXPR.
struct RIMemo * ptr
Definition: debug.c:88
Tewaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition: dllexport.h:86
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition: dllexport.h:77
Defines enum ruby_fl_type.
@ RUBY_FL_USHIFT
Definition: fl_type.h:150
Arithmetic conversion between C's long and Ruby's.
#define rb_long2int
Definition: long.h:62
Defines RBIMPL_ATTR_MAYBE_UNUSED.
#define RBIMPL_ATTR_MAYBE_UNUSED()
Wraps (or simulates) [[maybe_unused]]
Definition: maybe_unused.h:35
Defines RBIMPL_ATTR_PURE.
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE iff.
Definition: pure.h:38
#define RARRAY_EMBED_FLAG
Definition: rarray.h:43
#define RARRAY_TRANSIENT_FLAG
Definition: rarray.h:50
#define RARRAY_LEN
Definition: rarray.h:52
#define RARRAY(obj)
Definition: rarray.h:42
void rb_ary_ptr_use_end(VALUE a)
Definition: array.c:252
VALUE * rb_ary_ptr_use_start(VALUE ary)
Definition: array.c:243
ruby_rarray_flags
Definition: rarray.h:72
#define RARRAY_EMBED_LEN_SHIFT
Definition: rarray.h:46
#define RARRAY_EMBED_LEN_MAX
Definition: rarray.h:45
ruby_rarray_consts
Definition: rarray.h:82
#define RARRAY_EMBED_LEN_MASK
Definition: rarray.h:44
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Definition: rarray.h:240
#define RARRAY_CONST_PTR
Definition: rarray.h:53
Defines struct RBasic.
#define RBASIC(obj)
Definition: rbasic.h:34
RGENGC write-barrier APIs.
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:107
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj)
Definition: rgengc.h:123
#define f
C99 shim for <stdbool.h>
#define const
Definition: strftime.c:108
Definition: rarray.h:87
struct RBasic basic
Definition: rarray.h:88
const VALUE shared_root
Definition: rarray.h:99
long capa
Definition: rarray.h:93
long len
Definition: rarray.h:91
union RArray::@95 as
const VALUE * ptr
Definition: rarray.h:101
Definition: rbasic.h:47
Defines VALUE and ID.
unsigned long VALUE
Definition: value.h:38
Defines enum ruby_value_type.
@ RUBY_T_ARRAY
Definition: value_type.h:119