Ruby 3.5.0dev (2025-02-22 revision 412997300569c1853c09813e4924b6df3d7e8669)
struct.h
1#ifndef INTERNAL_STRUCT_H /*-*-C-*-vi:se ft=c:*/
2#define INTERNAL_STRUCT_H
11#include "ruby/internal/stdbool.h" /* for bool */
12#include "ruby/ruby.h" /* for struct RBasic */
13
14enum {
15 RSTRUCT_EMBED_LEN_MASK = RUBY_FL_USER7 | RUBY_FL_USER6 | RUBY_FL_USER5 | RUBY_FL_USER4 |
17 RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
18};
19
20struct RStruct {
21 struct RBasic basic;
22 union {
23 struct {
24 long len;
25 const VALUE *ptr;
26 } heap;
27 /* This is a length 1 array because:
28 * 1. GCC has a bug that does not optimize C flexible array members
29 * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
30 * 2. Zero length arrays are not supported by all compilers
31 */
32 const VALUE ary[1];
33 } as;
34};
35
36#define RSTRUCT(obj) ((struct RStruct *)(obj))
37
38#ifdef RSTRUCT_LEN
39# undef RSTRUCT_LEN
40#endif
41
42#ifdef RSTRUCT_PTR
43# undef RSTRUCT_PTR
44#endif
45
46#ifdef RSTRUCT_SET
47# undef RSTRUCT_SET
48#endif
49
50#ifdef RSTRUCT_GET
51# undef RSTRUCT_GET
52#endif
53
54#define RSTRUCT_LEN internal_RSTRUCT_LEN
55#define RSTRUCT_SET internal_RSTRUCT_SET
56#define RSTRUCT_GET internal_RSTRUCT_GET
57
58/* struct.c */
59VALUE rb_struct_init_copy(VALUE copy, VALUE s);
60VALUE rb_struct_lookup(VALUE s, VALUE idx);
61VALUE rb_struct_s_keyword_init(VALUE klass);
62static inline long RSTRUCT_EMBED_LEN(VALUE st);
63static inline long RSTRUCT_LEN(VALUE st);
64static inline int RSTRUCT_LENINT(VALUE st);
65static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
66static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
67static inline VALUE RSTRUCT_GET(VALUE st, long k);
68
69static inline long
70RSTRUCT_EMBED_LEN(VALUE st)
71{
72 long ret = FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK);
73 ret >>= RSTRUCT_EMBED_LEN_SHIFT;
74 return ret;
75}
76
77static inline long
78RSTRUCT_LEN(VALUE st)
79{
80 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
81 return RSTRUCT_EMBED_LEN(st);
82 }
83 else {
84 return RSTRUCT(st)->as.heap.len;
85 }
86}
87
88static inline int
89RSTRUCT_LENINT(VALUE st)
90{
91 return rb_long2int(RSTRUCT_LEN(st));
92}
93
94static inline const VALUE *
95RSTRUCT_CONST_PTR(VALUE st)
96{
97 const struct RStruct *p = RSTRUCT(st);
98
99 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
100 return p->as.ary;
101 }
102 else {
103 return p->as.heap.ptr;
104 }
105}
106
107static inline void
108RSTRUCT_SET(VALUE st, long k, VALUE v)
109{
110 RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[k], v);
111}
112
113static inline VALUE
114RSTRUCT_GET(VALUE st, long k)
115{
116 return RSTRUCT_CONST_PTR(st)[k];
117}
118
119#endif /* INTERNAL_STRUCT_H */
@ RUBY_FL_USHIFT
Number of bits in ruby_fl_type that are not open to users.
Definition fl_type.h:159
@ 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_USER2
User-defined flag.
Definition fl_type.h:330
@ RUBY_FL_USER4
User-defined flag.
Definition fl_type.h:332
@ RUBY_FL_USER1
User-defined flag.
Definition fl_type.h:329
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:132
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition gc.h:603
int len
Length of the buffer.
Definition io.h:8
#define rb_long2int
Just another name of rb_long2int_inline.
Definition long.h:62
C99 shim for <stdbool.h>
Ruby object's base components.
Definition rbasic.h:63
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40