Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 157 lines (125 sloc) 3.133 kB
2a7794d @sj26 Ruby 1.9.3 p0
authored
1 /* -*-c-*- */
2 /**********************************************************************
3
4 vm_exec.c -
5
6 $Author: naruse $
7
8 Copyright (C) 2004-2007 Koichi Sasada
9
10 **********************************************************************/
11
12 #include <math.h>
13
14 #if VMDEBUG > 0
15 #define DECL_SC_REG(type, r, reg) register type reg_##r
16
17 #elif __GNUC__ && __x86_64__
18 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
19
20 #elif __GNUC__ && __i386__
21 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
22
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 */
27
28 #if OPT_STACK_CACHING
29 static VALUE finish_insn_seq[1] = { BIN(finish_SC_ax_ax) };
30 #elif OPT_CALL_THREADED_CODE
31 static VALUE const finish_insn_seq[1] = { 0 };
32 #else
33 static VALUE finish_insn_seq[1] = { BIN(finish) };
34 #endif
35
36 #if !OPT_CALL_THREADED_CODE
37 static VALUE
38 vm_exec_core(rb_thread_t *th, VALUE initial)
39 {
40
41 #if OPT_STACK_CACHING
42 #if 0
43 #elif __GNUC__ && __x86_64__
44 DECL_SC_REG(VALUE, a, "12");
45 DECL_SC_REG(VALUE, b, "13");
46 #else
47 register VALUE reg_a;
48 register VALUE reg_b;
49 #endif
50 #endif
51
52 #if __GNUC__ && __i386__
53 DECL_SC_REG(VALUE *, pc, "di");
54 DECL_SC_REG(rb_control_frame_t *, cfp, "si");
55 #define USE_MACHINE_REGS 1
56
57 #elif __GNUC__ && __x86_64__
58 DECL_SC_REG(VALUE *, pc, "14");
59 DECL_SC_REG(rb_control_frame_t *, cfp, "15");
60 #define USE_MACHINE_REGS 1
61
62 #else
63 register rb_control_frame_t *reg_cfp;
64 VALUE *reg_pc;
65 #endif
66
67 #if USE_MACHINE_REGS
68
69 #undef RESTORE_REGS
70 #define RESTORE_REGS() \
71 { \
72 REG_CFP = th->cfp; \
73 reg_pc = reg_cfp->pc; \
74 }
75
76 #undef REG_PC
77 #define REG_PC reg_pc
78 #undef GET_PC
79 #define GET_PC() (reg_pc)
80 #undef SET_PC
81 #define SET_PC(x) (reg_cfp->pc = REG_PC = (x))
82 #endif
83
84 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
85 #include "vmtc.inc"
86 if (UNLIKELY(th == 0)) {
87 #if OPT_STACK_CACHING
88 finish_insn_seq[0] = (VALUE)&&LABEL (finish_SC_ax_ax);
89 #else
90 finish_insn_seq[0] = (VALUE)&&LABEL (finish);
91 #endif
92 return (VALUE)insns_address_table;
93 }
94 #endif
95 reg_cfp = th->cfp;
96 reg_pc = reg_cfp->pc;
97
98 #if OPT_STACK_CACHING
99 reg_a = initial;
100 reg_b = 0;
101 #endif
102
103 first:
104 INSN_DISPATCH();
105 /*****************/
106 #include "vm.inc"
107 /*****************/
108 END_INSNS_DISPATCH();
109
110 /* unreachable */
111 rb_bug("vm_eval: unreachable");
112 goto first;
113 }
114
115 const void **
116 rb_vm_get_insns_address_table(void)
117 {
118 return (const void **)vm_exec_core(0, 0);
119 }
120
121 #else
122
123 #include "vm.inc"
124 #include "vmtc.inc"
125
126 const void *const *
127 rb_vm_get_insns_address_table(void)
128 {
129 return insns_address_table;
130 }
131
132 static VALUE
133 vm_exec_core(rb_thread_t *th, VALUE initial)
134 {
135 register rb_control_frame_t *reg_cfp = th->cfp;
136 VALUE ret;
137
138 while (*GET_PC()) {
139 reg_cfp = ((rb_insn_func_t) (*GET_PC()))(th, reg_cfp);
140
141 if (reg_cfp == 0) {
142 VALUE err = th->errinfo;
143 th->errinfo = Qnil;
144 return err;
145 }
146 }
147
148 if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_FINISH) {
149 rb_bug("cfp consistency error");
150 }
151
152 ret = *(th->cfp->sp-1); /* pop */
153 th->cfp++; /* pop cf */
154 return ret;
155 }
156 #endif
Something went wrong with that request. Please try again.