Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
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
15static 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#elif defined(__GNUC__) && defined(__aarch64__)
31#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("x" reg)
32
33#else
34#define DECL_SC_REG(type, r, reg) register type reg_##r
35#endif
36/* #define DECL_SC_REG(r, reg) VALUE reg_##r */
37
38#if VM_DEBUG_STACKOVERFLOW
39NORETURN(static void vm_stack_overflow_for_insn(void));
40static void
41vm_stack_overflow_for_insn(void)
42{
43 rb_bug("CHECK_VM_STACK_OVERFLOW_FOR_INSN: should not overflow here. "
44 "Please contact ruby-core/dev with your (a part of) script. "
45 "This check will be removed soon.");
46}
47#endif
48
49#if !OPT_CALL_THREADED_CODE
50static VALUE
51vm_exec_core(rb_execution_context_t *ec, VALUE initial)
52{
53
54#if OPT_STACK_CACHING
55#if 0
56#elif __GNUC__ && __x86_64__
57 DECL_SC_REG(VALUE, a, "12");
58 DECL_SC_REG(VALUE, b, "13");
59#else
60 register VALUE reg_a;
61 register VALUE reg_b;
62#endif
63#endif
64
65#if defined(__GNUC__) && defined(__i386__)
66 DECL_SC_REG(const VALUE *, pc, "di");
68#define USE_MACHINE_REGS 1
69
70#elif defined(__GNUC__) && defined(__x86_64__)
71 DECL_SC_REG(const VALUE *, pc, "14");
73#define USE_MACHINE_REGS 1
74
75#elif defined(__GNUC__) && defined(__powerpc64__)
76 DECL_SC_REG(const VALUE *, pc, "14");
78#define USE_MACHINE_REGS 1
79
80#elif defined(__GNUC__) && defined(__aarch64__)
81 DECL_SC_REG(const VALUE *, pc, "19");
83#define USE_MACHINE_REGS 1
84
85#else
87 const VALUE *reg_pc;
88#endif
89
90#if USE_MACHINE_REGS
91
92#undef RESTORE_REGS
93#define RESTORE_REGS() \
94{ \
95 VM_REG_CFP = ec->cfp; \
96 reg_pc = reg_cfp->pc; \
97}
98
99#undef VM_REG_PC
100#define VM_REG_PC reg_pc
101#undef GET_PC
102#define GET_PC() (reg_pc)
103#undef SET_PC
104#define SET_PC(x) (reg_cfp->pc = VM_REG_PC = (x))
105#endif
106
107#if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
108#include "vmtc.inc"
109 if (UNLIKELY(ec == 0)) {
110 return (VALUE)insns_address_table;
111 }
112#endif
113 reg_cfp = ec->cfp;
114 reg_pc = reg_cfp->pc;
115
116#if OPT_STACK_CACHING
117 reg_a = initial;
118 reg_b = 0;
119#endif
120
121 first:
123/*****************/
124 #include "vm.inc"
125/*****************/
127
128 /* unreachable */
129 rb_bug("vm_eval: unreachable");
130 goto first;
131}
132
133const void **
135{
136 return (const void **)vm_exec_core(0, 0);
137}
138
139#else /* OPT_CALL_THREADED_CODE */
140
141#include "vm.inc"
142#include "vmtc.inc"
143
144const void **
146{
147 return (const void **)insns_address_table;
148}
149
150static VALUE
151vm_exec_core(rb_execution_context_t *ec, VALUE initial)
152{
153 register rb_control_frame_t *reg_cfp = ec->cfp;
154 rb_thread_t *th;
155
156 while (1) {
157 reg_cfp = ((rb_insn_func_t) (*GET_PC()))(ec, reg_cfp);
158
159 if (UNLIKELY(reg_cfp == 0)) {
160 break;
161 }
162 }
163
164 if ((th = rb_ec_thread_ptr(ec))->retval != Qundef) {
165 VALUE ret = th->retval;
166 th->retval = Qundef;
167 return ret;
168 }
169 else {
170 VALUE err = ec->errinfo;
171 ec->errinfo = Qnil;
172 return err;
173 }
174}
175#endif
void rb_bug(const char *fmt,...)
Definition: error.c:636
rb_control_frame_t * cfp
#define Qundef
#define GET_PC()
rb_control_frame_t * reg_cfp
#define NORETURN(x)
#define INSN_DISPATCH()
#define END_INSNS_DISPATCH()
#define UNLIKELY(x)
#define Qnil
rb_control_frame_t const VALUE * pc
unsigned long VALUE
Definition: ruby.h:102
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_execution_context_t *, rb_control_frame_t *)
Definition: vm_core.h:1143
const void ** rb_vm_get_insns_address_table(void)
Definition: vm_exec.c:134
#define DECL_SC_REG(type, r, reg)
Definition: vm_exec.c:34