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 = GC_GUARDED_PTR_REF((rb_block_t *)(th)->cfp->lfp[0]); \
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 #include <crt_externs.h>
00032 #endif
00033
00034
00035 #ifdef __GNUC__
00036 # ifndef atarist
00037 # ifndef alloca
00038 # define alloca __builtin_alloca
00039 # endif
00040 # endif
00041 #else
00042 # ifdef HAVE_ALLOCA_H
00043 # include <alloca.h>
00044 # else
00045 # ifdef _AIX
00046 #pragma alloca
00047 # else
00048 # ifndef alloca
00049 void *alloca();
00050 # endif
00051 # endif
00052 # endif
00053 #endif
00054
00055 #ifndef HAVE_STRING_H
00056 char *strrchr(const char *, const char);
00057 #endif
00058
00059 #ifdef HAVE_UNISTD_H
00060 #include <unistd.h>
00061 #endif
00062
00063 #ifdef HAVE_NET_SOCKET_H
00064 #include <net/socket.h>
00065 #endif
00066
00067 #define ruby_setjmp(env) RUBY_SETJMP(env)
00068 #define ruby_longjmp(env,val) RUBY_LONGJMP(env,val)
00069 #ifdef __CYGWIN__
00070 # ifndef _setjmp
00071 int _setjmp(jmp_buf);
00072 # endif
00073 # ifndef _longjmp
00074 NORETURN(void _longjmp(jmp_buf, int));
00075 # endif
00076 #endif
00077
00078 #include <sys/types.h>
00079 #include <signal.h>
00080 #include <errno.h>
00081
00082 #ifdef HAVE_SYS_SELECT_H
00083 #include <sys/select.h>
00084 #endif
00085
00086
00087
00088
00089
00090
00091
00092 #ifdef HAVE_SELECT_LARGE_FDSET
00093 #define select(n, r, w, e, t) select_large_fdset(n, r, w, e, t)
00094 #endif
00095
00096 #ifdef HAVE_SYS_PARAM_H
00097 #include <sys/param.h>
00098 #endif
00099
00100 #include <sys/stat.h>
00101
00102 #define SAVE_ROOT_JMPBUF(th, stmt) do \
00103 if (ruby_setjmp((th)->root_jmpbuf) == 0) { \
00104 stmt; \
00105 } \
00106 else { \
00107 rb_fiber_start(); \
00108 } while (0)
00109
00110 #define TH_PUSH_TAG(th) do { \
00111 rb_thread_t * const _th = th; \
00112 struct rb_vm_tag _tag; \
00113 _tag.tag = 0; \
00114 _tag.prev = _th->tag; \
00115 _th->tag = &_tag;
00116
00117 #define TH_POP_TAG() \
00118 _th->tag = _tag.prev; \
00119 } while (0)
00120
00121 #define TH_POP_TAG2() \
00122 _th->tag = _tag.prev
00123
00124 #define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
00125 #define POP_TAG() TH_POP_TAG()
00126
00127 #define TH_EXEC_TAG() ruby_setjmp(_th->tag->buf)
00128
00129 #define EXEC_TAG() \
00130 TH_EXEC_TAG()
00131
00132 #define TH_JUMP_TAG(th, st) do { \
00133 ruby_longjmp(th->tag->buf,(st)); \
00134 } while (0)
00135
00136 #define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), st)
00137
00138 enum ruby_tag_type {
00139 RUBY_TAG_RETURN = 0x1,
00140 RUBY_TAG_BREAK = 0x2,
00141 RUBY_TAG_NEXT = 0x3,
00142 RUBY_TAG_RETRY = 0x4,
00143 RUBY_TAG_REDO = 0x5,
00144 RUBY_TAG_RAISE = 0x6,
00145 RUBY_TAG_THROW = 0x7,
00146 RUBY_TAG_FATAL = 0x8,
00147 RUBY_TAG_MASK = 0xf
00148 };
00149 #define TAG_RETURN RUBY_TAG_RETURN
00150 #define TAG_BREAK RUBY_TAG_BREAK
00151 #define TAG_NEXT RUBY_TAG_NEXT
00152 #define TAG_RETRY RUBY_TAG_RETRY
00153 #define TAG_REDO RUBY_TAG_REDO
00154 #define TAG_RAISE RUBY_TAG_RAISE
00155 #define TAG_THROW RUBY_TAG_THROW
00156 #define TAG_FATAL RUBY_TAG_FATAL
00157 #define TAG_MASK RUBY_TAG_MASK
00158
00159 #define NEW_THROW_OBJECT(val, pt, st) \
00160 ((VALUE)rb_node_newnode(NODE_LIT, (VALUE)(val), (VALUE)(pt), (VALUE)(st)))
00161 #define SET_THROWOBJ_CATCH_POINT(obj, val) \
00162 (RNODE((obj))->u2.value = (val))
00163 #define SET_THROWOBJ_STATE(obj, val) \
00164 (RNODE((obj))->u3.value = (val))
00165
00166 #define GET_THROWOBJ_VAL(obj) ((VALUE)RNODE((obj))->u1.value)
00167 #define GET_THROWOBJ_CATCH_POINT(obj) ((VALUE*)RNODE((obj))->u2.value)
00168 #define GET_THROWOBJ_STATE(obj) ((int)RNODE((obj))->u3.value)
00169
00170 #define SCOPE_TEST(f) (rb_vm_cref()->nd_visi & (f))
00171 #define SCOPE_CHECK(f) (rb_vm_cref()->nd_visi == (f))
00172 #define SCOPE_SET(f) (rb_vm_cref()->nd_visi = (f))
00173
00174 #define CHECK_STACK_OVERFLOW(cfp, margin) do \
00175 if ((VALUE *)((char *)(((VALUE *)(cfp)->sp) + (margin)) + sizeof(rb_control_frame_t)) >= ((VALUE *)cfp)) { \
00176 rb_exc_raise(sysstack_error); \
00177 } \
00178 while (0)
00179
00180 void rb_thread_cleanup(void);
00181 void rb_thread_wait_other_threads(void);
00182
00183 enum {
00184 RAISED_EXCEPTION = 1,
00185 RAISED_STACKOVERFLOW = 2,
00186 RAISED_NOMEMORY = 4
00187 };
00188 int rb_threadptr_set_raised(rb_thread_t *th);
00189 int rb_threadptr_reset_raised(rb_thread_t *th);
00190 #define rb_thread_raised_set(th, f) ((th)->raised_flag |= (f))
00191 #define rb_thread_raised_reset(th, f) ((th)->raised_flag &= ~(f))
00192 #define rb_thread_raised_p(th, f) (((th)->raised_flag & (f)) != 0)
00193 #define rb_thread_raised_clear(th) ((th)->raised_flag = 0)
00194
00195 VALUE rb_f_eval(int argc, VALUE *argv, VALUE self);
00196 VALUE rb_make_exception(int argc, VALUE *argv);
00197
00198 NORETURN(void rb_fiber_start(void));
00199
00200 NORETURN(void rb_print_undef(VALUE, ID, int));
00201 NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
00202 NORETURN(void rb_vm_jump_tag_but_local_jump(int, VALUE));
00203 NORETURN(void rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv,
00204 VALUE obj, int call_status));
00205
00206 VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
00207 NODE *rb_vm_cref(void);
00208 VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename, VALUE filepath);
00209 void rb_vm_set_progname(VALUE filename);
00210 void rb_thread_terminate_all(void);
00211 VALUE rb_vm_top_self();
00212 VALUE rb_vm_cbase(void);
00213 int rb_vm_get_sourceline(const rb_control_frame_t *);
00214 void rb_trap_restore_mask(void);
00215
00216 #ifndef CharNext
00217 #define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))
00218 #endif
00219
00220 #if defined DOSISH || defined __CYGWIN__
00221 static inline void
00222 translit_char(char *p, int from, int to)
00223 {
00224 while (*p) {
00225 if ((unsigned char)*p == from)
00226 *p = to;
00227 p = CharNext(p);
00228 }
00229 }
00230 #endif
00231
00232 #endif
00233