Ruby  2.5.0dev(2017-10-22revision60238)
vm_exec.c
Go to the documentation of this file.
1 /* -*-c-*- */
2 /**********************************************************************
3 
4  vm_exec.c -
5 
6  $Author$
7 
8  Copyright (C) 2004-2007 Koichi Sasada
9 
10 **********************************************************************/
11 
12 #include <math.h>
13 
14 #if VM_COLLECT_USAGE_DETAILS
15 static void vm_analysis_insn(int insn);
16 #endif
17 
18 #if VMDEBUG > 0
19 #define DECL_SC_REG(type, r, reg) register type reg_##r
20 
21 #elif defined(__GNUC__) && defined(__x86_64__)
22 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
23 
24 #elif defined(__GNUC__) && defined(__i386__)
25 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
26 
27 #elif defined(__GNUC__) && defined(__powerpc64__)
28 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
29 
30 #else
31 #define DECL_SC_REG(type, r, reg) register type reg_##r
32 #endif
33 /* #define DECL_SC_REG(r, reg) VALUE reg_##r */
34 
35 #if VM_DEBUG_STACKOVERFLOW
36 NORETURN(static void vm_stack_overflow_for_insn(void));
37 static void
38 vm_stack_overflow_for_insn(void)
39 {
40  rb_bug("CHECK_VM_STACK_OVERFLOW_FOR_INSN: should not overflow here. "
41  "Please contact ruby-core/dev with your (a part of) script. "
42  "This check will be removed soon.");
43 }
44 #endif
45 
46 #if !OPT_CALL_THREADED_CODE
47 static VALUE
48 vm_exec_core(rb_thread_t *th, VALUE initial)
49 {
50 
51 #if OPT_STACK_CACHING
52 #if 0
53 #elif __GNUC__ && __x86_64__ && !defined(__native_client__)
54  DECL_SC_REG(VALUE, a, "12");
55  DECL_SC_REG(VALUE, b, "13");
56 #else
57  register VALUE reg_a;
58  register VALUE reg_b;
59 #endif
60 #endif
61 
62 #if defined(__GNUC__) && defined(__i386__)
63  DECL_SC_REG(const VALUE *, pc, "di");
64  DECL_SC_REG(rb_control_frame_t *, cfp, "si");
65 #define USE_MACHINE_REGS 1
66 
67 #elif defined(__GNUC__) && defined(__x86_64__)
68  DECL_SC_REG(const VALUE *, pc, "14");
69 # if defined(__native_client__)
70  DECL_SC_REG(rb_control_frame_t *, cfp, "13");
71 # else
72  DECL_SC_REG(rb_control_frame_t *, cfp, "15");
73 # endif
74 #define USE_MACHINE_REGS 1
75 
76 #elif defined(__GNUC__) && defined(__powerpc64__)
77  DECL_SC_REG(const VALUE *, pc, "14");
78  DECL_SC_REG(rb_control_frame_t *, cfp, "15");
79 #define USE_MACHINE_REGS 1
80 
81 #else
82  register rb_control_frame_t *reg_cfp;
83  const VALUE *reg_pc;
84 #endif
85 
86 #if USE_MACHINE_REGS
87 
88 #undef RESTORE_REGS
89 #define RESTORE_REGS() \
90 { \
91  VM_REG_CFP = th->ec.cfp; \
92  reg_pc = reg_cfp->pc; \
93 }
94 
95 #undef VM_REG_PC
96 #define VM_REG_PC reg_pc
97 #undef GET_PC
98 #define GET_PC() (reg_pc)
99 #undef SET_PC
100 #define SET_PC(x) (reg_cfp->pc = VM_REG_PC = (x))
101 #endif
102 
103 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
104 #include "vmtc.inc"
105  if (UNLIKELY(th == 0)) {
106  return (VALUE)insns_address_table;
107  }
108 #endif
109  reg_cfp = th->ec.cfp;
110  reg_pc = reg_cfp->pc;
111 
112 #if OPT_STACK_CACHING
113  reg_a = initial;
114  reg_b = 0;
115 #endif
116 
117  first:
118  INSN_DISPATCH();
119 /*****************/
120  #include "vm.inc"
121 /*****************/
123 
124  /* unreachable */
125  rb_bug("vm_eval: unreachable");
126  goto first;
127 }
128 
129 const void **
131 {
132  return (const void **)vm_exec_core(0, 0);
133 }
134 
135 #else /* OPT_CALL_THREADED_CODE */
136 
137 #include "vm.inc"
138 #include "vmtc.inc"
139 
140 const void **
142 {
143  return (const void **)insns_address_table;
144 }
145 
146 static VALUE
147 vm_exec_core(rb_thread_t *th, VALUE initial)
148 {
149  register rb_control_frame_t *reg_cfp = th->ec.cfp;
150 
151  while (1) {
152  reg_cfp = ((rb_insn_func_t) (*GET_PC()))(th, reg_cfp);
153 
154  if (UNLIKELY(reg_cfp == 0)) {
155  break;
156  }
157  }
158 
159  if (th->retval != Qundef) {
160  VALUE ret = th->retval;
161  th->retval = Qundef;
162  return ret;
163  }
164  else {
165  VALUE err = th->ec.errinfo;
166  th->ec.errinfo = Qnil;
167  return err;
168  }
169 }
170 #endif
#define END_INSNS_DISPATCH()
Definition: vm_exec.h:149
void rb_bug(const char *fmt,...)
Definition: error.c:521
rb_control_frame_t * cfp
Definition: vm_core.h:744
const void ** rb_vm_get_insns_address_table(void)
Definition: vm_exec.c:130
#define NORETURN(x)
Definition: defines.h:34
#define UNLIKELY(x)
Definition: internal.h:43
#define GET_PC()
Definition: vm_insnhelper.h:84
#define DECL_SC_REG(type, r, reg)
Definition: vm_exec.c:31
int err
Definition: win32.c:135
#define INSN_DISPATCH()
Definition: vm_exec.h:145
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_thread_t *, rb_control_frame_t *)
Definition: vm_core.h:1002
const VALUE * pc
Definition: vm_core.h:663
rb_execution_context_t ec
Definition: vm_core.h:790
#define Qundef
Definition: ruby.h:439