Ruby 3.2.4p170 (2024-04-23 revision af471c0e0127eea0cafa6f308c0425bbfab0acf5)
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 "internal/gc.h" /* for RB_OBJ_WRITE */
13#include "ruby/ruby.h" /* for struct RBasic */
14
15enum {
16 RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
17 RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
18 RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
19 RSTRUCT_TRANSIENT_FLAG = FL_USER3,
20};
21
22struct RStruct {
23 struct RBasic basic;
24 union {
25 struct {
26 long len;
27 const VALUE *ptr;
28 } heap;
29 const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
30 } as;
31};
32
33#define RSTRUCT(obj) ((struct RStruct *)(obj))
34
35#ifdef RSTRUCT_LEN
36# undef RSTRUCT_LEN
37#endif
38
39#ifdef RSTRUCT_PTR
40# undef RSTRUCT_PTR
41#endif
42
43#ifdef RSTRUCT_SET
44# undef RSTRUCT_SET
45#endif
46
47#ifdef RSTRUCT_GET
48# undef RSTRUCT_GET
49#endif
50
51#define RSTRUCT_LEN internal_RSTRUCT_LEN
52#define RSTRUCT_SET internal_RSTRUCT_SET
53#define RSTRUCT_GET internal_RSTRUCT_GET
54
55/* struct.c */
56VALUE rb_struct_init_copy(VALUE copy, VALUE s);
57VALUE rb_struct_lookup(VALUE s, VALUE idx);
58VALUE rb_struct_s_keyword_init(VALUE klass);
59static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
60static inline bool RSTRUCT_TRANSIENT_P(VALUE st);
61static inline void RSTRUCT_TRANSIENT_SET(VALUE st);
62static inline void RSTRUCT_TRANSIENT_UNSET(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 bool
71RSTRUCT_TRANSIENT_P(VALUE st)
72{
73#if USE_TRANSIENT_HEAP
74 return FL_TEST_RAW(st, RSTRUCT_TRANSIENT_FLAG);
75#else
76 return false;
77#endif
78}
79
80static inline void
81RSTRUCT_TRANSIENT_SET(VALUE st)
82{
83#if USE_TRANSIENT_HEAP
84 FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
85#endif
86}
87
88static inline void
89RSTRUCT_TRANSIENT_UNSET(VALUE st)
90{
91#if USE_TRANSIENT_HEAP
92 FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
93#endif
94}
95
96static inline long
97RSTRUCT_EMBED_LEN(VALUE st)
98{
99 long ret = FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK);
100 ret >>= RSTRUCT_EMBED_LEN_SHIFT;
101 return ret;
102}
103
104static inline long
105RSTRUCT_LEN(VALUE st)
106{
107 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
108 return RSTRUCT_EMBED_LEN(st);
109 }
110 else {
111 return RSTRUCT(st)->as.heap.len;
112 }
113}
114
115static inline int
116RSTRUCT_LENINT(VALUE st)
117{
118 return rb_long2int(RSTRUCT_LEN(st));
119}
120
121static inline const VALUE *
122RSTRUCT_CONST_PTR(VALUE st)
123{
124 const struct RStruct *p = RSTRUCT(st);
125
126 if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
127 return p->as.ary;
128 }
129 else {
130 return p->as.heap.ptr;
131 }
132}
133
134static inline void
135RSTRUCT_SET(VALUE st, long k, VALUE v)
136{
137 RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[k], v);
138}
139
140static inline VALUE
141RSTRUCT_GET(VALUE st, long k)
142{
143 return RSTRUCT_CONST_PTR(st)[k];
144}
145
146static inline const VALUE *
147rb_struct_const_heap_ptr(VALUE st)
148{
149 /* TODO: check embed on debug mode */
150 return RSTRUCT(st)->as.heap.ptr;
151}
152
153#endif /* INTERNAL_STRUCT_H */
@ RUBY_FL_USHIFT
Number of bits in ruby_fl_type that are not open to users.
Definition fl_type.h:167
@ RUBY_FL_USER2
User-defined flag.
Definition fl_type.h:362
@ RUBY_FL_USER1
User-defined flag.
Definition fl_type.h:361
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
Definition fl_type.h:142
#define FL_USER3
Old name of RUBY_FL_USER3.
Definition fl_type.h:75
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:140
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition fl_type.h:138
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition rgengc.h:220
#define rb_long2int
Just another name of rb_long2int_inline.
Definition long.h:62
@ RVALUE_EMBED_LEN_MAX
Max possible number of objects that can be embedded.
Definition rbasic.h:55
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