Ruby  2.0.0p247(2013-06-27revision41674)
eval_intern.h
Go to the documentation of this file.
00001 #ifndef RUBY_EVAL_INTERN_H
00002 #define RUBY_EVAL_INTERN_H
00003 
00004 #include "ruby/ruby.h"
00005 #include "vm_core.h"
00006 
00007 #define PASS_PASSED_BLOCK_TH(th) do { \
00008     (th)->passed_block = rb_vm_control_frame_block_ptr(th->cfp); \
00009     (th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \
00010 } while (0)
00011 
00012 #define PASS_PASSED_BLOCK() do { \
00013     rb_thread_t * const __th__ = GET_THREAD(); \
00014     PASS_PASSED_BLOCK_TH(__th__); \
00015 } while (0)
00016 
00017 #ifdef HAVE_STDLIB_H
00018 #include <stdlib.h>
00019 #endif
00020 #ifndef EXIT_SUCCESS
00021 #define EXIT_SUCCESS 0
00022 #endif
00023 #ifndef EXIT_FAILURE
00024 #define EXIT_FAILURE 1
00025 #endif
00026 
00027 #include <stdio.h>
00028 #include <setjmp.h>
00029 
00030 #ifdef __APPLE__
00031 # ifdef HAVE_CRT_EXTERNS_H
00032 #  include <crt_externs.h>
00033 # else
00034 #  include "missing/crt_externs.h"
00035 # endif
00036 #endif
00037 
00038 #ifndef HAVE_STRING_H
00039 char *strrchr(const char *, const char);
00040 #endif
00041 
00042 #ifdef HAVE_UNISTD_H
00043 #include <unistd.h>
00044 #endif
00045 
00046 #ifdef HAVE_NET_SOCKET_H
00047 #include <net/socket.h>
00048 #endif
00049 
00050 #define ruby_setjmp(env) RUBY_SETJMP(env)
00051 #define ruby_longjmp(env,val) RUBY_LONGJMP((env),(val))
00052 #ifdef __CYGWIN__
00053 # ifndef _setjmp
00054 int _setjmp(jmp_buf);
00055 # endif
00056 # ifndef _longjmp
00057 NORETURN(void _longjmp(jmp_buf, int));
00058 # endif
00059 #endif
00060 
00061 #include <sys/types.h>
00062 #include <signal.h>
00063 #include <errno.h>
00064 
00065 #ifdef HAVE_SYS_SELECT_H
00066 #include <sys/select.h>
00067 #endif
00068 
00069 /*
00070   Solaris sys/select.h switches select to select_large_fdset to support larger
00071   file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment.
00072   But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically.
00073   So following definition is required to use select_large_fdset.
00074 */
00075 #ifdef HAVE_SELECT_LARGE_FDSET
00076 #define select(n, r, w, e, t) select_large_fdset((n), (r), (w), (e), (t))
00077 extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval *);
00078 #endif
00079 
00080 #ifdef HAVE_SYS_PARAM_H
00081 #include <sys/param.h>
00082 #endif
00083 
00084 #include <sys/stat.h>
00085 
00086 #define SAVE_ROOT_JMPBUF(th, stmt) do \
00087   if (ruby_setjmp((th)->root_jmpbuf) == 0) { \
00088       stmt; \
00089   } \
00090   else { \
00091       rb_fiber_start(); \
00092   } while (0)
00093 
00094 #define TH_PUSH_TAG(th) do { \
00095   rb_thread_t * const _th = (th); \
00096   struct rb_vm_tag _tag; \
00097   _tag.tag = 0; \
00098   _tag.prev = _th->tag; \
00099   _th->tag = &_tag;
00100 
00101 #define TH_POP_TAG() \
00102   _th->tag = _tag.prev; \
00103 } while (0)
00104 
00105 #define TH_POP_TAG2() \
00106   _th->tag = _tag.prev
00107 
00108 #define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
00109 #define POP_TAG()      TH_POP_TAG()
00110 
00111 #define TH_EXEC_TAG() ruby_setjmp(_th->tag->buf)
00112 
00113 #define EXEC_TAG() \
00114   TH_EXEC_TAG()
00115 
00116 #define TH_JUMP_TAG(th, st) do { \
00117   ruby_longjmp((th)->tag->buf,(st)); \
00118 } while (0)
00119 
00120 #define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), (st))
00121 
00122 #define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
00123 
00124 enum ruby_tag_type {
00125     RUBY_TAG_RETURN     = 0x1,
00126     RUBY_TAG_BREAK      = 0x2,
00127     RUBY_TAG_NEXT       = 0x3,
00128     RUBY_TAG_RETRY      = 0x4,
00129     RUBY_TAG_REDO       = 0x5,
00130     RUBY_TAG_RAISE      = 0x6,
00131     RUBY_TAG_THROW      = 0x7,
00132     RUBY_TAG_FATAL      = 0x8,
00133     RUBY_TAG_MASK       = 0xf
00134 };
00135 #define TAG_RETURN      RUBY_TAG_RETURN
00136 #define TAG_BREAK       RUBY_TAG_BREAK
00137 #define TAG_NEXT        RUBY_TAG_NEXT
00138 #define TAG_RETRY       RUBY_TAG_RETRY
00139 #define TAG_REDO        RUBY_TAG_REDO
00140 #define TAG_RAISE       RUBY_TAG_RAISE
00141 #define TAG_THROW       RUBY_TAG_THROW
00142 #define TAG_FATAL       RUBY_TAG_FATAL
00143 #define TAG_MASK        RUBY_TAG_MASK
00144 
00145 #define NEW_THROW_OBJECT(val, pt, st) \
00146   ((VALUE)rb_node_newnode(NODE_LIT, (VALUE)(val), (VALUE)(pt), (VALUE)(st)))
00147 #define SET_THROWOBJ_CATCH_POINT(obj, val) \
00148   (RNODE((obj))->u2.value = (val))
00149 #define SET_THROWOBJ_STATE(obj, val) \
00150   (RNODE((obj))->u3.value = (val))
00151 
00152 #define GET_THROWOBJ_VAL(obj)         ((VALUE)RNODE((obj))->u1.value)
00153 #define GET_THROWOBJ_CATCH_POINT(obj) ((VALUE*)RNODE((obj))->u2.value)
00154 #define GET_THROWOBJ_STATE(obj)       ((int)RNODE((obj))->u3.value)
00155 
00156 #define SCOPE_TEST(f)  (rb_vm_cref()->nd_visi & (f))
00157 #define SCOPE_CHECK(f) (rb_vm_cref()->nd_visi == (f))
00158 #define SCOPE_SET(f)   (rb_vm_cref()->nd_visi = (f))
00159 
00160 void rb_thread_cleanup(void);
00161 void rb_thread_wait_other_threads(void);
00162 
00163 enum {
00164     RAISED_EXCEPTION = 1,
00165     RAISED_STACKOVERFLOW = 2,
00166     RAISED_NOMEMORY = 4
00167 };
00168 int rb_threadptr_set_raised(rb_thread_t *th);
00169 int rb_threadptr_reset_raised(rb_thread_t *th);
00170 #define rb_thread_raised_set(th, f)   ((th)->raised_flag |= (f))
00171 #define rb_thread_raised_reset(th, f) ((th)->raised_flag &= ~(f))
00172 #define rb_thread_raised_p(th, f)     (((th)->raised_flag & (f)) != 0)
00173 #define rb_thread_raised_clear(th)    ((th)->raised_flag = 0)
00174 
00175 VALUE rb_f_eval(int argc, VALUE *argv, VALUE self);
00176 VALUE rb_make_exception(int argc, VALUE *argv);
00177 
00178 NORETURN(void rb_method_name_error(VALUE, VALUE));
00179 
00180 NORETURN(void rb_fiber_start(void));
00181 
00182 NORETURN(void rb_print_undef(VALUE, ID, int));
00183 NORETURN(void rb_print_undef_str(VALUE, VALUE));
00184 NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
00185 NORETURN(void rb_vm_jump_tag_but_local_jump(int));
00186 NORETURN(void rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv,
00187                                       VALUE obj, int call_status));
00188 
00189 VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
00190 NODE *rb_vm_cref(void);
00191 VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename);
00192 void rb_vm_set_progname(VALUE filename);
00193 void rb_thread_terminate_all(void);
00194 VALUE rb_vm_top_self();
00195 VALUE rb_vm_cbase(void);
00196 
00197 #ifndef CharNext                /* defined as CharNext[AW] on Windows. */
00198 #define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
00199 #endif
00200 
00201 #if defined DOSISH || defined __CYGWIN__
00202 static inline void
00203 translit_char(char *p, int from, int to)
00204 {
00205     while (*p) {
00206         if ((unsigned char)*p == from)
00207             *p = to;
00208         p = CharNext(p);
00209     }
00210 }
00211 #endif
00212 
00213 #endif /* RUBY_EVAL_INTERN_H */
00214