Ruby 3.3.6p108 (2024-11-05 revision 75015d4c1f6965b5e85e96fb309f1f2129f933c0)
imemo.h
1#ifndef INTERNAL_IMEMO_H /*-*-C-*-vi:se ft=c:*/
2#define INTERNAL_IMEMO_H
11#include "ruby/internal/config.h"
12#include <stddef.h> /* for size_t */
13#include "internal/array.h" /* for rb_ary_hidden_new_fill */
14#include "ruby/internal/stdbool.h" /* for bool */
15#include "ruby/ruby.h" /* for rb_block_call_func_t */
16
17#ifndef IMEMO_DEBUG
18# define IMEMO_DEBUG 0
19#endif
20
21#define IMEMO_MASK 0x0f
22
23/* FL_USER0 to FL_USER3 is for type */
24#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
25#define IMEMO_FL_USER0 FL_USER4
26#define IMEMO_FL_USER1 FL_USER5
27#define IMEMO_FL_USER2 FL_USER6
28#define IMEMO_FL_USER3 FL_USER7
29#define IMEMO_FL_USER4 FL_USER8
30#define IMEMO_FL_USER5 FL_USER9
31
32enum imemo_type {
33 imemo_env = 0,
34 imemo_cref = 1,
35 imemo_svar = 2,
36 imemo_throw_data = 3,
37 imemo_ifunc = 4,
38 imemo_memo = 5,
39 imemo_ment = 6,
40 imemo_iseq = 7,
41 imemo_tmpbuf = 8,
42 imemo_ast = 9,
43 imemo_parser_strterm = 10,
44 imemo_callinfo = 11,
45 imemo_callcache = 12,
46 imemo_constcache = 13,
47};
48
49/* CREF (Class REFerence) is defined in method.h */
50
52struct vm_svar {
53 VALUE flags;
55 const VALUE lastline;
56 const VALUE backref;
57 const VALUE others;
58};
59
62 VALUE flags;
63 VALUE reserved;
64 const VALUE throw_obj;
65 const struct rb_control_frame_struct *catch_frame;
66 int throw_state;
67};
68
69#define THROW_DATA_CONSUMED IMEMO_FL_USER0
70
71/* IFUNC (Internal FUNCtion) */
72
74#if SIZEOF_INT * 2 > SIZEOF_VALUE
75 signed int min: (SIZEOF_VALUE * CHAR_BIT) / 2;
76 signed int max: (SIZEOF_VALUE * CHAR_BIT) / 2;
77#else
78 int min, max;
79#endif
80};
81
83struct vm_ifunc {
84 VALUE flags;
85 VALUE *svar_lep;
87 const void *data;
88 struct vm_ifunc_argc argc;
89};
90
92 VALUE flags;
93 VALUE reserved;
94 VALUE *ptr; /* malloc'ed buffer */
95 struct rb_imemo_tmpbuf_struct *next; /* next imemo */
96 size_t cnt; /* buffer size in VALUE */
97};
98
103struct MEMO {
104 VALUE flags;
105 VALUE reserved;
106 const VALUE v1;
107 const VALUE v2;
108 union {
109 long cnt;
110 long state;
111 const VALUE value;
112 void (*func)(void);
113 } u3;
114};
115
116/* ment is in method.h */
117
118#define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
119#define MEMO_CAST(m) ((struct MEMO *)(m))
120#define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
121#define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
122#define NEW_MEMO_FOR(type, value) \
123 ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
124#define NEW_PARTIAL_MEMO_FOR(type, value, member) \
125 ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), \
126 rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
127 MEMO_FOR(type, value))
128
130rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
131struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
132static inline enum imemo_type imemo_type(VALUE imemo);
133static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
134static inline bool imemo_throw_data_p(VALUE imemo);
135static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
136static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
137static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
138static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
139static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
140static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
141static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
142
143RUBY_SYMBOL_EXPORT_BEGIN
144#if IMEMO_DEBUG
145VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
146#define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
147#else
148VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
149#endif
150const char *rb_imemo_name(enum imemo_type type);
151RUBY_SYMBOL_EXPORT_END
152
153static inline enum imemo_type
154imemo_type(VALUE imemo)
155{
156 return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
157}
158
159static inline int
160imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
161{
162 if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
163 /* fixed at compile time if imemo_type is given. */
164 const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
165 const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
166 /* fixed at runtime. */
167 return expected_type == (RBASIC(imemo)->flags & mask);
168 }
169 else {
170 return 0;
171 }
172}
173
174#define IMEMO_TYPE_P(v, t) imemo_type_p((VALUE)v, t)
175
176static inline bool
177imemo_throw_data_p(VALUE imemo)
178{
179 return RB_TYPE_P(imemo, T_IMEMO);
180}
181
182static inline struct vm_ifunc *
183rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
184{
185 return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
186}
187
188static inline VALUE
189rb_imemo_tmpbuf_auto_free_pointer(void)
190{
191 return rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0);
192}
193
194static inline void *
195RB_IMEMO_TMPBUF_PTR(VALUE v)
196{
197 const struct rb_imemo_tmpbuf_struct *p = (const void *)v;
198 return p->ptr;
199}
200
201static inline void *
202rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
203{
204 return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
205}
206
207static inline VALUE
208rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
209{
210 const void *src;
211 VALUE imemo;
212 rb_imemo_tmpbuf_t *tmpbuf;
213 void *dst;
214 size_t len;
215
216 SafeStringValue(str);
217 /* create tmpbuf to keep the pointer before xmalloc */
218 imemo = rb_imemo_tmpbuf_auto_free_pointer();
219 tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
220 len = RSTRING_LEN(str);
221 src = RSTRING_PTR(str);
222 dst = ruby_xmalloc(len);
223 memcpy(dst, src, len);
224 tmpbuf->ptr = dst;
225 return imemo;
226}
227
228static inline void
229MEMO_V1_SET(struct MEMO *m, VALUE v)
230{
231 RB_OBJ_WRITE(m, &m->v1, v);
232}
233
234static inline void
235MEMO_V2_SET(struct MEMO *m, VALUE v)
236{
237 RB_OBJ_WRITE(m, &m->v2, v);
238}
239
240#endif /* INTERNAL_IMEMO_H */
#define T_IMEMO
Old name of RUBY_T_IMEMO.
Definition value_type.h:67
#define FL_USHIFT
Old name of RUBY_FL_USHIFT.
Definition fl_type.h:69
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition gc.h:619
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
Definition error.h:35
int len
Length of the buffer.
Definition io.h:8
rb_block_call_func * rb_block_call_func_t
Shorthand type that represents an iterator-written-in-C function pointer.
Definition iterator.h:88
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RBASIC(obj)
Convenient casting macro.
Definition rbasic.h:40
#define SafeStringValue(v)
Definition rstring.h:98
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
C99 shim for <stdbool.h>
MEMO.
Definition imemo.h:103
IFUNC (Internal FUNCtion)
Definition imemo.h:83
SVAR (Special VARiable)
Definition imemo.h:52
const VALUE cref_or_me
class reference or rb_method_entry_t
Definition imemo.h:54
THROW_DATA.
Definition imemo.h:61
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
Definition value.h:69
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
@ RUBY_T_MASK
Bitmask of ruby_value_type.
Definition value_type.h:144