Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /* -*-c-*- */ 00002 /********************************************************************** 00003 00004 vm_exec.c - 00005 00006 $Author: nagachika $ 00007 00008 Copyright (C) 2004-2007 Koichi Sasada 00009 00010 **********************************************************************/ 00011 00012 #include <math.h> 00013 00014 #if VM_COLLECT_USAGE_DETAILS 00015 static void vm_analysis_insn(int insn); 00016 #endif 00017 00018 #if VMDEBUG > 0 00019 #define DECL_SC_REG(type, r, reg) register type reg_##r 00020 00021 #elif defined(__GNUC__) && defined(__x86_64__) 00022 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg) 00023 00024 #elif defined(__GNUC__) && defined(__i386__) 00025 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg) 00026 00027 #else 00028 #define DECL_SC_REG(type, r, reg) register type reg_##r 00029 #endif 00030 /* #define DECL_SC_REG(r, reg) VALUE reg_##r */ 00031 00032 #if !OPT_CALL_THREADED_CODE 00033 static VALUE 00034 vm_exec_core(rb_thread_t *th, VALUE initial) 00035 { 00036 00037 #if OPT_STACK_CACHING 00038 #if 0 00039 #elif __GNUC__ && __x86_64__ 00040 DECL_SC_REG(VALUE, a, "12"); 00041 DECL_SC_REG(VALUE, b, "13"); 00042 #else 00043 register VALUE reg_a; 00044 register VALUE reg_b; 00045 #endif 00046 #endif 00047 00048 #if defined(__GNUC__) && defined(__i386__) 00049 DECL_SC_REG(VALUE *, pc, "di"); 00050 DECL_SC_REG(rb_control_frame_t *, cfp, "si"); 00051 #define USE_MACHINE_REGS 1 00052 00053 #elif defined(__GNUC__) && defined(__x86_64__) 00054 DECL_SC_REG(VALUE *, pc, "14"); 00055 DECL_SC_REG(rb_control_frame_t *, cfp, "15"); 00056 #define USE_MACHINE_REGS 1 00057 00058 #else 00059 register rb_control_frame_t *reg_cfp; 00060 VALUE *reg_pc; 00061 #endif 00062 00063 #if USE_MACHINE_REGS 00064 00065 #undef RESTORE_REGS 00066 #define RESTORE_REGS() \ 00067 { \ 00068 REG_CFP = th->cfp; \ 00069 reg_pc = reg_cfp->pc; \ 00070 } 00071 00072 #undef REG_PC 00073 #define REG_PC reg_pc 00074 #undef GET_PC 00075 #define GET_PC() (reg_pc) 00076 #undef SET_PC 00077 #define SET_PC(x) (reg_cfp->pc = REG_PC = (x)) 00078 #endif 00079 00080 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE 00081 #include "vmtc.inc" 00082 if (UNLIKELY(th == 0)) { 00083 return (VALUE)insns_address_table; 00084 } 00085 #endif 00086 reg_cfp = th->cfp; 00087 reg_pc = reg_cfp->pc; 00088 00089 #if OPT_STACK_CACHING 00090 reg_a = initial; 00091 reg_b = 0; 00092 #endif 00093 00094 first: 00095 INSN_DISPATCH(); 00096 /*****************/ 00097 #include "vm.inc" 00098 /*****************/ 00099 END_INSNS_DISPATCH(); 00100 00101 /* unreachable */ 00102 rb_bug("vm_eval: unreachable"); 00103 goto first; 00104 } 00105 00106 const void ** 00107 rb_vm_get_insns_address_table(void) 00108 { 00109 return (const void **)vm_exec_core(0, 0); 00110 } 00111 00112 #else /* OPT_CALL_THREADED_CODE */ 00113 00114 #include "vm.inc" 00115 #include "vmtc.inc" 00116 00117 const void ** 00118 rb_vm_get_insns_address_table(void) 00119 { 00120 return (const void **)insns_address_table; 00121 } 00122 00123 static VALUE 00124 vm_exec_core(rb_thread_t *th, VALUE initial) 00125 { 00126 register rb_control_frame_t *reg_cfp = th->cfp; 00127 00128 while (1) { 00129 reg_cfp = ((rb_insn_func_t) (*GET_PC()))(th, reg_cfp); 00130 00131 if (UNLIKELY(reg_cfp == 0)) { 00132 break; 00133 } 00134 } 00135 00136 if (th->retval != Qundef) { 00137 VALUE ret = th->retval; 00138 th->retval = Qundef; 00139 return ret; 00140 } 00141 else { 00142 VALUE err = th->errinfo; 00143 th->errinfo = Qnil; 00144 return err; 00145 } 00146 } 00147 #endif 00148