Ruby: eval_intern.h Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

eval_intern.h
Go to the documentation of this file.
1#ifndef RUBY_EVAL_INTERN_H
2#define RUBY_EVAL_INTERN_H
3
4#include "ruby/ruby.h"
5#include "vm_core.h"
6
7static inline void
8vm_passed_block_handler_set(rb_execution_context_t *ec, VALUE block_handler)
9{
10 vm_block_handler_verify(block_handler);
11 ec->passed_block_handler = block_handler;
12}
13
14static inline void
15pass_passed_block_handler(rb_execution_context_t *ec)
16{
17 VALUE block_handler = rb_vm_frame_block_handler(ec->cfp);
18 vm_passed_block_handler_set(ec, block_handler);
19 VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_PASSED);
20}
21
22#define PASS_PASSED_BLOCK_HANDLER_EC(ec) pass_passed_block_handler(ec)
23#define PASS_PASSED_BLOCK_HANDLER() pass_passed_block_handler(GET_EC())
24
25#ifdef HAVE_STDLIB_H
26#include <stdlib.h>
27#endif
28#ifndef EXIT_SUCCESS
29#define EXIT_SUCCESS 0
30#endif
31#ifndef EXIT_FAILURE
32#define EXIT_FAILURE 1
33#endif
34
35#include <stdio.h>
36#include <setjmp.h>
37
38#ifdef __APPLE__
39# ifdef HAVE_CRT_EXTERNS_H
40# include <crt_externs.h>
41# else
42# include "missing/crt_externs.h"
43# endif
44#endif
45
46#ifndef HAVE_STRING_H
47 char *strrchr(const char *, const char);
48#endif
49
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif
53
54#ifdef HAVE_NET_SOCKET_H
55#include <net/socket.h>
56#endif
57
58#define ruby_setjmp(env) RUBY_SETJMP(env)
59#define ruby_longjmp(env,val) RUBY_LONGJMP((env),(val))
60#ifdef __CYGWIN__
61# ifndef _setjmp
62int _setjmp(jmp_buf);
63# endif
64# ifndef _longjmp
65 NORETURN(void _longjmp(jmp_buf, int));
66# endif
67#endif
68
69#include <sys/types.h>
70#include <signal.h>
71#include <errno.h>
72
73#ifdef HAVE_SYS_SELECT_H
74#include <sys/select.h>
75#endif
76
77/*
78 Solaris sys/select.h switches select to select_large_fdset to support larger
79 file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment.
80 But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically.
81 So following definition is required to use select_large_fdset.
82*/
83#ifdef HAVE_SELECT_LARGE_FDSET
84#define select(n, r, w, e, t) select_large_fdset((n), (r), (w), (e), (t))
85extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval *);
86#endif
87
88#ifdef HAVE_SYS_PARAM_H
89#include <sys/param.h>
90#endif
91
92#include <sys/stat.h>
93
94#ifdef _MSC_VER
95#define SAVE_ROOT_JMPBUF_BEFORE_STMT \
96 __try {
97#define SAVE_ROOT_JMPBUF_AFTER_STMT \
98 } \
99 __except (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW ? \
100 (rb_ec_raised_set(GET_EC(), RAISED_STACKOVERFLOW), \
101 raise(SIGSEGV), \
102 EXCEPTION_EXECUTE_HANDLER) : \
103 EXCEPTION_CONTINUE_SEARCH) { \
104 /* never reaches here */ \
105 }
106#elif defined(__MINGW32__)
107LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
108#define SAVE_ROOT_JMPBUF_BEFORE_STMT \
109 do { \
110 PVOID _handler = AddVectoredExceptionHandler(1, rb_w32_stack_overflow_handler);
111
112#define SAVE_ROOT_JMPBUF_AFTER_STMT \
113 RemoveVectoredExceptionHandler(_handler); \
114 } while (0);
115#else
116#define SAVE_ROOT_JMPBUF_BEFORE_STMT
117#define SAVE_ROOT_JMPBUF_AFTER_STMT
118#endif
119
120#define SAVE_ROOT_JMPBUF(th, stmt) do \
121 if (ruby_setjmp((th)->root_jmpbuf) == 0) { \
122 SAVE_ROOT_JMPBUF_BEFORE_STMT \
123 stmt; \
124 SAVE_ROOT_JMPBUF_AFTER_STMT \
125 } \
126 else { \
127 rb_fiber_start(); \
128 } while (0)
129
130#define EC_PUSH_TAG(ec) do { \
131 rb_execution_context_t * const _ec = (ec); \
132 struct rb_vm_tag _tag; \
133 _tag.state = TAG_NONE; \
134 _tag.tag = Qundef; \
135 _tag.prev = _ec->tag; \
136 _tag.lock_rec = rb_ec_vm_lock_rec(_ec); \
137
138#define EC_POP_TAG() \
139 _ec->tag = _tag.prev; \
140} while (0)
141
142#define EC_TMPPOP_TAG() \
143 _ec->tag = _tag.prev
144
145#define EC_REPUSH_TAG() (void)(_ec->tag = &_tag)
146
147#if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8) || __clang__
148/* This macro prevents GCC 4.6--4.8 from emitting maybe-uninitialized warnings.
149 * This macro also prevents Clang from dumping core in EC_EXEC_TAG().
150 * (I confirmed Clang 4.0.1 and 5.0.0.)
151 */
152# define VAR_FROM_MEMORY(var) __extension__(*(__typeof__(var) volatile *)&(var))
153# define VAR_INITIALIZED(var) ((var) = VAR_FROM_MEMORY(var))
154# define VAR_NOCLOBBERED(var) volatile var
155#else
156# define VAR_FROM_MEMORY(var) (var)
157# define VAR_INITIALIZED(var) ((void)&(var))
158# define VAR_NOCLOBBERED(var) var
159#endif
160
161static inline void
162rb_ec_vm_lock_rec_check(const rb_execution_context_t *ec, unsigned int recorded_lock_rec)
163{
164 unsigned int current_lock_rec = rb_ec_vm_lock_rec(ec);
165 if (current_lock_rec != recorded_lock_rec) {
166 rb_ec_vm_lock_rec_release(ec, recorded_lock_rec, current_lock_rec);
167 }
168}
169
170/* clear ec->tag->state, and return the value */
171static inline int
172rb_ec_tag_state(const rb_execution_context_t *ec)
173{
174 struct rb_vm_tag *tag = ec->tag;
175 enum ruby_tag_type state = tag->state;
176 tag->state = TAG_NONE;
177 rb_ec_vm_lock_rec_check(ec, tag->lock_rec);
178 return state;
179}
180
181 NORETURN(static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st));
182static inline void
183rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
184{
185 ec->tag->state = st;
186 ruby_longjmp(ec->tag->buf, 1);
187}
188
189/*
190 setjmp() in assignment expression rhs is undefined behavior
191 [ISO/IEC 9899:1999] 7.13.1.1
192*/
193#define EC_EXEC_TAG() \
194 (ruby_setjmp(_tag.buf) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
195
196#define EC_JUMP_TAG(ec, st) rb_ec_tag_jump(ec, st)
197
198#define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
199
200/* CREF operators */
201
202#define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
203#define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
204
205static inline VALUE
206CREF_CLASS(const rb_cref_t *cref)
207{
208 return cref->klass;
209}
210
211static inline rb_cref_t *
212CREF_NEXT(const rb_cref_t *cref)
213{
214 return cref->next;
215}
216
217static inline const rb_scope_visibility_t *
218CREF_SCOPE_VISI(const rb_cref_t *cref)
219{
220 return &cref->scope_visi;
221}
222
223static inline VALUE
224CREF_REFINEMENTS(const rb_cref_t *cref)
225{
226 return cref->refinements;
227}
228
229static inline void
230CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
231{
232 RB_OBJ_WRITE(cref, &cref->refinements, refs);
233}
234
235static inline int
236CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
237{
238 return cref->flags & CREF_FL_PUSHED_BY_EVAL;
239}
240
241static inline void
242CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
243{
244 cref->flags |= CREF_FL_PUSHED_BY_EVAL;
245}
246
247static inline int
248CREF_OMOD_SHARED(const rb_cref_t *cref)
249{
250 return cref->flags & CREF_FL_OMOD_SHARED;
251}
252
253static inline void
254CREF_OMOD_SHARED_SET(rb_cref_t *cref)
255{
256 cref->flags |= CREF_FL_OMOD_SHARED;
257}
258
259static inline void
260CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
261{
262 cref->flags &= ~CREF_FL_OMOD_SHARED;
263}
264
265enum {
266 RAISED_EXCEPTION = 1,
267 RAISED_STACKOVERFLOW = 2,
268 RAISED_NOMEMORY = 4
269};
270#define rb_ec_raised_set(ec, f) ((ec)->raised_flag |= (f))
271#define rb_ec_raised_reset(ec, f) ((ec)->raised_flag &= ~(f))
272#define rb_ec_raised_p(ec, f) (((ec)->raised_flag & (f)) != 0)
273#define rb_ec_raised_clear(ec) ((ec)->raised_flag = 0)
274int rb_ec_set_raised(rb_execution_context_t *ec);
275int rb_ec_reset_raised(rb_execution_context_t *ec);
276int rb_ec_stack_check(rb_execution_context_t *ec);
277
278 VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
279 VALUE rb_make_exception(int argc, const VALUE *argv);
280
281 NORETURN(void rb_method_name_error(VALUE, VALUE));
282
283 NORETURN(void rb_fiber_start(void));
284
285 NORETURN(void rb_print_undef(VALUE, ID, rb_method_visibility_t));
286 NORETURN(void rb_print_undef_str(VALUE, VALUE));
287 NORETURN(void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t));
288 NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
289 NORETURN(void rb_vm_jump_tag_but_local_jump(int));
290
291 VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
292 rb_cref_t *rb_vm_cref(void);
293 rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
294 VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
295void rb_vm_set_progname(VALUE filename);
296 VALUE rb_vm_cbase(void);
297
298/* vm_backtrace.c */
299 VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec);
300 VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n);
301 VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
302
303#ifndef CharNext /* defined as CharNext[AW] on Windows. */
304# ifdef HAVE_MBLEN
305# define CharNext(p) rb_char_next(p)
306static inline const char *
307rb_char_next(const char *p)
308{
309 if (p) {
310 int len = mblen(p, RUBY_MBCHAR_MAXSIZE);
311 p += len > 0 ? len : 1;
312 }
313 return p;
314}
315# else
316# define CharNext(p) ((p) + 1)
317# endif
318#endif
319
320#if defined DOSISH || defined __CYGWIN__
321static inline void
322translit_char(char *p, int from, int to)
323{
324 while (*p) {
325 if ((unsigned char)*p == from)
326 *p = to;
327 p = CharNext(p);
328 }
329}
330#endif
331
332#endif /* RUBY_EVAL_INTERN_H */
NORETURN
#define NORETURN(x)
Definition: attributes.h:152
crt_externs.h
RUBY_MBCHAR_MAXSIZE
#define RUBY_MBCHAR_MAXSIZE
Definition: defines.h:96
len
uint8_t len
Definition: escape.c:17
rb_ec_set_raised
int rb_ec_set_raised(rb_execution_context_t *ec)
Definition: thread.c:2587
CharNext
#define CharNext(p)
Definition: eval_intern.h:316
rb_vm_call_cfunc
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
Definition: vm.c:2452
ruby_longjmp
#define ruby_longjmp(env, val)
Definition: eval_intern.h:59
rb_print_undef_str
void rb_print_undef_str(VALUE, VALUE)
Definition: eval_error.c:412
rb_ec_backtrace_object
VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec)
Definition: vm_backtrace.c:770
rb_ec_backtrace_str_ary
VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n)
Definition: vm_backtrace.c:892
CREF_FL_PUSHED_BY_EVAL
#define CREF_FL_PUSHED_BY_EVAL
Definition: eval_intern.h:202
rb_method_name_error
void rb_method_name_error(VALUE, VALUE)
Definition: proc.c:1909
rb_ec_stack_check
int rb_ec_stack_check(rb_execution_context_t *ec)
Definition: gc.c:5546
rb_vm_localjump_error
void rb_vm_localjump_error(const char *, VALUE, int)
Definition: vm.c:1711
strrchr
char * strrchr(const char *, const char)
rb_print_inaccessible
void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t)
Definition: eval_error.c:425
rb_vm_set_progname
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3690
rb_print_undef
void rb_print_undef(VALUE, ID, rb_method_visibility_t)
Definition: eval_error.c:397
rb_f_eval
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1778
rb_vm_jump_tag_but_local_jump
void rb_vm_jump_tag_but_local_jump(int)
Definition: vm.c:1750
rb_vm_make_jump_tag_but_local_jump
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
Definition: vm.c:1718
rb_vm_cbase
VALUE rb_vm_cbase(void)
Definition: vm.c:1665
CREF_FL_OMOD_SHARED
#define CREF_FL_OMOD_SHARED
Definition: eval_intern.h:203
rb_ec_reset_raised
int rb_ec_reset_raised(rb_execution_context_t *ec)
Definition: thread.c:2597
rb_vm_cref_replace_with_duplicated_cref
rb_cref_t * rb_vm_cref_replace_with_duplicated_cref(void)
Definition: vm.c:1631
rb_vm_cref
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1624
RAISED_STACKOVERFLOW
@ RAISED_STACKOVERFLOW
Definition: eval_intern.h:267
RAISED_NOMEMORY
@ RAISED_NOMEMORY
Definition: eval_intern.h:268
RAISED_EXCEPTION
@ RAISED_EXCEPTION
Definition: eval_intern.h:266
rb_fiber_start
void rb_fiber_start(void)
Definition: cont.c:2014
rb_make_exception
VALUE rb_make_exception(int argc, const VALUE *argv)
Make an Exception object from the list of arguments in a manner similar to Kernel#raise.
Definition: eval.c:888
rb_ec_backtrace_location_ary
VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal)
Definition: vm_backtrace.c:898
filename
const char * filename
Definition: ioapi.h:137
rb_method_visibility_t
rb_method_visibility_t
Definition: method.h:29
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:107
ruby.h
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
rb_control_frame_struct::ep
const VALUE * ep
Definition: vm_core.h:774
rb_cref_struct
CREF (Class REFerence)
Definition: method.h:44
rb_cref_struct::scope_visi
const rb_scope_visibility_t scope_visi
Definition: method.h:49
rb_cref_struct::flags
VALUE flags
Definition: method.h:45
rb_cref_struct::refinements
VALUE refinements
Definition: method.h:46
rb_cref_struct::next
struct rb_cref_struct * next
Definition: method.h:48
rb_cref_struct::klass
VALUE klass
Definition: method.h:47
rb_execution_context_struct
Definition: vm_core.h:854
rb_execution_context_struct::passed_block_handler
VALUE passed_block_handler
Definition: vm_core.h:890
rb_execution_context_struct::cfp
rb_control_frame_t * cfp
Definition: vm_core.h:858
rb_execution_context_struct::tag
struct rb_vm_tag * tag
Definition: vm_core.h:860
rb_scope_visi_struct
Definition: method.h:38
rb_vm_tag
Definition: vm_core.h:808
rb_vm_tag::buf
rb_jmpbuf_t buf
Definition: vm_core.h:811
rb_vm_tag::state
enum ruby_tag_type state
Definition: vm_core.h:813
rb_vm_tag::tag
VALUE tag
Definition: vm_core.h:809
state
Definition: blast.c:41
timeval
Definition: missing.h:51
VALUE
unsigned long VALUE
Definition: value.h:38
ID
unsigned long ID
Definition: value.h:39
rb_vm_frame_block_handler
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
Definition: vm.c:126
vm_core.h
TAG_NONE
#define TAG_NONE
Definition: vm_core.h:198
ruby_tag_type
ruby_tag_type
Definition: vm_core.h:185
VM_FRAME_FLAG_PASSED
@ VM_FRAME_FLAG_PASSED
Definition: vm_core.h:1197
rb_ec_vm_lock_rec_release
void rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec, unsigned int recorded_lock_rec, unsigned int current_lock_rec)
Definition: vm_sync.c:282