Ruby  2.5.0dev(2017-10-22revision60238)
vm_exec.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  vm.h -
4 
5  $Author$
6  created at: 04/01/01 16:56:59 JST
7 
8  Copyright (C) 2004-2007 Koichi Sasada
9 
10 **********************************************************************/
11 
12 #ifndef RUBY_VM_EXEC_H
13 #define RUBY_VM_EXEC_H
14 
15 typedef long OFFSET;
16 typedef unsigned long lindex_t;
17 typedef VALUE GENTRY;
18 typedef rb_iseq_t *ISEQ;
19 
20 #ifdef __GCC__
21 /* TODO: machine dependent prefetch instruction */
22 #define PREFETCH(pc)
23 #else
24 #define PREFETCH(pc)
25 #endif
26 
27 #if VMDEBUG > 0
28 #define debugs printf
29 #define DEBUG_ENTER_INSN(insn) \
30  rb_vmdebug_debug_print_pre(th, GET_CFP(),GET_PC());
31 
32 #if OPT_STACK_CACHING
33 #define SC_REGS() , reg_a, reg_b
34 #else
35 #define SC_REGS()
36 #endif
37 
38 #define DEBUG_END_INSN() \
39  rb_vmdebug_debug_print_post(th, GET_CFP() SC_REGS());
40 
41 #else
42 
43 #define debugs
44 #define DEBUG_ENTER_INSN(insn)
45 #define DEBUG_END_INSN()
46 #endif
47 
48 #define throwdebug if(0)printf
49 /* #define throwdebug printf */
50 
51 /************************************************/
52 #if defined(DISPATCH_XXX)
53 error !
54 /************************************************/
55 #elif OPT_CALL_THREADED_CODE
56 
57 #define LABEL(x) insn_func_##x
58 #define ELABEL(x)
59 #define LABEL_PTR(x) &LABEL(x)
60 
61 #define INSN_ENTRY(insn) \
62  static rb_control_frame_t * \
63  FUNC_FASTCALL(LABEL(insn))(rb_thread_t *th, rb_control_frame_t *reg_cfp) {
64 
65 #define END_INSN(insn) return reg_cfp;}
66 
67 #define NEXT_INSN() return reg_cfp;
68 
69 /************************************************/
70 #elif OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
71 /* threaded code with gcc */
72 
73 #define LABEL(x) INSN_LABEL_##x
74 #define ELABEL(x) INSN_ELABEL_##x
75 #define LABEL_PTR(x) &&LABEL(x)
76 
77 #define INSN_ENTRY_SIG(insn)
78 
79 
80 #define INSN_DISPATCH_SIG(insn)
81 
82 #define INSN_ENTRY(insn) \
83  LABEL(insn): \
84  INSN_ENTRY_SIG(insn); \
85 
86 /* dispatcher */
87 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && __GNUC__ == 3
88 #define DISPATCH_ARCH_DEPEND_WAY(addr) \
89  __asm__ __volatile__("jmp *%0;\t# -- inserted by vm.h\t[length = 2]" : : "r" (addr))
90 
91 #else
92 #define DISPATCH_ARCH_DEPEND_WAY(addr) \
93  /* do nothing */
94 
95 #endif
96 
97 
98 /**********************************/
99 #if OPT_DIRECT_THREADED_CODE
100 
101 /* for GCC 3.4.x */
102 #define TC_DISPATCH(insn) \
103  INSN_DISPATCH_SIG(insn); \
104  goto *(void const *)GET_CURRENT_INSN(); \
105  ;
106 
107 #else
108 /* token threaded code */
109 
110 #define TC_DISPATCH(insn) \
111  DISPATCH_ARCH_DEPEND_WAY(insns_address_table[GET_CURRENT_INSN()]); \
112  INSN_DISPATCH_SIG(insn); \
113  goto *insns_address_table[GET_CURRENT_INSN()]; \
114  rb_bug("tc error");
115 
116 
117 #endif /* DISPATCH_DIRECT_THREADED_CODE */
118 
119 #define END_INSN(insn) \
120  DEBUG_END_INSN(); \
121  TC_DISPATCH(insn);
122 
123 #define INSN_DISPATCH() \
124  TC_DISPATCH(__START__) \
125  {
126 
127 #define END_INSNS_DISPATCH() \
128  rb_bug("unknown insn: %"PRIdVALUE, GET_CURRENT_INSN()); \
129  } /* end of while loop */ \
130 
131 #define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
132 
133 /************************************************/
134 #else /* no threaded code */
135 /* most common method */
136 
137 #define INSN_ENTRY(insn) \
138 case BIN(insn):
139 
140 #define END_INSN(insn) \
141  DEBUG_END_INSN(); \
142  break;
143 
144 
145 #define INSN_DISPATCH() \
146  while (1) { \
147  switch (GET_CURRENT_INSN()) {
148 
149 #define END_INSNS_DISPATCH() \
150 default: \
151  SDR(); \
152  rb_bug("unknown insn: %ld", GET_CURRENT_INSN()); \
153  } /* end of switch */ \
154  } /* end of while loop */ \
155 
156 #define NEXT_INSN() goto first
157 
158 #endif
159 
160 #define VM_SP_CNT(th, sp) ((sp) - (th)->ec.vm_stack)
161 
162 #if OPT_CALL_THREADED_CODE
163 #define THROW_EXCEPTION(exc) do { \
164  th->ec.errinfo = (VALUE)(exc); \
165  return 0; \
166 } while (0)
167 #else
168 #define THROW_EXCEPTION(exc) return (VALUE)(exc)
169 #endif
170 
171 #define SCREG(r) (reg_##r)
172 
173 #define VM_DEBUG_STACKOVERFLOW 0
174 
175 #if VM_DEBUG_STACKOVERFLOW
176 #define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp, margin) \
177  WHEN_VM_STACK_OVERFLOWED(cfp, (cfp)->sp, margin) vm_stack_overflow_for_insn()
178 #else
179 #define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp, margin)
180 #endif
181 
182 #endif /* RUBY_VM_EXEC_H */
long OFFSET
Definition: vm_exec.h:15
rb_iseq_t * ISEQ
Definition: vm_exec.h:18
unsigned long VALUE
Definition: ruby.h:85
unsigned long lindex_t
Definition: vm_exec.h:16
VALUE GENTRY
Definition: vm_exec.h:17