Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
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_execution_context_t *ec, VALUE initial)
49 {
50 
51 #if OPT_STACK_CACHING
52 #if 0
53 #elif __GNUC__ && __x86_64__
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");
65 #define USE_MACHINE_REGS 1
66 
67 #elif defined(__GNUC__) && defined(__x86_64__)
68  DECL_SC_REG(const VALUE *, pc, "14");
70 #define USE_MACHINE_REGS 1
71 
72 #elif defined(__GNUC__) && defined(__powerpc64__)
73  DECL_SC_REG(const VALUE *, pc, "14");
75 #define USE_MACHINE_REGS 1
76 
77 #else
78  register rb_control_frame_t *reg_cfp;
79  const VALUE *reg_pc;
80 #endif
81 
82 #if USE_MACHINE_REGS
83 
84 #undef RESTORE_REGS
85 #define RESTORE_REGS() \
86 { \
87  VM_REG_CFP = ec->cfp; \
88  reg_pc = reg_cfp->pc; \
89 }
90 
91 #undef VM_REG_PC
92 #define VM_REG_PC reg_pc
93 #undef GET_PC
94 #define GET_PC() (reg_pc)
95 #undef SET_PC
96 #define SET_PC(x) (reg_cfp->pc = VM_REG_PC = (x))
97 #endif
98 
99 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
100 #include "vmtc.inc"
101  if (UNLIKELY(ec == 0)) {
102  return (VALUE)insns_address_table;
103  }
104 #endif
105  reg_cfp = ec->cfp;
106  reg_pc = reg_cfp->pc;
107 
108 #if OPT_STACK_CACHING
109  reg_a = initial;
110  reg_b = 0;
111 #endif
112 
113  first:
114  INSN_DISPATCH();
115 /*****************/
116  #include "vm.inc"
117 /*****************/
119 
120  /* unreachable */
121  rb_bug("vm_eval: unreachable");
122  goto first;
123 }
124 
125 const void **
127 {
128  return (const void **)vm_exec_core(0, 0);
129 }
130 
131 #else /* OPT_CALL_THREADED_CODE */
132 
133 #include "vm.inc"
134 #include "vmtc.inc"
135 
136 const void **
138 {
139  return (const void **)insns_address_table;
140 }
141 
142 static VALUE
143 vm_exec_core(rb_execution_context_t *ec, VALUE initial)
144 {
145  register rb_control_frame_t *reg_cfp = ec->cfp;
146  rb_thread_t *th;
147 
148  while (1) {
149  reg_cfp = ((rb_insn_func_t) (*GET_PC()))(ec, reg_cfp);
150 
151  if (UNLIKELY(reg_cfp == 0)) {
152  break;
153  }
154  }
155 
156  if ((th = rb_ec_thread_ptr(ec))->retval != Qundef) {
157  VALUE ret = th->retval;
158  th->retval = Qundef;
159  return ret;
160  }
161  else {
162  VALUE err = ec->errinfo;
163  ec->errinfo = Qnil;
164  return err;
165  }
166 }
167 #endif
UNLIKELY
#define UNLIKELY(x)
Definition: ffi_common.h:126
reg_cfp
rb_control_frame_t * reg_cfp
Definition: rb_mjit_min_header-2.7.0.h:15146
GET_PC
#define GET_PC()
Definition: vm_insnhelper.h:79
NORETURN
#define NORETURN(x)
Definition: defines.h:528
VALUE
unsigned long VALUE
Definition: ruby.h:102
Qundef
#define Qundef
Definition: ruby.h:470
END_INSNS_DISPATCH
#define END_INSNS_DISPATCH()
Definition: vm_exec.h:147
INSN_DISPATCH
#define INSN_DISPATCH()
Definition: vm_exec.h:143
pc
rb_control_frame_t const VALUE * pc
Definition: rb_mjit_min_header-2.7.0.h:16923
rb_execution_context_struct::cfp
rb_control_frame_t * cfp
Definition: vm_core.h:847
rb_insn_func_t
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_execution_context_t *, rb_control_frame_t *)
Definition: vm_core.h:1143
rb_execution_context_struct::errinfo
VALUE errinfo
Definition: vm_core.h:875
rb_control_frame_struct
Definition: vm_core.h:760
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
rb_vm_get_insns_address_table
const void ** rb_vm_get_insns_address_table(void)
Definition: vm_exec.c:126
DECL_SC_REG
#define DECL_SC_REG(type, r, reg)
Definition: vm_exec.c:31
err
int err
Definition: win32.c:135
rb_control_frame_struct::pc
const VALUE * pc
Definition: vm_core.h:761
Qnil
#define Qnil
Definition: ruby.h:469
rb_thread_struct
Definition: vm_core.h:910
cfp
rb_control_frame_t * cfp
Definition: rb_mjit_min_header-2.7.0.h:14544
rb_execution_context_struct
Definition: vm_core.h:843