Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013, 2014 Damien P. George
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : : #ifndef MICROPY_INCLUDED_PY_EMIT_H
27 : : #define MICROPY_INCLUDED_PY_EMIT_H
28 : :
29 : : #include "py/lexer.h"
30 : : #include "py/scope.h"
31 : :
32 : : /* Notes on passes:
33 : : * We don't know exactly the opcodes in pass 1 because they depend on the
34 : : * closing over of variables (LOAD_CLOSURE, BUILD_TUPLE, MAKE_CLOSURE), which
35 : : * depends on determining the scope of variables in each function, and this
36 : : * is not known until the end of pass 1.
37 : : * As a consequence, we don't know the maximum stack size until the end of pass 2.
38 : : * This is problematic for some emitters (x64) since they need to know the maximum
39 : : * stack size to compile the entry to the function, and this affects code size.
40 : : */
41 : :
42 : : typedef enum {
43 : : MP_PASS_SCOPE = 1, // work out id's and their kind, and number of labels
44 : : MP_PASS_STACK_SIZE = 2, // work out maximum stack size
45 : : MP_PASS_CODE_SIZE = 3, // work out code size and label offsets
46 : : MP_PASS_EMIT = 4, // emit code (may be run multiple times if the emitter requests it)
47 : : } pass_kind_t;
48 : :
49 : : #define MP_EMIT_STAR_FLAG_SINGLE (0x01)
50 : : #define MP_EMIT_STAR_FLAG_DOUBLE (0x02)
51 : :
52 : : #define MP_EMIT_BREAK_FROM_FOR (0x8000)
53 : :
54 : : // Kind for emit_id_ops->local()
55 : : #define MP_EMIT_IDOP_LOCAL_FAST (0)
56 : : #define MP_EMIT_IDOP_LOCAL_DEREF (1)
57 : :
58 : : // Kind for emit_id_ops->global()
59 : : #define MP_EMIT_IDOP_GLOBAL_NAME (0)
60 : : #define MP_EMIT_IDOP_GLOBAL_GLOBAL (1)
61 : :
62 : : // Kind for emit->import()
63 : : #define MP_EMIT_IMPORT_NAME (0)
64 : : #define MP_EMIT_IMPORT_FROM (1)
65 : : #define MP_EMIT_IMPORT_STAR (2)
66 : :
67 : : // Kind for emit->subscr()
68 : : #define MP_EMIT_SUBSCR_LOAD (0)
69 : : #define MP_EMIT_SUBSCR_STORE (1)
70 : : #define MP_EMIT_SUBSCR_DELETE (2)
71 : :
72 : : // Kind for emit->attr()
73 : : #define MP_EMIT_ATTR_LOAD (0)
74 : : #define MP_EMIT_ATTR_STORE (1)
75 : : #define MP_EMIT_ATTR_DELETE (2)
76 : :
77 : : // Kind for emit->setup_block()
78 : : #define MP_EMIT_SETUP_BLOCK_WITH (0)
79 : : #define MP_EMIT_SETUP_BLOCK_EXCEPT (1)
80 : : #define MP_EMIT_SETUP_BLOCK_FINALLY (2)
81 : :
82 : : // Kind for emit->build()
83 : : #define MP_EMIT_BUILD_TUPLE (0)
84 : : #define MP_EMIT_BUILD_LIST (1)
85 : : #define MP_EMIT_BUILD_MAP (2)
86 : : #define MP_EMIT_BUILD_SET (3)
87 : : #define MP_EMIT_BUILD_SLICE (4)
88 : :
89 : : // Kind for emit->yield()
90 : : #define MP_EMIT_YIELD_VALUE (0)
91 : : #define MP_EMIT_YIELD_FROM (1)
92 : :
93 : : typedef struct _emit_t emit_t;
94 : :
95 : : typedef struct _mp_emit_common_t {
96 : : pass_kind_t pass;
97 : : uint16_t ct_cur_child;
98 : : mp_raw_code_t **children;
99 : : #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE
100 : : mp_map_t qstr_map;
101 : : #endif
102 : : mp_obj_list_t const_obj_list;
103 : : } mp_emit_common_t;
104 : :
105 : : typedef struct _mp_emit_method_table_id_ops_t {
106 : : void (*local)(emit_t *emit, qstr qst, mp_uint_t local_num, int kind);
107 : : void (*global)(emit_t *emit, qstr qst, int kind);
108 : : } mp_emit_method_table_id_ops_t;
109 : :
110 : : typedef struct _emit_method_table_t {
111 : : #if MICROPY_DYNAMIC_COMPILER
112 : : emit_t *(*emit_new)(mp_emit_common_t * emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
113 : : void (*emit_free)(emit_t *emit);
114 : : #endif
115 : :
116 : : void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope);
117 : : bool (*end_pass)(emit_t *emit);
118 : : void (*adjust_stack_size)(emit_t *emit, mp_int_t delta);
119 : : void (*set_source_line)(emit_t *emit, mp_uint_t line);
120 : :
121 : : mp_emit_method_table_id_ops_t load_id;
122 : : mp_emit_method_table_id_ops_t store_id;
123 : : mp_emit_method_table_id_ops_t delete_id;
124 : :
125 : : void (*label_assign)(emit_t *emit, mp_uint_t l);
126 : : void (*import)(emit_t *emit, qstr qst, int kind);
127 : : void (*load_const_tok)(emit_t *emit, mp_token_kind_t tok);
128 : : void (*load_const_small_int)(emit_t *emit, mp_int_t arg);
129 : : void (*load_const_str)(emit_t *emit, qstr qst);
130 : : void (*load_const_obj)(emit_t *emit, mp_obj_t obj);
131 : : void (*load_null)(emit_t *emit);
132 : : void (*load_method)(emit_t *emit, qstr qst, bool is_super);
133 : : void (*load_build_class)(emit_t *emit);
134 : : void (*subscr)(emit_t *emit, int kind);
135 : : void (*attr)(emit_t *emit, qstr qst, int kind);
136 : : void (*dup_top)(emit_t *emit);
137 : : void (*dup_top_two)(emit_t *emit);
138 : : void (*pop_top)(emit_t *emit);
139 : : void (*rot_two)(emit_t *emit);
140 : : void (*rot_three)(emit_t *emit);
141 : : void (*jump)(emit_t *emit, mp_uint_t label);
142 : : void (*pop_jump_if)(emit_t *emit, bool cond, mp_uint_t label);
143 : : void (*jump_if_or_pop)(emit_t *emit, bool cond, mp_uint_t label);
144 : : void (*unwind_jump)(emit_t *emit, mp_uint_t label, mp_uint_t except_depth);
145 : : void (*setup_block)(emit_t *emit, mp_uint_t label, int kind);
146 : : void (*with_cleanup)(emit_t *emit, mp_uint_t label);
147 : : #if MICROPY_PY_ASYNC_AWAIT
148 : : void (*async_with_setup_finally)(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump);
149 : : #endif
150 : : void (*end_finally)(emit_t *emit);
151 : : void (*get_iter)(emit_t *emit, bool use_stack);
152 : : void (*for_iter)(emit_t *emit, mp_uint_t label);
153 : : void (*for_iter_end)(emit_t *emit);
154 : : void (*pop_except_jump)(emit_t *emit, mp_uint_t label, bool within_exc_handler);
155 : : void (*unary_op)(emit_t *emit, mp_unary_op_t op);
156 : : void (*binary_op)(emit_t *emit, mp_binary_op_t op);
157 : : void (*build)(emit_t *emit, mp_uint_t n_args, int kind);
158 : : void (*store_map)(emit_t *emit);
159 : : void (*store_comp)(emit_t *emit, scope_kind_t kind, mp_uint_t set_stack_index);
160 : : void (*unpack_sequence)(emit_t *emit, mp_uint_t n_args);
161 : : void (*unpack_ex)(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right);
162 : : void (*make_function)(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults);
163 : : void (*make_closure)(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults);
164 : : void (*call_function)(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags);
165 : : void (*call_method)(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags);
166 : : void (*return_value)(emit_t *emit);
167 : : void (*raise_varargs)(emit_t *emit, mp_uint_t n_args);
168 : : void (*yield)(emit_t *emit, int kind);
169 : :
170 : : // these methods are used to control entry to/exit from an exception handler
171 : : // they may or may not emit code
172 : : void (*start_except_handler)(emit_t *emit);
173 : : void (*end_except_handler)(emit_t *emit);
174 : : } emit_method_table_t;
175 : :
176 : : #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE
177 : : qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst);
178 : : #else
179 : : static inline qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) {
180 : : return qst;
181 : : }
182 : : #endif
183 : :
184 : : size_t mp_emit_common_use_const_obj(mp_emit_common_t *emit, mp_obj_t const_obj);
185 : :
186 : 26858 : static inline size_t mp_emit_common_alloc_const_child(mp_emit_common_t *emit, mp_raw_code_t *rc) {
187 [ + + ]: 26858 : if (emit->pass == MP_PASS_EMIT) {
188 : 6741 : emit->children[emit->ct_cur_child] = rc;
189 : : }
190 : 26858 : return emit->ct_cur_child++;
191 : : }
192 : :
193 : 84943 : static inline void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst) {
194 : 84943 : scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);
195 : 84947 : }
196 : :
197 : : id_info_t *mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst);
198 : : void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emit_method_table, scope_t *scope, qstr qst);
199 : :
200 : : extern const emit_method_table_t emit_bc_method_table;
201 : : extern const emit_method_table_t emit_native_x64_method_table;
202 : : extern const emit_method_table_t emit_native_x86_method_table;
203 : : extern const emit_method_table_t emit_native_thumb_method_table;
204 : : extern const emit_method_table_t emit_native_arm_method_table;
205 : : extern const emit_method_table_t emit_native_xtensa_method_table;
206 : : extern const emit_method_table_t emit_native_xtensawin_method_table;
207 : : extern const emit_method_table_t emit_native_rv32_method_table;
208 : : extern const emit_method_table_t emit_native_debug_method_table;
209 : :
210 : : extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops;
211 : : extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops;
212 : : extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops;
213 : :
214 : : emit_t *emit_bc_new(mp_emit_common_t *emit_common);
215 : : emit_t *emit_native_x64_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
216 : : emit_t *emit_native_x86_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
217 : : emit_t *emit_native_thumb_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
218 : : emit_t *emit_native_arm_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
219 : : emit_t *emit_native_xtensa_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
220 : : emit_t *emit_native_xtensawin_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
221 : : emit_t *emit_native_rv32_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
222 : : emit_t *emit_native_debug_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
223 : :
224 : : void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels);
225 : :
226 : : void emit_bc_free(emit_t *emit);
227 : : void emit_native_x64_free(emit_t *emit);
228 : : void emit_native_x86_free(emit_t *emit);
229 : : void emit_native_thumb_free(emit_t *emit);
230 : : void emit_native_arm_free(emit_t *emit);
231 : : void emit_native_xtensa_free(emit_t *emit);
232 : : void emit_native_xtensawin_free(emit_t *emit);
233 : : void emit_native_rv32_free(emit_t *emit);
234 : : void emit_native_debug_free(emit_t *emit);
235 : :
236 : : void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope);
237 : : bool mp_emit_bc_end_pass(emit_t *emit);
238 : : void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta);
239 : : void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t line);
240 : :
241 : : void mp_emit_bc_load_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind);
242 : : void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind);
243 : : void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind);
244 : : void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind);
245 : : void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind);
246 : : void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind);
247 : :
248 : : void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l);
249 : : void mp_emit_bc_import(emit_t *emit, qstr qst, int kind);
250 : : void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok);
251 : : void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg);
252 : : void mp_emit_bc_load_const_str(emit_t *emit, qstr qst);
253 : : void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj);
254 : : void mp_emit_bc_load_null(emit_t *emit);
255 : : void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super);
256 : : void mp_emit_bc_load_build_class(emit_t *emit);
257 : : void mp_emit_bc_subscr(emit_t *emit, int kind);
258 : : void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind);
259 : : void mp_emit_bc_dup_top(emit_t *emit);
260 : : void mp_emit_bc_dup_top_two(emit_t *emit);
261 : : void mp_emit_bc_pop_top(emit_t *emit);
262 : : void mp_emit_bc_rot_two(emit_t *emit);
263 : : void mp_emit_bc_rot_three(emit_t *emit);
264 : : void mp_emit_bc_jump(emit_t *emit, mp_uint_t label);
265 : : void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label);
266 : : void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label);
267 : : void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth);
268 : : void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind);
269 : : void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label);
270 : : #if MICROPY_PY_ASYNC_AWAIT
271 : : void mp_emit_bc_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump);
272 : : #endif
273 : : void mp_emit_bc_end_finally(emit_t *emit);
274 : : void mp_emit_bc_get_iter(emit_t *emit, bool use_stack);
275 : : void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label);
276 : : void mp_emit_bc_for_iter_end(emit_t *emit);
277 : : void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler);
278 : : void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op);
279 : : void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op);
280 : : void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind);
281 : : void mp_emit_bc_store_map(emit_t *emit);
282 : : void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t list_stack_index);
283 : : void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args);
284 : : void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right);
285 : : void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults);
286 : : void mp_emit_bc_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults);
287 : : void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags);
288 : : void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags);
289 : : void mp_emit_bc_return_value(emit_t *emit);
290 : : void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args);
291 : : void mp_emit_bc_yield(emit_t *emit, int kind);
292 : : void mp_emit_bc_start_except_handler(emit_t *emit);
293 : : void mp_emit_bc_end_except_handler(emit_t *emit);
294 : :
295 : : typedef struct _emit_inline_asm_t emit_inline_asm_t;
296 : :
297 : : typedef struct _emit_inline_asm_method_table_t {
298 : : #if MICROPY_DYNAMIC_COMPILER
299 : : emit_inline_asm_t *(*asm_new)(mp_uint_t max_num_labels);
300 : : void (*asm_free)(emit_inline_asm_t *emit);
301 : : #endif
302 : :
303 : : void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, mp_obj_t *error_slot);
304 : : void (*end_pass)(emit_inline_asm_t *emit, mp_uint_t type_sig);
305 : : mp_uint_t (*count_params)(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params);
306 : : bool (*label)(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id);
307 : : void (*op)(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args);
308 : : } emit_inline_asm_method_table_t;
309 : :
310 : : extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table;
311 : : extern const emit_inline_asm_method_table_t emit_inline_xtensa_method_table;
312 : :
313 : : emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels);
314 : : emit_inline_asm_t *emit_inline_xtensa_new(mp_uint_t max_num_labels);
315 : :
316 : : void emit_inline_thumb_free(emit_inline_asm_t *emit);
317 : : void emit_inline_xtensa_free(emit_inline_asm_t *emit);
318 : :
319 : : #if MICROPY_WARNINGS
320 : : void mp_emitter_warning(pass_kind_t pass, const char *msg);
321 : : #else
322 : : #define mp_emitter_warning(pass, msg)
323 : : #endif
324 : :
325 : : #endif // MICROPY_INCLUDED_PY_EMIT_H
|