Ruby  3.4.0dev (2024-11-05 revision e440268d51fe02b303e3817a7a733a0dac1c5091)
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 
14 enum {
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 
20 struct 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 */
59 VALUE rb_struct_init_copy(VALUE copy, VALUE s);
60 VALUE rb_struct_lookup(VALUE s, VALUE idx);
61 VALUE rb_struct_s_keyword_init(VALUE klass);
62 static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
63 static inline long RSTRUCT_EMBED_LEN(VALUE st);
64 static inline long RSTRUCT_LEN(VALUE st);
65 static inline int RSTRUCT_LENINT(VALUE st);
66 static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
67 static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
68 static inline VALUE RSTRUCT_GET(VALUE st, long k);
69 
70 static inline long
71 RSTRUCT_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 
78 static inline long
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 
89 static inline int
90 RSTRUCT_LENINT(VALUE st)
91 {
92  return rb_long2int(RSTRUCT_LEN(st));
93 }
94 
95 static inline const VALUE *
96 RSTRUCT_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 
108 static inline void
109 RSTRUCT_SET(VALUE st, long k, VALUE v)
110 {
111  RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[k], v);
112 }
113 
114 static inline VALUE
115 RSTRUCT_GET(VALUE st, long k)
116 {
117  return RSTRUCT_CONST_PTR(st)[k];
118 }
119 
120 static inline const VALUE *
121 rb_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: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
static long RSTRUCT_LEN(VALUE st)
Returns the number of struct members.
Definition: rstruct.h:94
static VALUE RSTRUCT_SET(VALUE st, int k, VALUE v)
Resembles Struct#[]=.
Definition: rstruct.h:104
static VALUE RSTRUCT_GET(VALUE st, int k)
Resembles Struct#[].
Definition: rstruct.h:114
C99 shim for <stdbool.h>
Ruby object's base components.
Definition: rbasic.h:63
Definition: struct.h:20
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40