1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/* Notes on passes:
* We don't know exactly the opcodes in pass 1 because they depend on the
* closing over of variables (LOAD_CLOSURE, BUILD_TUPLE, MAKE_CLOSURE), which
* depends on determining the scope of variables in each function, and this
* is not known until the end of pass 1.
* As a consequence, we don't know the maximum stack size until the end of pass 2.
* This is problematic for some emitters (x64) since they need to know the maximum
* stack size to compile the entry to the function, and this affects code size.
*/
typedef enum {
PASS_1 = 1, // work out id's and their kind, and number of labels
PASS_2 = 2, // work out stack size and code size and label offsets
PASS_3 = 3, // emit code
} pass_kind_t;
#define MP_EMIT_STAR_FLAG_SINGLE (0x01)
#define MP_EMIT_STAR_FLAG_DOUBLE (0x02)
typedef struct _emit_t emit_t;
typedef struct _emit_method_table_t {
void (*set_native_types)(emit_t *emit, bool do_native_types);
void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope);
void (*end_pass)(emit_t *emit);
bool (*last_emit_was_return_value)(emit_t *emit);
void (*adjust_stack_size)(emit_t *emit, int delta);
void (*set_line_number)(emit_t *emit, int line);
void (*load_id)(emit_t *emit, qstr qstr);
void (*store_id)(emit_t *emit, qstr qstr);
void (*delete_id)(emit_t *emit, qstr qstr);
void (*label_assign)(emit_t *emit, uint l);
void (*import_name)(emit_t *emit, qstr qstr);
void (*import_from)(emit_t *emit, qstr qstr);
void (*import_star)(emit_t *emit);
void (*load_const_tok)(emit_t *emit, mp_token_kind_t tok);
void (*load_const_small_int)(emit_t *emit, machine_int_t arg);
void (*load_const_int)(emit_t *emit, qstr qstr);
void (*load_const_dec)(emit_t *emit, qstr qstr);
void (*load_const_id)(emit_t *emit, qstr qstr);
void (*load_const_str)(emit_t *emit, qstr qstr, bool bytes);
void (*load_const_verbatim_str)(emit_t *emit, const char *str); // only needed for emitcpy
void (*load_fast)(emit_t *emit, qstr qstr, uint id_flags, int local_num);
void (*load_deref)(emit_t *emit, qstr qstr, int local_num);
void (*load_closure)(emit_t *emit, qstr qstr, int local_num); // only needed for emitcpy
void (*load_name)(emit_t *emit, qstr qstr);
void (*load_global)(emit_t *emit, qstr qstr);
void (*load_attr)(emit_t *emit, qstr qstr);
void (*load_method)(emit_t *emit, qstr qstr);
void (*load_build_class)(emit_t *emit);
void (*load_subscr)(emit_t *emit);
void (*store_fast)(emit_t *emit, qstr qstr, int local_num);
void (*store_deref)(emit_t *emit, qstr qstr, int local_num);
void (*store_name)(emit_t *emit, qstr qstr);
void (*store_global)(emit_t *emit, qstr qstr);
void (*store_attr)(emit_t *emit, qstr qstr);
void (*store_subscr)(emit_t *emit);
void (*delete_fast)(emit_t *emit, qstr qstr, int local_num);
void (*delete_deref)(emit_t *emit, qstr qstr, int local_num);
void (*delete_name)(emit_t *emit, qstr qstr);
void (*delete_global)(emit_t *emit, qstr qstr);
void (*delete_attr)(emit_t *emit, qstr qstr);
void (*delete_subscr)(emit_t *emit);
void (*dup_top)(emit_t *emit);
void (*dup_top_two)(emit_t *emit);
void (*pop_top)(emit_t *emit);
void (*rot_two)(emit_t *emit);
void (*rot_three)(emit_t *emit);
void (*jump)(emit_t *emit, uint label);
void (*pop_jump_if_true)(emit_t *emit, uint label);
void (*pop_jump_if_false)(emit_t *emit, uint label);
void (*jump_if_true_or_pop)(emit_t *emit, uint label);
void (*jump_if_false_or_pop)(emit_t *emit, uint label);
void (*setup_loop)(emit_t *emit, uint label);
void (*break_loop)(emit_t *emit, uint label, int except_depth);
void (*continue_loop)(emit_t *emit, uint label, int except_depth);
void (*setup_with)(emit_t *emit, uint label);
void (*with_cleanup)(emit_t *emit);
void (*setup_except)(emit_t *emit, uint label);
void (*setup_finally)(emit_t *emit, uint label);
void (*end_finally)(emit_t *emit);
void (*get_iter)(emit_t *emit);
void (*for_iter)(emit_t *emit, uint label);
void (*for_iter_end)(emit_t *emit);
void (*pop_block)(emit_t *emit);
void (*pop_except)(emit_t *emit);
void (*unary_op)(emit_t *emit, mp_unary_op_t op);
void (*binary_op)(emit_t *emit, mp_binary_op_t op);
void (*build_tuple)(emit_t *emit, int n_args);
void (*build_list)(emit_t *emit, int n_args);
void (*list_append)(emit_t *emit, int list_stack_index);
void (*build_map)(emit_t *emit, int n_args);
void (*store_map)(emit_t *emit);
void (*map_add)(emit_t *emit, int map_stack_index);
void (*build_set)(emit_t *emit, int n_args);
void (*set_add)(emit_t *emit, int set_stack_index);
void (*build_slice)(emit_t *emit, int n_args);
void (*unpack_sequence)(emit_t *emit, int n_args);
void (*unpack_ex)(emit_t *emit, int n_left, int n_right);
void (*make_function)(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults);
void (*make_closure)(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults);
void (*call_function)(emit_t *emit, int n_positional, int n_keyword, uint star_flags);
void (*call_method)(emit_t *emit, int n_positional, int n_keyword, uint star_flags);
void (*return_value)(emit_t *emit);
void (*raise_varargs)(emit_t *emit, int n_args);
void (*yield_value)(emit_t *emit);
void (*yield_from)(emit_t *emit);
} emit_method_table_t;
void emit_common_load_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr);
void emit_common_store_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr);
void emit_common_delete_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr);
extern const emit_method_table_t emit_pass1_method_table;
extern const emit_method_table_t emit_cpython_method_table;
extern const emit_method_table_t emit_bc_method_table;
extern const emit_method_table_t emit_native_x64_method_table;
extern const emit_method_table_t emit_native_thumb_method_table;
emit_t *emit_pass1_new(void);
emit_t *emit_cpython_new(uint max_num_labels);
emit_t *emit_bc_new(uint max_num_labels);
emit_t *emit_native_x64_new(uint max_num_labels);
emit_t *emit_native_thumb_new(uint max_num_labels);
void emit_pass1_free(emit_t *emit);
void emit_bc_free(emit_t *emit);
void emit_native_x64_free(emit_t *emit);
void emit_native_thumb_free(emit_t *emit);
typedef struct _emit_inline_asm_t emit_inline_asm_t;
typedef struct _emit_inline_asm_method_table_t {
void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope);
bool (*end_pass)(emit_inline_asm_t *emit);
int (*count_params)(emit_inline_asm_t *emit, int n_params, mp_parse_node_t *pn_params);
void (*label)(emit_inline_asm_t *emit, uint label_num, qstr label_id);
void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args);
} emit_inline_asm_method_table_t;
extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table;
emit_inline_asm_t *emit_inline_thumb_new(uint max_num_labels);
void emit_inline_thumb_free(emit_inline_asm_t *emit);
|