21#define DEBUG_ENTER_INSN(insn) \
22 rb_vmdebug_debug_print_pre(ec, GET_CFP(), GET_PC());
25#define SC_REGS() , reg_a, reg_b
30#define DEBUG_END_INSN() \
31 rb_vmdebug_debug_print_post(ec, GET_CFP() SC_REGS());
36#define DEBUG_ENTER_INSN(insn)
37#define DEBUG_END_INSN()
40#define throwdebug if(0)printf
43#ifndef USE_INSNS_COUNTER
44#define USE_INSNS_COUNTER 0
48#if defined(DISPATCH_XXX)
51#elif OPT_CALL_THREADED_CODE
53#define LABEL(x) insn_func_##x
55#define LABEL_PTR(x) &LABEL(x)
57#define INSN_ENTRY(insn) \
58 static rb_control_frame_t * \
59 FUNC_FASTCALL(LABEL(insn))(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp) {
61#define END_INSN(insn) return reg_cfp;}
63#define NEXT_INSN() return reg_cfp;
65#define START_OF_ORIGINAL_INSN(x)
66#define DISPATCH_ORIGINAL_INSN(x) return LABEL(x)(ec, reg_cfp);
69#elif OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
72#define LABEL(x) INSN_LABEL_##x
73#define ELABEL(x) INSN_ELABEL_##x
74#define LABEL_PTR(x) RB_GNUC_EXTENSION(&&LABEL(x))
76#define INSN_ENTRY_SIG(insn) \
77 if (0) fprintf(stderr, "exec: %s@(%"PRIdPTRDIFF", %"PRIdPTRDIFF")@%s:%u\n", #insn, \
78 (reg_pc - reg_cfp->iseq->body->iseq_encoded), \
79 (reg_cfp->pc - reg_cfp->iseq->body->iseq_encoded), \
80 RSTRING_PTR(rb_iseq_path(reg_cfp->iseq)), \
81 rb_iseq_line_no(reg_cfp->iseq, reg_pc - reg_cfp->iseq->body->iseq_encoded)); \
82 if (USE_INSNS_COUNTER) vm_insns_counter_count_insn(BIN(insn));
84#define INSN_DISPATCH_SIG(insn)
86#define INSN_ENTRY(insn) \
88 INSN_ENTRY_SIG(insn); \
91#if OPT_DIRECT_THREADED_CODE
94#define TC_DISPATCH(insn) \
95 INSN_DISPATCH_SIG(insn); \
96 RB_GNUC_EXTENSION_BLOCK(goto *(void const *)GET_CURRENT_INSN()); \
103#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && __GNUC__ == 3
104#define DISPATCH_ARCH_DEPEND_WAY(addr) \
105 __asm__ __volatile__("jmp *%0;\t# -- inserted by vm.h\t[length = 2]" : : "r" (addr))
108#define DISPATCH_ARCH_DEPEND_WAY(addr) \
111#define TC_DISPATCH(insn) \
112 DISPATCH_ARCH_DEPEND_WAY(insns_address_table[GET_CURRENT_INSN()]); \
113 INSN_DISPATCH_SIG(insn); \
114 RB_GNUC_EXTENSION_BLOCK(goto *insns_address_table[GET_CURRENT_INSN()]); \
119#define END_INSN(insn) \
123#define INSN_DISPATCH() \
124 TC_DISPATCH(__START__) \
127#define END_INSNS_DISPATCH() \
128 rb_bug("unknown insn: %"PRIdVALUE, GET_CURRENT_INSN()); \
131#define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
133#define START_OF_ORIGINAL_INSN(x) start_of_##x:
134#define DISPATCH_ORIGINAL_INSN(x) goto start_of_##x;
140#define INSN_ENTRY(insn) \
143#define END_INSN(insn) \
147#define INSN_DISPATCH() \
149 switch (GET_CURRENT_INSN()) {
151#define END_INSNS_DISPATCH() \
154 rb_bug("unknown insn: %ld", GET_CURRENT_INSN()); \
158#define NEXT_INSN() goto first
160#define START_OF_ORIGINAL_INSN(x) start_of_##x:
161#define DISPATCH_ORIGINAL_INSN(x) goto start_of_##x;
165#define VM_SP_CNT(ec, sp) ((sp) - (ec)->vm_stack)
168#define THROW_EXCEPTION(exc) do { \
169 ec->errinfo = (VALUE)(exc); \
170 EC_JUMP_TAG(ec, ec->tag->state); \
173#if OPT_CALL_THREADED_CODE
174#define THROW_EXCEPTION(exc) do { \
175 ec->errinfo = (VALUE)(exc); \
179#define THROW_EXCEPTION(exc) return (VALUE)(exc)
183#define SCREG(r) (reg_##r)
185#define VM_DEBUG_STACKOVERFLOW 0
187#if VM_DEBUG_STACKOVERFLOW
188#define CHECK_VM_STACK_OVERFLOW_FOR_INSN CHECK_VM_STACK_OVERFLOW
190#define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp, margin)
193#define INSN_LABEL2(insn, name) INSN_LABEL_ ## insn ## _ ## name
194#define INSN_LABEL(x) INSN_LABEL2(NAME_OF_CURRENT_INSN, x)
void error(const char *msg)