Ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a25176072e02db9254f0e0c84c805cd)
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);
12}
13
14static inline void
15pass_passed_block_handler(rb_execution_context_t *ec)
16{
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
47char *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
65NORETURN(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
137#define EC_POP_TAG() \
138 _ec->tag = _tag.prev; \
139} while (0)
140
141#define EC_TMPPOP_TAG() \
142 _ec->tag = _tag.prev
143
144#define EC_REPUSH_TAG() (void)(_ec->tag = &_tag)
145
146#if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8) || __clang__
147/* This macro prevents GCC 4.6--4.8 from emitting maybe-uninitialized warnings.
148 * This macro also prevents Clang from dumping core in EC_EXEC_TAG().
149 * (I confirmed Clang 4.0.1 and 5.0.0.)
150 */
151# define VAR_FROM_MEMORY(var) __extension__(*(__typeof__(var) volatile *)&(var))
152# define VAR_INITIALIZED(var) ((var) = VAR_FROM_MEMORY(var))
153# define VAR_NOCLOBBERED(var) volatile var
154#else
155# define VAR_FROM_MEMORY(var) (var)
156# define VAR_INITIALIZED(var) ((void)&(var))
157# define VAR_NOCLOBBERED(var) var
158#endif
159
160/* clear ec->tag->state, and return the value */
161static inline int
162rb_ec_tag_state(const rb_execution_context_t *ec)
163{
164 enum ruby_tag_type state = ec->tag->state;
165 ec->tag->state = TAG_NONE;
166 return state;
167}
168
169NORETURN(static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st));
170static inline void
171rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
172{
173 ec->tag->state = st;
174 ruby_longjmp(ec->tag->buf, 1);
175}
176
177/*
178 setjmp() in assignment expression rhs is undefined behavior
179 [ISO/IEC 9899:1999] 7.13.1.1
180*/
181#define EC_EXEC_TAG() \
182 (ruby_setjmp(_tag.buf) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
183
184#define EC_JUMP_TAG(ec, st) rb_ec_tag_jump(ec, st)
185
186#define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
187
188/* CREF operators */
189
190#define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
191#define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
192
193static inline VALUE
194CREF_CLASS(const rb_cref_t *cref)
195{
196 return cref->klass;
197}
198
199static inline rb_cref_t *
200CREF_NEXT(const rb_cref_t *cref)
201{
202 return cref->next;
203}
204
205static inline const rb_scope_visibility_t *
206CREF_SCOPE_VISI(const rb_cref_t *cref)
207{
208 return &cref->scope_visi;
209}
210
211static inline VALUE
212CREF_REFINEMENTS(const rb_cref_t *cref)
213{
214 return cref->refinements;
215}
216
217static inline void
218CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
219{
220 RB_OBJ_WRITE(cref, &cref->refinements, refs);
221}
222
223static inline int
224CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
225{
226 return cref->flags & CREF_FL_PUSHED_BY_EVAL;
227}
228
229static inline void
230CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
231{
233}
234
235static inline int
236CREF_OMOD_SHARED(const rb_cref_t *cref)
237{
238 return cref->flags & CREF_FL_OMOD_SHARED;
239}
240
241static inline void
242CREF_OMOD_SHARED_SET(rb_cref_t *cref)
243{
244 cref->flags |= CREF_FL_OMOD_SHARED;
245}
246
247static inline void
248CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
249{
250 cref->flags &= ~CREF_FL_OMOD_SHARED;
251}
252
253enum {
258#define rb_ec_raised_set(ec, f) ((ec)->raised_flag |= (f))
259#define rb_ec_raised_reset(ec, f) ((ec)->raised_flag &= ~(f))
260#define rb_ec_raised_p(ec, f) (((ec)->raised_flag & (f)) != 0)
261#define rb_ec_raised_clear(ec) ((ec)->raised_flag = 0)
265
266VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
268
270
272
276NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
278
280rb_cref_t *rb_vm_cref(void);
283void rb_vm_set_progname(VALUE filename);
284void rb_thread_terminate_all(void);
285VALUE rb_vm_cbase(void);
286
287/* vm_backtrace.c */
289VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n);
291
292#ifndef CharNext /* defined as CharNext[AW] on Windows. */
293# ifdef HAVE_MBLEN
294# define CharNext(p) rb_char_next(p)
295static inline const char *
296rb_char_next(const char *p)
297{
298 if (p) {
299 int len = mblen(p, RUBY_MBCHAR_MAXSIZE);
300 p += len > 0 ? len : 1;
301 }
302 return p;
303}
304# else
305# define CharNext(p) ((p) + 1)
306# endif
307#endif
308
309#if defined DOSISH || defined __CYGWIN__
310static inline void
311translit_char(char *p, int from, int to)
312{
313 while (*p) {
314 if ((unsigned char)*p == from)
315 *p = to;
316 p = CharNext(p);
317 }
318}
319#endif
320
321#endif /* RUBY_EVAL_INTERN_H */
void rb_fiber_start(void)
Definition: cont.c:1804
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:383
void rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:411
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:398
int rb_ec_set_raised(rb_execution_context_t *ec)
Definition: thread.c:2343
#define CharNext(p)
Definition: eval_intern.h:305
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
Definition: vm.c:2212
#define ruby_longjmp(env, val)
Definition: eval_intern.h:59
VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec)
Definition: vm_backtrace.c:557
VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n)
Definition: vm_backtrace.c:714
@ RAISED_STACKOVERFLOW
Definition: eval_intern.h:255
@ RAISED_NOMEMORY
Definition: eval_intern.h:256
@ RAISED_EXCEPTION
Definition: eval_intern.h:254
#define CREF_FL_PUSHED_BY_EVAL
Definition: eval_intern.h:190
int rb_ec_stack_check(rb_execution_context_t *ec)
Definition: gc.c:4681
NORETURN(static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st))
char * strrchr(const char *, const char)
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3291
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1670
void rb_thread_terminate_all(void)
Definition: thread.c:554
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
Definition: vm.c:1478
VALUE rb_vm_cbase(void)
Definition: vm.c:1425
#define CREF_FL_OMOD_SHARED
Definition: eval_intern.h:191
int rb_ec_reset_raised(rb_execution_context_t *ec)
Definition: thread.c:2353
rb_cref_t * rb_vm_cref_replace_with_duplicated_cref(void)
Definition: vm.c:1391
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1384
VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n)
Definition: vm_backtrace.c:720
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:851
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1778
int _setjmp(jmp_buf)
#define TAG_NONE
#define RUBY_MBCHAR_MAXSIZE
rb_control_frame_t struct rb_calling_info const struct rb_call_info VALUE block_handler
enum ruby_tag_type st
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
const char size_t n
unsigned long VALUE
void _longjmp(jmp_buf, int) __attribute__((__noreturn__))
__inline__ const void *__restrict__ size_t len
#define RB_OBJ_WRITE(a, slot, b)
const VALUE * argv
unsigned long ID
int mblen(const char *, size_t)
long jmp_buf[32]
CREF (Class REFerence)
const rb_scope_visibility_t scope_visi
struct rb_cref_struct * next
enum ruby_tag_type state
void rb_vm_jump_tag_but_local_jump(int state)
Definition: vm.c:1510
MJIT_FUNC_EXPORTED void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
Definition: vm.c:1471