Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# vm_exec.c

Go to the documentation of this file.

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