1 /**********************************************************************
6 created at: 04/01/01 23:36:57 JST
8 Copyright (C) 2004-2007 Koichi Sasada
10 **********************************************************************/
12 #ifndef RUBY_COMPILE_H
13 #define RUBY_COMPILE_H
17 * debug function(macro) interface depend on CPDEBUG
18 * if it is less than 0, runtime option is in effect.
23 * 2: show node important parameters
25 * 5: show other parameters
26 * 10: show every AST array
34 #define compile_debug CPDEBUG
36 #define compile_debug iseq->compile_data->option->debug_level
39 NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4));
43 #define compile_debug_print_indent(level) \
44 ruby_debug_print_indent(level, compile_debug, gl_node_level * 2)
46 #define debugp(header, value) (void) \
47 (compile_debug_print_indent(1) && \
48 ruby_debug_print_value(1, compile_debug, header, value))
50 #define debugi(header, id) (void) \
51 (compile_debug_print_indent(1) && \
52 ruby_debug_print_id(1, compile_debug, header, id))
54 #define debugp_param(header, value) (void) \
55 (compile_debug_print_indent(1) && \
56 ruby_debug_print_value(1, compile_debug, header, value))
58 #define debugp_verbose(header, value) (void) \
59 (compile_debug_print_indent(2) && \
60 ruby_debug_print_value(2, compile_debug, header, value))
62 #define debugp_verbose_node(header, value) (void) \
63 (compile_debug_print_indent(10) && \
64 ruby_debug_print_value(10, compile_debug, header, value))
66 #define debug_node_start(node) ((void) \
67 (compile_debug_print_indent(1) && \
68 (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)node), gl_node_level)), \
71 #define debug_node_end() gl_node_level --;
87 #define debugi(header, id) r_id(id)
88 #define debugp(header, value) r_value(value)
89 #define debugp_verbose(header, value) r_value(value)
90 #define debugp_verbose_node(header, value) r_value(value)
91 #define debugp_param(header, value) r_value(value)
92 #define debug_node_start(node) ((void)0)
93 #define debug_node_end() ((void)0)
96 #if CPDEBUG > 1 || CPDEBUG < 0
97 PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
98 #define debugs if (compile_debug_print_indent(1)) ruby_debug_printf
99 #define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs(msg, stderr)), (v))
101 #define debugs if(0)printf
102 #define debug_compile(msg, v) (v)
106 /* create new label */
107 #define NEW_LABEL(l) new_label_body(iseq, l)
109 #define iseq_filename(iseq) \
110 (((rb_iseq_t*)DATA_PTR(iseq))->filename)
112 #define NEW_ISEQVAL(node, name, type) \
113 new_child_iseq(iseq, node, name, 0, type)
115 #define NEW_CHILD_ISEQVAL(node, name, type) \
116 new_child_iseq(iseq, node, name, iseq->self, type)
118 #define NEW_SPECIAQL_BLOCK_ISEQVAL(iseq, sym) \
119 new_child_iseq(iseq, iseq->node, iseq->name, iseq->parent_iseq, iseq->type, sym)
121 /* add instructions */
122 #define ADD_SEQ(seq1, seq2) \
123 APPEND_LIST(seq1, seq2)
125 /* add an instruction */
126 #define ADD_INSN(seq, line, insn) \
127 ADD_ELEM(seq, (LINK_ELEMENT *) new_insn_body(iseq, line, BIN(insn), 0))
129 /* add an instruction with label operand */
130 #define ADD_INSNL(seq, line, insn, label) \
131 ADD_ELEM(seq, (LINK_ELEMENT *) \
132 new_insn_body(iseq, line, BIN(insn), 1, (VALUE)label))
134 /* add an instruction with some operands (1, 2, 3, 5) */
135 #define ADD_INSN1(seq, line, insn, op1) \
136 ADD_ELEM(seq, (LINK_ELEMENT *) \
137 new_insn_body(iseq, line, BIN(insn), 1, (VALUE)op1))
139 #define ADD_INSN2(seq, line, insn, op1, op2) \
140 ADD_ELEM(seq, (LINK_ELEMENT *) \
141 new_insn_body(iseq, line, BIN(insn), 2, (VALUE)op1, (VALUE)op2))
143 #define ADD_INSN3(seq, line, insn, op1, op2, op3) \
144 ADD_ELEM(seq, (LINK_ELEMENT *) \
145 new_insn_body(iseq, line, BIN(insn), 3, (VALUE)op1, (VALUE)op2, (VALUE)op3))
147 /* Specific Insn factory */
148 #define ADD_SEND(seq, line, id, argc) \
149 ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(0))
151 #define ADD_CALL_RECEIVER(seq, line) \
152 ADD_INSN(seq, line, putnil)
154 #define ADD_CALL(seq, line, id, argc) \
155 ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
157 #define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
158 ADD_SEND_R(seq, line, id, argc, block, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
160 #define ADD_SEND_R(seq, line, id, argc, block, flag) \
161 ADD_ELEM(seq, (LINK_ELEMENT *) \
162 new_insn_send(iseq, line, \
163 (VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag))
165 #define ADD_TRACE(seq, line, event) \
166 if (iseq->compile_data->option->trace_instruction) { \
167 ADD_INSN1(seq, line, trace, INT2FIX(event)); \
171 #define ADD_LABEL(seq, label) \
172 ADD_ELEM(seq, (LINK_ELEMENT *) label)
174 #define ADD_ADJUST(seq, line, label) \
175 ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line))
177 #define ADD_ADJUST_RESTORE(seq, label) \
178 ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, -1))
180 #define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
181 (rb_ary_push(iseq->compile_data->catch_table_ary, \
182 rb_ary_new3(5, type, \
183 (VALUE)(ls) | 1, (VALUE)(le) | 1, \
184 iseqv, (VALUE)(lc) | 1)))
187 #define COMPILE(anchor, desc, node) \
188 (debug_compile("== " desc "\n", \
189 iseq_compile_each(iseq, anchor, node, 0)))
191 /* compile node, this node's value will be poped */
192 #define COMPILE_POPED(anchor, desc, node) \
193 (debug_compile("== " desc "\n", \
194 iseq_compile_each(iseq, anchor, node, 1)))
196 /* compile node, which is poped when 'poped' is true */
197 #define COMPILE_(anchor, desc, node, poped) \
198 (debug_compile("== " desc "\n", \
199 iseq_compile_each(iseq, anchor, node, poped)))
201 #define OPERAND_AT(insn, idx) \
202 (((INSN*)(insn))->operands[idx])
204 #define INSN_OF(insn) \
205 (((INSN*)(insn))->insn_id)
208 #define COMPILE_ERROR(strs) \
210 VALUE tmp = GET_THREAD()->errinfo; \
211 if (compile_debug) rb_compile_bug strs; \
212 GET_THREAD()->errinfo = iseq->compile_data->err_info; \
213 rb_compile_error strs; \
214 iseq->compile_data->err_info = GET_THREAD()->errinfo; \
215 GET_THREAD()->errinfo = tmp; \
220 #define ERROR_ARGS ruby_sourcefile, nd_line(node),
227 /* leave name uninitialized so that compiler warn if INIT_ANCHOR is
229 #define DECL_ANCHOR(name) \
230 LINK_ANCHOR *name, name##_body__ = {{0,},}
231 #define INIT_ANCHOR(name) \
232 (name##_body__.last = &name##_body__.anchor, name = &name##_body__)
234 #endif /* RUBY_COMPILE_H */