Ruby 3.3.6p108 (2024-11-05 revision 75015d4c1f6965b5e85e96fb309f1f2129f933c0)
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 const VALUE *rb_struct_const_heap_ptr(VALUE st);
63static inline long RSTRUCT_EMBED_LEN(VALUE st);
64static inline long RSTRUCT_LEN(VALUE st);
65static inline int RSTRUCT_LENINT(VALUE st);
66static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
67static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
68static inline VALUE RSTRUCT_GET(VALUE st, long k);
69
70static inline long
71RSTRUCT_EMBED_LEN(VALUE st)
72{
73 long ret = FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK);
74 ret >>= RSTRUCT_EMBED_LEN_SHIFT;
75 return ret;
76}
77
78static inline long
79RSTRUCT_LEN(VALUE st)
80{
81 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
82 return RSTRUCT_EMBED_LEN(st);
83 }
84 else {
85 return RSTRUCT(st)->as.heap.len;
86 }
87}
88
89static inline int
90RSTRUCT_LENINT(VALUE st)
91{
92 return rb_long2int(RSTRUCT_LEN(st));
93}
94
95static inline const VALUE *
96RSTRUCT_CONST_PTR(VALUE st)
97{
98 const struct RStruct *p = RSTRUCT(st);
99
100 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
101 return p->as.ary;
102 }
103 else {
104 return p->as.heap.ptr;
105 }
106}
107
108static inline void
109RSTRUCT_SET(VALUE st, long k, VALUE v)
110{
111 RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[k], v);
112}
113
114static inline VALUE
115RSTRUCT_GET(VALUE st, long k)
116{
117 return RSTRUCT_CONST_PTR(st)[k];
118}
119
120static inline const VALUE *
121rb_struct_const_heap_ptr(VALUE st)
122{
123 assert(!FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK));
124 return RSTRUCT(st)->as.heap.ptr;
125}
126
127#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:619
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's object's, base components.
Definition rbasic.h:64
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40