00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef RUBY_VM_EXEC_H
00013 #define RUBY_VM_EXEC_H
00014
00015 typedef long OFFSET;
00016 typedef unsigned long lindex_t;
00017 typedef VALUE GENTRY;
00018 typedef rb_iseq_t *ISEQ;
00019
00020 #ifdef __GCC__
00021
00022 #define PREFETCH(pc)
00023 #else
00024 #define PREFETCH(pc)
00025 #endif
00026
00027 #if VMDEBUG > 0
00028 #define debugs printf
00029 #define DEBUG_ENTER_INSN(insn) \
00030 rb_vmdebug_debug_print_pre(th, GET_CFP());
00031
00032 #if OPT_STACK_CACHING
00033 #define SC_REGS() , reg_a, reg_b
00034 #else
00035 #define SC_REGS()
00036 #endif
00037
00038 #define DEBUG_END_INSN() \
00039 rb_vmdebug_debug_print_post(th, GET_CFP() SC_REGS());
00040
00041 #else
00042
00043 #define debugs
00044 #define DEBUG_ENTER_INSN(insn)
00045 #define DEBUG_END_INSN()
00046 #endif
00047
00048 #define throwdebug if(0)printf
00049
00050
00051
00052 #if defined(DISPATCH_XXX)
00053 error !
00054
00055 #elif OPT_CALL_THREADED_CODE
00056
00057 #define LABEL(x) insn_func_##x
00058 #define ELABEL(x)
00059 #define LABEL_PTR(x) &LABEL(x)
00060
00061 #define INSN_ENTRY(insn) \
00062 static rb_control_frame_t * \
00063 FUNC_FASTCALL(LABEL(insn))(rb_thread_t *th, rb_control_frame_t *reg_cfp) {
00064
00065 #define END_INSN(insn) return reg_cfp;}
00066
00067 #define NEXT_INSN() return reg_cfp;
00068
00069
00070 #elif OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
00071
00072
00073 #define LABEL(x) INSN_LABEL_##x
00074 #define ELABEL(x) INSN_ELABEL_##x
00075 #define LABEL_PTR(x) &&LABEL(x)
00076
00077 #define INSN_ENTRY_SIG(insn)
00078
00079
00080 #define INSN_DISPATCH_SIG(insn)
00081
00082 #define INSN_ENTRY(insn) \
00083 LABEL(insn): \
00084 INSN_ENTRY_SIG(insn); \
00085
00086
00087 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && __GNUC__ == 3
00088 #define DISPATCH_ARCH_DEPEND_WAY(addr) \
00089 asm volatile("jmp *%0;\t# -- inseted by vm.h\t[length = 2]" : : "r" (addr))
00090
00091 #else
00092 #define DISPATCH_ARCH_DEPEND_WAY(addr) \
00093
00094
00095 #endif
00096
00097
00098
00099 #if OPT_DIRECT_THREADED_CODE
00100
00101
00102 #define TC_DISPATCH(insn) \
00103 INSN_DISPATCH_SIG(insn); \
00104 goto *(void const *)GET_CURRENT_INSN(); \
00105 ;
00106
00107 #else
00108
00109
00110 #define TC_DISPATCH(insn) \
00111 DISPATCH_ARCH_DEPEND_WAY(insns_address_table[GET_CURRENT_INSN()]); \
00112 INSN_DISPATCH_SIG(insn); \
00113 goto *insns_address_table[GET_CURRENT_INSN()]; \
00114 rb_bug("tc error");
00115
00116
00117 #endif
00118
00119 #define END_INSN(insn) \
00120 DEBUG_END_INSN(); \
00121 TC_DISPATCH(insn); \
00122
00123 #define INSN_DISPATCH() \
00124 TC_DISPATCH(__START__) \
00125 {
00126
00127 #define END_INSNS_DISPATCH() \
00128 rb_bug("unknown insn: %"PRIdVALUE, GET_CURRENT_INSN()); \
00129 } \
00130
00131 #define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
00132
00133
00134 #else
00135
00136
00137 #define INSN_ENTRY(insn) \
00138 case BIN(insn):
00139
00140 #define END_INSN(insn) \
00141 DEBUG_END_INSN(); \
00142 break;
00143
00144
00145 #define INSN_DISPATCH() \
00146 while (1) { \
00147 switch (GET_CURRENT_INSN()) {
00148
00149 #define END_INSNS_DISPATCH() \
00150 default: \
00151 SDR(); \
00152 rb_bug("unknown insn: %ld", GET_CURRENT_INSN()); \
00153 } \
00154 } \
00155
00156 #define NEXT_INSN() goto first
00157
00158 #endif
00159
00160 #define VM_SP_CNT(th, sp) ((sp) - (th)->stack)
00161
00162 #if OPT_CALL_THREADED_CODE
00163 #define THROW_EXCEPTION(exc) do { \
00164 th->errinfo = (VALUE)(exc); \
00165 return 0; \
00166 } while (0)
00167 #else
00168 #define THROW_EXCEPTION(exc) return (VALUE)(exc)
00169 #endif
00170
00171 #define SCREG(r) (reg_##r)
00172
00173 #endif
00174