Ruby  2.4.2p198(2017-09-14revision59899)
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 
7 static inline void
9 {
10  VM_ASSERT(vm_block_handler_verify(block_handler));
11  th->passed_block_handler = block_handler;
12 }
13 
14 static inline void
16 {
17  VALUE block_handler = rb_vm_frame_block_handler(th->cfp);
18  VM_ASSERT(vm_block_handler_verify(block_handler));
19  vm_passed_block_handler_set(th, block_handler);
21 }
22 
23 #define PASS_PASSED_BLOCK_HANDLER_TH(th) pass_passed_block_handler(th)
24 #define PASS_PASSED_BLOCK_HANDLER() pass_passed_block_handler(GET_THREAD())
25 
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #ifndef EXIT_SUCCESS
30 #define EXIT_SUCCESS 0
31 #endif
32 #ifndef EXIT_FAILURE
33 #define EXIT_FAILURE 1
34 #endif
35 
36 #include <stdio.h>
37 #include <setjmp.h>
38 
39 #ifdef __APPLE__
40 # ifdef HAVE_CRT_EXTERNS_H
41 # include <crt_externs.h>
42 # else
43 # include "missing/crt_externs.h"
44 # endif
45 #endif
46 
47 #ifndef HAVE_STRING_H
48 char *strrchr(const char *, const char);
49 #endif
50 
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 
55 #ifdef HAVE_NET_SOCKET_H
56 #include <net/socket.h>
57 #endif
58 
59 #define ruby_setjmp(env) RUBY_SETJMP(env)
60 #define ruby_longjmp(env,val) RUBY_LONGJMP((env),(val))
61 #ifdef __CYGWIN__
62 # ifndef _setjmp
63 int _setjmp(jmp_buf);
64 # endif
65 # ifndef _longjmp
66 NORETURN(void _longjmp(jmp_buf, int));
67 # endif
68 #endif
69 
70 #include <sys/types.h>
71 #include <signal.h>
72 #include <errno.h>
73 
74 #ifdef HAVE_SYS_SELECT_H
75 #include <sys/select.h>
76 #endif
77 
78 /*
79  Solaris sys/select.h switches select to select_large_fdset to support larger
80  file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment.
81  But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically.
82  So following definition is required to use select_large_fdset.
83 */
84 #ifdef HAVE_SELECT_LARGE_FDSET
85 #define select(n, r, w, e, t) select_large_fdset((n), (r), (w), (e), (t))
86 extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval *);
87 #endif
88 
89 #ifdef HAVE_SYS_PARAM_H
90 #include <sys/param.h>
91 #endif
92 
93 #include <sys/stat.h>
94 
95 #ifdef _MSC_VER
96 #define SAVE_ROOT_JMPBUF_BEFORE_STMT \
97  __try {
98 #define SAVE_ROOT_JMPBUF_AFTER_STMT \
99  } \
100  __except (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW ? \
101  (rb_thread_raised_set(GET_THREAD(), RAISED_STACKOVERFLOW), \
102  raise(SIGSEGV), \
103  EXCEPTION_EXECUTE_HANDLER) : \
104  EXCEPTION_CONTINUE_SEARCH) { \
105  /* never reaches here */ \
106  }
107 #elif defined(__MINGW32__)
108 LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
109 #define SAVE_ROOT_JMPBUF_BEFORE_STMT \
110  do { \
111  PVOID _handler = AddVectoredExceptionHandler(1, rb_w32_stack_overflow_handler);
112 
113 #define SAVE_ROOT_JMPBUF_AFTER_STMT \
114  RemoveVectoredExceptionHandler(_handler); \
115  } while (0);
116 #else
117 #define SAVE_ROOT_JMPBUF_BEFORE_STMT
118 #define SAVE_ROOT_JMPBUF_AFTER_STMT
119 #endif
120 
121 #define SAVE_ROOT_JMPBUF(th, stmt) do \
122  if (ruby_setjmp((th)->root_jmpbuf) == 0) { \
123  SAVE_ROOT_JMPBUF_BEFORE_STMT \
124  stmt; \
125  SAVE_ROOT_JMPBUF_AFTER_STMT \
126  } \
127  else { \
128  rb_fiber_start(); \
129  } while (0)
130 
131 #define TH_PUSH_TAG(th) do { \
132  rb_thread_t * const _th = (th); \
133  struct rb_vm_tag _tag; \
134  _tag.tag = Qundef; \
135  _tag.prev = _th->tag;
136 
137 #define TH_POP_TAG() \
138  _th->tag = _tag.prev; \
139 } while (0)
140 
141 #define TH_TMPPOP_TAG() \
142  _th->tag = _tag.prev
143 
144 #define TH_REPUSH_TAG() (void)(_th->tag = &_tag)
145 
146 #define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
147 #define POP_TAG() TH_POP_TAG()
148 
149 #if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8)
150 # define VAR_FROM_MEMORY(var) __extension__(*(__typeof__(var) volatile *)&(var))
151 # define VAR_INITIALIZED(var) ((var) = VAR_FROM_MEMORY(var))
152 # define VAR_NOCLOBBERED(var) volatile var
153 #else
154 # define VAR_FROM_MEMORY(var) (var)
155 # define VAR_INITIALIZED(var) ((void)&(var))
156 # define VAR_NOCLOBBERED(var) var
157 #endif
158 
159 /* clear th->state, and return the value */
160 static inline int
162 {
163  int state = th->state;
164  th->state = 0;
165  return state;
166 }
167 
168 NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, int));
169 static inline void
171 {
172  th->state = st;
173  ruby_longjmp(th->tag->buf, 1);
174 }
175 
176 /*
177  setjmp() in assignment expression rhs is undefined behavior
178  [ISO/IEC 9899:1999] 7.13.1.1
179 */
180 #define TH_EXEC_TAG() \
181  (ruby_setjmp(_tag.buf) ? rb_threadptr_tag_state(VAR_FROM_MEMORY(_th)) : (TH_REPUSH_TAG(), 0))
182 
183 #define EXEC_TAG() \
184  TH_EXEC_TAG()
185 
186 #define TH_JUMP_TAG(th, st) rb_threadptr_tag_jump(th, st)
187 
188 #define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), (st))
189 
190 #define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
191 
192 /* CREF operators */
193 
194 #define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
195 #define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
196 
197 static inline VALUE
198 CREF_CLASS(const rb_cref_t *cref)
199 {
200  return cref->klass;
201 }
202 
203 static inline rb_cref_t *
204 CREF_NEXT(const rb_cref_t *cref)
205 {
206  return cref->next;
207 }
208 
209 static inline const rb_scope_visibility_t *
211 {
212  return &cref->scope_visi;
213 }
214 
215 static inline VALUE
217 {
218  return cref->refinements;
219 }
220 
221 static inline void
223 {
224  RB_OBJ_WRITE(cref, &cref->refinements, refs);
225 }
226 
227 static inline int
229 {
230  return cref->flags & CREF_FL_PUSHED_BY_EVAL;
231 }
232 
233 static inline void
235 {
236  cref->flags |= CREF_FL_PUSHED_BY_EVAL;
237 }
238 
239 static inline int
241 {
242  return cref->flags & CREF_FL_OMOD_SHARED;
243 }
244 
245 static inline void
247 {
248  cref->flags |= CREF_FL_OMOD_SHARED;
249 }
250 
251 static inline void
253 {
254  cref->flags &= ~CREF_FL_OMOD_SHARED;
255 }
256 
257 void rb_thread_cleanup(void);
259 
260 enum {
264 };
267 #define rb_thread_raised_set(th, f) ((th)->raised_flag |= (f))
268 #define rb_thread_raised_reset(th, f) ((th)->raised_flag &= ~(f))
269 #define rb_thread_raised_p(th, f) (((th)->raised_flag & (f)) != 0)
270 #define rb_thread_raised_clear(th) ((th)->raised_flag = 0)
271 
272 VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
273 VALUE rb_make_exception(int argc, const VALUE *argv);
274 
276 
277 NORETURN(void rb_fiber_start(void));
278 
282 NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
285  VALUE obj, int call_status));
286 
288 rb_cref_t *rb_vm_cref(void);
290 VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
291 void rb_vm_set_progname(VALUE filename);
292 void rb_thread_terminate_all(void);
293 VALUE rb_vm_cbase(void);
294 
295 #ifndef CharNext /* defined as CharNext[AW] on Windows. */
296 # ifdef HAVE_MBLEN
297 # define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
298 # else
299 # define CharNext(p) ((p) + 1)
300 # endif
301 #endif
302 
303 #if defined DOSISH || defined __CYGWIN__
304 static inline void
305 translit_char(char *p, int from, int to)
306 {
307  while (*p) {
308  if ((unsigned char)*p == from)
309  *p = to;
310  p = CharNext(p);
311  }
312 }
313 #endif
314 
315 #endif /* RUBY_EVAL_INTERN_H */
rb_control_frame_t * cfp
Definition: vm_core.h:708
const VALUE * ep
Definition: vm_core.h:636
static void vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
Definition: eval_intern.h:8
NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, int))
VALUE passed_block_handler
Definition: vm_core.h:717
#define ruby_longjmp(env, val)
Definition: eval_intern.h:60
#define CharNext(p)
Definition: eval_intern.h:299
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:197
#define CREF_FL_PUSHED_BY_EVAL
Definition: eval_intern.h:194
static int CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
Definition: eval_intern.h:228
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
Definition: vm.c:2077
#define CREF_FL_OMOD_SHARED
Definition: eval_intern.h:195
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
VALUE rb_make_exception(int argc, const VALUE *argv)
Definition: eval.c:763
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:212
void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
Definition: vm.c:1392
static VALUE CREF_REFINEMENTS(const rb_cref_t *cref)
Definition: eval_intern.h:216
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1649
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1436
void rb_thread_terminate_all(void)
Definition: thread.c:472
static void CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
Definition: eval_intern.h:252
static void pass_passed_block_handler(rb_thread_t *th)
Definition: eval_intern.h:15
const rb_scope_visibility_t scope_visi
Definition: method.h:45
struct rb_cref_struct *const next
Definition: method.h:44
int rb_threadptr_set_raised(rb_thread_t *th)
Definition: thread.c:2180
#define val
static void CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
Definition: eval_intern.h:234
rb_method_visibility_t
Definition: method.h:26
void rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:225
int argc
Definition: ruby.c:183
const VALUE refinements
Definition: method.h:42
void rb_fiber_start(void)
Definition: cont.c:1266
rb_cref_t * rb_vm_cref_replace_with_duplicated_cref(void)
Definition: vm.c:1312
const VALUE klass
Definition: method.h:43
void rb_thread_cleanup(void)
VALUE rb_vm_cbase(void)
Definition: vm.c:1346
void rb_thread_wait_other_threads(void)
static rb_cref_t * CREF_NEXT(const rb_cref_t *cref)
Definition: eval_intern.h:204
#define VM_ASSERT(expr)
Definition: vm_core.h:54
void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status)
Definition: vm_eval.c:776
static VALUE CREF_CLASS(const rb_cref_t *cref)
Definition: eval_intern.h:198
unsigned long ID
Definition: ruby.h:86
unsigned long VALUE
Definition: ruby.h:85
int rb_threadptr_reset_raised(rb_thread_t *th)
Definition: thread.c:2190
static int CREF_OMOD_SHARED(const rb_cref_t *cref)
Definition: eval_intern.h:240
static void rb_threadptr_tag_jump(rb_thread_t *th, int st)
Definition: eval_intern.h:170
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
Definition: vm.c:82
static int rb_threadptr_tag_state(rb_thread_t *th)
Definition: eval_intern.h:161
static int vm_block_handler_verify(VALUE block_handler)
Definition: vm_core.h:1272
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3096
VALUE flags
Definition: method.h:41
rb_jmpbuf_t buf
Definition: vm_core.h:665
struct rb_vm_tag * tag
Definition: vm_core.h:769
static const rb_scope_visibility_t * CREF_SCOPE_VISI(const rb_cref_t *cref)
Definition: eval_intern.h:210
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
Definition: vm.c:1399
static void CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
Definition: eval_intern.h:222
void rb_vm_jump_tag_but_local_jump(int state)
Definition: vm.c:1431
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1299
static void VM_ENV_FLAGS_SET(const VALUE *ep, VALUE flag)
Definition: vm_core.h:1001
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1437
char * strrchr(const char *, const char)
static void CREF_OMOD_SHARED_SET(rb_cref_t *cref)
Definition: eval_intern.h:246
char ** argv
Definition: ruby.c:184