* io.c (rb_open_file): encoding in mode string was ignored if perm is
[ruby-svn.git] / vm_evalbody.c
blob65f2964180370a93253cf8ea1c16c7cdd3899dfe
1 /* -*-c-*- */
2 /**********************************************************************
4 vm_evalbody.c -
6 $Author$
8 Copyright (C) 2004-2007 Koichi Sasada
10 **********************************************************************/
12 #include <math.h>
14 #if VMDEBUG > 0
15 #define DECL_SC_REG(type, r, reg) register type reg_##r
17 #elif __GNUC__ && __x86_64__
18 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
20 #elif __GNUC__ && __i386__
21 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
23 #else
24 #define DECL_SC_REG(type, r, reg) register type reg_##r
25 #endif
26 /* #define DECL_SC_REG(r, reg) VALUE reg_##r */
28 #if !OPT_CALL_THREADED_CODE
29 static VALUE
30 vm_eval(rb_thread_t *th, VALUE initial)
33 #if OPT_STACK_CACHING
34 #if 0
35 #elif __GNUC__ && __x86_64
36 DECL_SC_REG(VALUE, a, "12");
37 DECL_SC_REG(VALUE, b, "13");
38 #else
39 register VALUE reg_a;
40 register VALUE reg_b;
41 #endif
42 #endif
44 #if __GNUC__ && __i386__
45 DECL_SC_REG(VALUE *, pc, "di");
46 DECL_SC_REG(rb_control_frame_t *, cfp, "si");
47 #define USE_MACHINE_REGS 1
49 #elif __GNUC__ && __x86_64__
50 DECL_SC_REG(VALUE *, pc, "14");
51 DECL_SC_REG(rb_control_frame_t *, cfp, "15");
52 #define USE_MACHINE_REGS 1
54 #else
55 register rb_control_frame_t *reg_cfp;
56 VALUE *reg_pc;
57 #endif
59 #if USE_MACHINE_REGS
61 #undef RESTORE_REGS
62 #define RESTORE_REGS() \
63 { \
64 REG_CFP = th->cfp; \
65 reg_pc = reg_cfp->pc; \
68 #undef REG_PC
69 #define REG_PC reg_pc
70 #undef GET_PC
71 #define GET_PC() (reg_pc)
72 #undef SET_PC
73 #define SET_PC(x) (reg_cfp->pc = REG_PC = (x))
74 #endif
76 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
77 #include "vmtc.inc"
78 if (th == 0) {
79 #if OPT_STACK_CACHING
80 finish_insn_seq[0] = (VALUE)&&LABEL (finish_SC_ax_ax);
81 #else
82 finish_insn_seq[0] = (VALUE)&&LABEL (finish);
83 #endif
84 return (VALUE)insns_address_table;
86 #endif
87 reg_cfp = th->cfp;
88 reg_pc = reg_cfp->pc;
90 #if OPT_STACK_CACHING
91 reg_a = initial;
92 reg_b = 0;
93 #endif
95 first:
96 INSN_DISPATCH();
97 /*****************/
98 #include "vm.inc"
99 /*****************/
100 END_INSNS_DISPATCH();
102 /* unreachable */
103 rb_bug("vm_eval: unreachable");
104 goto first;
107 #else
109 #include "vm.inc"
110 #include "vmtc.inc"
112 const void *const *
113 get_insns_address_table()
115 return insns_address_table;
118 VALUE
119 vm_eval(rb_thread_t *th, VALUE initial)
121 register rb_control_frame_t *reg_cfp = th->cfp;
122 VALUE ret;
124 while (*GET_PC()) {
125 reg_cfp = ((rb_insn_func_t) (*GET_PC()))(th, reg_cfp);
127 if (reg_cfp == 0) {
128 VALUE err = th->errinfo;
129 th->errinfo = Qnil;
130 return err;
134 if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_FINISH) {
135 rb_bug("cfp consistency error");
138 ret = *(th->cfp->sp-1); /* pop */
139 th->cfp++; /* pop cf */
140 return ret;
142 #endif
144 const void **
145 vm_get_insns_address_table(void)
147 return (const void **)vm_eval(0, 0);