Ruby  2.5.0dev(2017-10-22revision60238)
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
8 vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
9 {
10  vm_block_handler_verify(block_handler);
11  th->passed_block_handler = block_handler;
12 }
13 
14 static inline void
15 pass_passed_block_handler(rb_thread_t *th)
16 {
17  VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
18  vm_block_handler_verify(block_handler);
19  vm_passed_block_handler_set(th, block_handler);
20  VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_PASSED);
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.state = TAG_NONE; \
135  _tag.tag = Qundef; \
136  _tag.prev = _th->ec.tag;
137 
138 #define TH_POP_TAG() \
139  _th->ec.tag = _tag.prev; \
140 } while (0)
141 
142 #define TH_TMPPOP_TAG() \
143  _th->ec.tag = _tag.prev
144 
145 #define TH_REPUSH_TAG() (void)(_th->ec.tag = &_tag)
146 
147 #define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
148 #define POP_TAG() TH_POP_TAG()
149 
150 #if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8)
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 #if defined(USE_UNALIGNED_MEMBER_ACCESS) && USE_UNALIGNED_MEMBER_ACCESS && \
161  defined(__clang__)
162 # define UNALIGNED_MEMBER_ACCESS(expr) __extension__({ \
163  _Pragma("GCC diagnostic push"); \
164  _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); \
165  typeof(expr) unaligned_member_access_result = (expr); \
166  _Pragma("GCC diagnostic pop"); \
167  unaligned_member_access_result; \
168 })
169 #else
170 # define UNALIGNED_MEMBER_ACCESS(expr) expr
171 #endif
172 #define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
173 
174 #undef RB_OBJ_WRITE
175 #define RB_OBJ_WRITE(a, slot, b) UNALIGNED_MEMBER_ACCESS(rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__))
176 
177 /* clear th->ec.tag->state, and return the value */
178 static inline int
179 rb_threadptr_tag_state(rb_thread_t *th)
180 {
181  enum ruby_tag_type state = th->ec.tag->state;
182  th->ec.tag->state = TAG_NONE;
183  return state;
184 }
185 
186 NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, enum ruby_tag_type st));
187 static inline void
188 rb_threadptr_tag_jump(rb_thread_t *th, enum ruby_tag_type st)
189 {
190  th->ec.tag->state = st;
191  ruby_longjmp(th->ec.tag->buf, 1);
192 }
193 
194 /*
195  setjmp() in assignment expression rhs is undefined behavior
196  [ISO/IEC 9899:1999] 7.13.1.1
197 */
198 #define TH_EXEC_TAG() \
199  (ruby_setjmp(_tag.buf) ? rb_threadptr_tag_state(VAR_FROM_MEMORY(_th)) : (TH_REPUSH_TAG(), 0))
200 
201 #define EXEC_TAG() \
202  TH_EXEC_TAG()
203 
204 #define TH_JUMP_TAG(th, st) rb_threadptr_tag_jump(th, st)
205 
206 #define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), (st))
207 
208 #define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
209 
210 /* CREF operators */
211 
212 #define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
213 #define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
214 
215 static inline VALUE
216 CREF_CLASS(const rb_cref_t *cref)
217 {
218  return cref->klass;
219 }
220 
221 static inline rb_cref_t *
222 CREF_NEXT(const rb_cref_t *cref)
223 {
224  return cref->next;
225 }
226 
227 static inline const rb_scope_visibility_t *
228 CREF_SCOPE_VISI(const rb_cref_t *cref)
229 {
230  return &cref->scope_visi;
231 }
232 
233 static inline VALUE
234 CREF_REFINEMENTS(const rb_cref_t *cref)
235 {
236  return cref->refinements;
237 }
238 
239 static inline void
240 CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
241 {
242  RB_OBJ_WRITE(cref, &cref->refinements, refs);
243 }
244 
245 static inline int
246 CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
247 {
248  return cref->flags & CREF_FL_PUSHED_BY_EVAL;
249 }
250 
251 static inline void
252 CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
253 {
254  cref->flags |= CREF_FL_PUSHED_BY_EVAL;
255 }
256 
257 static inline int
258 CREF_OMOD_SHARED(const rb_cref_t *cref)
259 {
260  return cref->flags & CREF_FL_OMOD_SHARED;
261 }
262 
263 static inline void
264 CREF_OMOD_SHARED_SET(rb_cref_t *cref)
265 {
266  cref->flags |= CREF_FL_OMOD_SHARED;
267 }
268 
269 static inline void
270 CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
271 {
272  cref->flags &= ~CREF_FL_OMOD_SHARED;
273 }
274 
275 void rb_thread_cleanup(void);
277 
278 enum {
282 };
285 #define rb_thread_raised_set(th, f) ((th)->ec.raised_flag |= (f))
286 #define rb_thread_raised_reset(th, f) ((th)->ec.raised_flag &= ~(f))
287 #define rb_thread_raised_p(th, f) (((th)->ec.raised_flag & (f)) != 0)
288 #define rb_thread_raised_clear(th) ((th)->ec.raised_flag = 0)
290 
291 VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
292 VALUE rb_make_exception(int argc, const VALUE *argv);
293 
295 
296 NORETURN(void rb_fiber_start(void));
297 
301 NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
302 #if 0
303 NORETURN(void rb_vm_jump_tag_but_local_jump(int));
304 #endif
306  VALUE obj, int call_status));
307 
309 rb_cref_t *rb_vm_cref(void);
311 VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
312 void rb_vm_set_progname(VALUE filename);
313 void rb_thread_terminate_all(void);
314 VALUE rb_vm_cbase(void);
315 
316 /* vm_backtrace.c */
318 VALUE rb_threadptr_backtrace_str_ary(rb_thread_t *th, long lev, long n);
320 
321 #ifndef CharNext /* defined as CharNext[AW] on Windows. */
322 # ifdef HAVE_MBLEN
323 # define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
324 # else
325 # define CharNext(p) ((p) + 1)
326 # endif
327 #endif
328 
329 #if defined DOSISH || defined __CYGWIN__
330 static inline void
331 translit_char(char *p, int from, int to)
332 {
333  while (*p) {
334  if ((unsigned char)*p == from)
335  *p = to;
336  p = CharNext(p);
337  }
338 }
339 #endif
340 
341 #endif /* RUBY_EVAL_INTERN_H */
const VALUE * ep
Definition: vm_core.h:667
VALUE passed_block_handler
Definition: vm_core.h:795
#define ruby_longjmp(env, val)
Definition: eval_intern.h:60
ruby_tag_type
Definition: vm_core.h:151
#define CharNext(p)
Definition: eval_intern.h:325
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:216
#define CREF_FL_PUSHED_BY_EVAL
Definition: eval_intern.h:212
VALUE rb_threadptr_backtrace_object(rb_thread_t *th)
Definition: vm_backtrace.c:515
enum ruby_tag_type state
Definition: vm_core.h:701
rb_control_frame_t * cfp
Definition: vm_core.h:744
#define TAG_NONE
Definition: vm_core.h:164
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
Definition: vm.c:2100
#define CREF_FL_OMOD_SHARED
Definition: eval_intern.h:213
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:231
void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
Definition: vm.c:1414
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1642
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1385
VALUE rb_threadptr_backtrace_str_ary(rb_thread_t *th, long lev, long n)
Definition: vm_backtrace.c:653
void rb_thread_terminate_all(void)
Definition: thread.c:479
const rb_scope_visibility_t scope_visi
Definition: method.h:46
struct rb_cref_struct *const next
Definition: method.h:45
int rb_threadptr_set_raised(rb_thread_t *th)
Definition: thread.c:2173
#define val
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:244
int argc
Definition: ruby.c:187
const VALUE refinements
Definition: method.h:43
void rb_fiber_start(void)
Definition: cont.c:1325
rb_cref_t * rb_vm_cref_replace_with_duplicated_cref(void)
Definition: vm.c:1334
const VALUE klass
Definition: method.h:44
void rb_thread_cleanup(void)
VALUE rb_vm_cbase(void)
Definition: vm.c:1368
void rb_thread_wait_other_threads(void)
void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status)
Definition: vm_eval.c:728
NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, enum ruby_tag_type st))
unsigned long ID
Definition: ruby.h:86
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:788
unsigned long VALUE
Definition: ruby.h:85
int rb_threadptr_reset_raised(rb_thread_t *th)
Definition: thread.c:2183
CREF (Class REFerence)
Definition: method.h:41
#define RB_OBJ_WRITE(a, slot, b)
Definition: eval_intern.h:175
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
Definition: vm.c:82
VALUE rb_threadptr_backtrace_location_ary(rb_thread_t *th, long lev, long n)
Definition: vm_backtrace.c:659
struct rb_vm_tag * tag
Definition: vm_core.h:746
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3110
VALUE flags
Definition: method.h:42
rb_execution_context_t ec
Definition: vm_core.h:790
rb_jmpbuf_t buf
Definition: vm_core.h:699
int rb_threadptr_stack_check(rb_thread_t *th)
Definition: gc.c:4047
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
Definition: vm.c:1421
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1321
char * strrchr(const char *, const char)
char ** argv
Definition: ruby.c:188