blob: 27540f18de7c178326db259673ab44ef758e6967 [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <unistd.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <stdio.h>
5#include <string.h>
6#include <assert.h>
7
8#include "misc.h"
9#include "lexer.h"
10#include "machine.h"
11#include "parse.h"
12#include "compile.h"
13#include "scope.h"
14#include "runtime.h"
15#include "emit.h"
16#include "bc.h"
17
Damien415eb6f2013-10-05 12:19:06 +010018struct _emit_t {
19 pass_kind_t pass;
Damien429d7192013-10-04 19:53:11 +010020 int next_label;
21 int stack_size;
22 bool last_emit_was_return_value;
23
24 scope_t *scope;
25
26 int max_num_labels;
27 uint *label_offsets;
28
29 uint code_offset;
30 uint code_size;
31 byte *code_base;
32 byte dummy_data[8];
33};
34
Damien415eb6f2013-10-05 12:19:06 +010035uint emit_bc_get_code_size(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010036 return emit->code_size;
37}
38
Damien415eb6f2013-10-05 12:19:06 +010039void* emit_bc_get_code(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010040 return emit->code_base;
41}
42
Damien415eb6f2013-10-05 12:19:06 +010043static void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
44}
45
46static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
Damien429d7192013-10-04 19:53:11 +010047 emit->pass = pass;
48 emit->next_label = 1;
49 emit->stack_size = 0;
50 emit->last_emit_was_return_value = false;
51 emit->scope = scope;
52 if (pass == PASS_1) {
53 scope->unique_code_id = rt_get_new_unique_code_id();
54 } else if (pass > PASS_1) {
55 if (emit->label_offsets == NULL) {
56 emit->label_offsets = m_new(uint, emit->max_num_labels);
57 }
58 if (pass == PASS_2) {
59 memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
60 }
61 }
62 emit->code_offset = 0;
63}
64
Damien415eb6f2013-10-05 12:19:06 +010065static void emit_bc_end_pass(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +010066 // check stack is back to zero size
67 if (emit->stack_size != 0) {
68 printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
69 }
70
71 if (emit->pass == PASS_1) {
72 // calculate number of labels need
73 if (emit->next_label > emit->max_num_labels) {
74 emit->max_num_labels = emit->next_label;
75 }
76
77 } else if (emit->pass == PASS_2) {
78 // calculate size of code in bytes
79 emit->code_size = emit->code_offset;
80 emit->code_base = m_new(byte, emit->code_size);
81 printf("code_size: %u\n", emit->code_size);
82
83 } else if (emit->pass == PASS_3) {
84 rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_size, emit->scope->num_params);
85 }
86}
87
88// all functions must go through this one to emit bytes
Damien415eb6f2013-10-05 12:19:06 +010089static byte* emit_get_cur_to_write_bytes(emit_t* emit, int num_bytes_to_write) {
Damien429d7192013-10-04 19:53:11 +010090 //printf("emit %d\n", num_bytes_to_write);
91 if (emit->pass < PASS_3) {
92 emit->code_offset += num_bytes_to_write;
93 return emit->dummy_data;
94 } else {
95 assert(emit->code_offset + num_bytes_to_write <= emit->code_size);
96 byte *c = emit->code_base + emit->code_offset;
97 emit->code_offset += num_bytes_to_write;
98 return c;
99 }
100}
101
Damien415eb6f2013-10-05 12:19:06 +0100102static void emit_write_byte_1(emit_t* emit, byte b1) {
Damien429d7192013-10-04 19:53:11 +0100103 byte* c = emit_get_cur_to_write_bytes(emit, 1);
104 c[0] = b1;
105}
106
Damien415eb6f2013-10-05 12:19:06 +0100107static void emit_write_byte_1_byte(emit_t* emit, byte b1, uint b2) {
Damien429d7192013-10-04 19:53:11 +0100108 assert((b2 & (~0xff)) == 0);
109 byte* c = emit_get_cur_to_write_bytes(emit, 2);
110 c[0] = b1;
111 c[1] = b2;
112}
113
Damien415eb6f2013-10-05 12:19:06 +0100114static void emit_write_byte_1_int(emit_t* emit, byte b1, int num) {
Damien429d7192013-10-04 19:53:11 +0100115 assert((num & (~0x7fff)) == 0 || (num & (~0x7fff)) == (~0x7fff));
116 byte* c = emit_get_cur_to_write_bytes(emit, 3);
117 c[0] = b1;
118 c[1] = num;
119 c[2] = num >> 8;
120}
121
Damien415eb6f2013-10-05 12:19:06 +0100122static void emit_write_byte_1_uint(emit_t* emit, byte b1, uint num) {
Damien429d7192013-10-04 19:53:11 +0100123 if (num <= 127) { // fits in 0x7f
124 // fit argument in single byte
125 byte* c = emit_get_cur_to_write_bytes(emit, 2);
126 c[0] = b1;
127 c[1] = num;
128 } else if (num <= 16383) { // fits in 0x3fff
129 // fit argument in two bytes
130 byte* c = emit_get_cur_to_write_bytes(emit, 3);
131 c[0] = b1;
132 c[1] = (num >> 8) | 0x80;
133 c[2] = num;
134 } else {
135 // larger numbers not implemented/supported
136 assert(0);
137 }
138}
139
Damien415eb6f2013-10-05 12:19:06 +0100140static void emit_write_byte_1_qstr(emit_t* emit, byte b1, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100141 emit_write_byte_1_uint(emit, b1, qstr);
142}
143
Damien415eb6f2013-10-05 12:19:06 +0100144static void emit_write_byte_1_label(emit_t* emit, byte b1, int label) {
Damien429d7192013-10-04 19:53:11 +0100145 uint code_offset;
146 if (emit->pass < PASS_3) {
147 code_offset = 0;
148 } else {
149 code_offset = emit->label_offsets[label];
150 }
151 emit_write_byte_1_uint(emit, b1, code_offset);
152}
153
Damien415eb6f2013-10-05 12:19:06 +0100154bool emit_bc_last_emit_was_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100155 return emit->last_emit_was_return_value;
156}
157
Damien415eb6f2013-10-05 12:19:06 +0100158int emit_bc_get_stack_size(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100159 return emit->stack_size;
160}
161
Damien415eb6f2013-10-05 12:19:06 +0100162static void emit_bc_set_stack_size(emit_t *emit, int size) {
Damien429d7192013-10-04 19:53:11 +0100163 if (emit->pass > PASS_1) {
164 emit->stack_size = size;
165 }
166}
167
Damien415eb6f2013-10-05 12:19:06 +0100168static void emit_pre(emit_t *emit, int stack_size_delta) {
Damien429d7192013-10-04 19:53:11 +0100169 if (emit->pass > PASS_1) {
170 emit->stack_size += stack_size_delta;
171 if (emit->stack_size > emit->scope->stack_size) {
172 emit->scope->stack_size = emit->stack_size;
173 }
174 }
175 emit->last_emit_was_return_value = false;
176}
177
Damien415eb6f2013-10-05 12:19:06 +0100178static int emit_bc_label_new(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100179 return emit->next_label++;
180}
181
Damien415eb6f2013-10-05 12:19:06 +0100182static void emit_bc_label_assign(emit_t *emit, int l) {
Damien429d7192013-10-04 19:53:11 +0100183 emit_pre(emit, 0);
184 if (emit->pass > PASS_1) {
185 assert(l < emit->max_num_labels);
186 if (emit->pass == PASS_2) {
187 // assign label offset
188 assert(emit->label_offsets[l] == -1);
189 emit->label_offsets[l] = emit->code_offset;
190 } else if (emit->pass == PASS_3) {
191 // ensure label offset has not changed from PASS_2 to PASS_3
192 assert(emit->label_offsets[l] == emit->code_offset);
193 //printf("l%d: (at %d)\n", l, emit->code_offset);
194 }
195 }
196}
197
Damien415eb6f2013-10-05 12:19:06 +0100198static void emit_bc_import_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100199 emit_pre(emit, -1);
200 emit_write_byte_1_qstr(emit, PYBC_IMPORT_NAME, qstr);
201}
202
Damien415eb6f2013-10-05 12:19:06 +0100203static void emit_bc_import_from(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100204 emit_pre(emit, 1);
205 emit_write_byte_1_qstr(emit, PYBC_IMPORT_FROM, qstr);
206}
207
Damien415eb6f2013-10-05 12:19:06 +0100208static void emit_bc_import_star(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100209 emit_pre(emit, -1);
210 emit_write_byte_1(emit, PYBC_IMPORT_STAR);
211}
212
Damien415eb6f2013-10-05 12:19:06 +0100213static void emit_bc_load_const_tok(emit_t *emit, py_token_kind_t tok) {
Damien429d7192013-10-04 19:53:11 +0100214 emit_pre(emit, 1);
215 switch (tok) {
216 case PY_TOKEN_KW_FALSE: emit_write_byte_1(emit, PYBC_LOAD_CONST_FALSE); break;
217 case PY_TOKEN_KW_NONE: emit_write_byte_1(emit, PYBC_LOAD_CONST_NONE); break;
218 case PY_TOKEN_KW_TRUE: emit_write_byte_1(emit, PYBC_LOAD_CONST_TRUE); break;
219 default: assert(0);
220 }
221}
222
Damien415eb6f2013-10-05 12:19:06 +0100223static void emit_bc_load_const_small_int(emit_t *emit, int arg) {
Damien429d7192013-10-04 19:53:11 +0100224 emit_pre(emit, 1);
225 emit_write_byte_1_int(emit, PYBC_LOAD_CONST_SMALL_INT, arg);
226}
227
Damien415eb6f2013-10-05 12:19:06 +0100228static void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100229 emit_pre(emit, 1);
230 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_INT, qstr);
231}
232
Damien415eb6f2013-10-05 12:19:06 +0100233static void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100234 emit_pre(emit, 1);
235 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_DEC, qstr);
236}
237
Damien415eb6f2013-10-05 12:19:06 +0100238static void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100239 emit_pre(emit, 1);
240 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_ID, qstr);
241}
242
Damien415eb6f2013-10-05 12:19:06 +0100243static void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100244 emit_pre(emit, 1);
245 if (bytes) {
246 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_BYTES, qstr);
247 } else {
248 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_STRING, qstr);
249 }
250}
251
Damien415eb6f2013-10-05 12:19:06 +0100252static void emit_bc_load_const_verbatim_start(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100253 emit_pre(emit, 1);
254 assert(0);
255}
256
Damien415eb6f2013-10-05 12:19:06 +0100257static void emit_bc_load_const_verbatim_int(emit_t *emit, int val) {
Damien429d7192013-10-04 19:53:11 +0100258 assert(0);
259}
260
Damien415eb6f2013-10-05 12:19:06 +0100261static void emit_bc_load_const_verbatim_str(emit_t *emit, const char *str) {
Damien429d7192013-10-04 19:53:11 +0100262 assert(0);
263}
264
Damien415eb6f2013-10-05 12:19:06 +0100265static void emit_bc_load_const_verbatim_strn(emit_t *emit, const char *str, int len) {
Damien429d7192013-10-04 19:53:11 +0100266 assert(0);
267}
268
Damien415eb6f2013-10-05 12:19:06 +0100269static void emit_bc_load_const_verbatim_quoted_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100270 assert(0);
271}
272
Damien415eb6f2013-10-05 12:19:06 +0100273static void emit_bc_load_const_verbatim_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100274 assert(0);
275}
276
Damien415eb6f2013-10-05 12:19:06 +0100277static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100278 assert(local_num >= 0);
279 emit_pre(emit, 1);
280 switch (local_num) {
281 case 0: emit_write_byte_1(emit, PYBC_LOAD_FAST_0); break;
282 case 1: emit_write_byte_1(emit, PYBC_LOAD_FAST_1); break;
283 case 2: emit_write_byte_1(emit, PYBC_LOAD_FAST_2); break;
284 default: emit_write_byte_1_uint(emit, PYBC_LOAD_FAST_N, local_num); break;
285 }
286}
287
Damien415eb6f2013-10-05 12:19:06 +0100288static void emit_bc_load_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100289 emit_pre(emit, 1);
290 emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
291}
292
Damien415eb6f2013-10-05 12:19:06 +0100293static void emit_bc_load_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100294 emit_pre(emit, 1);
295 emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
296}
297
Damien415eb6f2013-10-05 12:19:06 +0100298static void emit_bc_load_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100299 emit_pre(emit, 1);
300 assert(0);
301}
302
Damien415eb6f2013-10-05 12:19:06 +0100303static void emit_bc_load_closure(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100304 emit_pre(emit, 1);
305 assert(0);
306}
307
Damien415eb6f2013-10-05 12:19:06 +0100308static void emit_bc_load_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100309 emit_pre(emit, 0);
310 emit_write_byte_1_qstr(emit, PYBC_LOAD_ATTR, qstr);
311}
312
Damien415eb6f2013-10-05 12:19:06 +0100313static void emit_bc_load_method(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100314 emit_pre(emit, 0);
315 emit_write_byte_1_qstr(emit, PYBC_LOAD_METHOD, qstr);
316}
317
Damien415eb6f2013-10-05 12:19:06 +0100318static void emit_bc_load_build_class(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100319 emit_pre(emit, 1);
320 emit_write_byte_1(emit, PYBC_LOAD_BUILD_CLASS);
321}
322
Damien415eb6f2013-10-05 12:19:06 +0100323static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100324 assert(local_num >= 0);
325 emit_pre(emit, -1);
326 switch (local_num) {
327 case 0: emit_write_byte_1(emit, PYBC_STORE_FAST_0); break;
328 case 1: emit_write_byte_1(emit, PYBC_STORE_FAST_1); break;
329 case 2: emit_write_byte_1(emit, PYBC_STORE_FAST_2); break;
330 default: emit_write_byte_1_uint(emit, PYBC_STORE_FAST_N, local_num); break;
331 }
332}
333
Damien415eb6f2013-10-05 12:19:06 +0100334static void emit_bc_store_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100335 emit_pre(emit, -1);
336 emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr);
337}
338
Damien415eb6f2013-10-05 12:19:06 +0100339static void emit_bc_store_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100340 emit_pre(emit, -1);
341 emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
342}
343
Damien415eb6f2013-10-05 12:19:06 +0100344static void emit_bc_store_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100345 emit_pre(emit, -1);
346 assert(0);
347}
348
Damien415eb6f2013-10-05 12:19:06 +0100349static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100350 emit_pre(emit, -2);
351 emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr);
352}
353
Damien415eb6f2013-10-05 12:19:06 +0100354static void emit_bc_store_locals(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100355 emit_pre(emit, -1);
356 emit_write_byte_1(emit, PYBC_STORE_LOCALS);
357}
358
Damien415eb6f2013-10-05 12:19:06 +0100359static void emit_bc_store_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100360 emit_pre(emit, -3);
361 emit_write_byte_1(emit, PYBC_STORE_SUBSCR);
362}
363
Damien415eb6f2013-10-05 12:19:06 +0100364static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100365 assert(local_num >= 0);
366 emit_pre(emit, 0);
367 emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
368}
369
Damien415eb6f2013-10-05 12:19:06 +0100370static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100371 emit_pre(emit, 0);
372 emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr);
373}
374
Damien415eb6f2013-10-05 12:19:06 +0100375static void emit_bc_delete_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100376 emit_pre(emit, 0);
377 emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
378}
379
Damien415eb6f2013-10-05 12:19:06 +0100380static void emit_bc_delete_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100381 emit_pre(emit, 0);
382 emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, qstr);
383}
384
Damien415eb6f2013-10-05 12:19:06 +0100385static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100386 emit_pre(emit, -1);
387 emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr);
388}
389
Damien415eb6f2013-10-05 12:19:06 +0100390static void emit_bc_delete_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100391 emit_pre(emit, -2);
392 emit_write_byte_1(emit, PYBC_DELETE_SUBSCR);
393}
394
Damien415eb6f2013-10-05 12:19:06 +0100395static void emit_bc_dup_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100396 emit_pre(emit, 1);
397 emit_write_byte_1(emit, PYBC_DUP_TOP);
398}
399
Damien415eb6f2013-10-05 12:19:06 +0100400static void emit_bc_dup_top_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100401 emit_pre(emit, 2);
402 emit_write_byte_1(emit, PYBC_DUP_TOP_TWO);
403}
404
Damien415eb6f2013-10-05 12:19:06 +0100405static void emit_bc_pop_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100406 emit_pre(emit, -1);
407 emit_write_byte_1(emit, PYBC_POP_TOP);
408}
409
Damien415eb6f2013-10-05 12:19:06 +0100410static void emit_bc_rot_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100411 emit_pre(emit, 0);
412 emit_write_byte_1(emit, PYBC_ROT_TWO);
413}
414
Damien415eb6f2013-10-05 12:19:06 +0100415static void emit_bc_rot_three(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100416 emit_pre(emit, 0);
417 emit_write_byte_1(emit, PYBC_ROT_THREE);
418}
419
Damien415eb6f2013-10-05 12:19:06 +0100420static void emit_bc_jump(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100421 emit_pre(emit, 0);
422 emit_write_byte_1_label(emit, PYBC_JUMP, label);
423}
424
Damien415eb6f2013-10-05 12:19:06 +0100425static void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100426 emit_pre(emit, -1);
427 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_TRUE, label);
428}
429
Damien415eb6f2013-10-05 12:19:06 +0100430static void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100431 emit_pre(emit, -1);
432 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_FALSE, label);
433}
434
Damien415eb6f2013-10-05 12:19:06 +0100435static void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100436 emit_pre(emit, -1);
437 emit_write_byte_1_label(emit, PYBC_JUMP_IF_TRUE_OR_POP, label);
438}
439
Damien415eb6f2013-10-05 12:19:06 +0100440static void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100441 emit_pre(emit, -1);
442 emit_write_byte_1_label(emit, PYBC_JUMP_IF_FALSE_OR_POP, label);
443}
444
Damien415eb6f2013-10-05 12:19:06 +0100445static void emit_bc_setup_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100446 emit_pre(emit, 0);
447 emit_write_byte_1_label(emit, PYBC_SETUP_LOOP, label);
448}
449
Damien415eb6f2013-10-05 12:19:06 +0100450static void emit_bc_break_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100451 emit_pre(emit, 0);
452 emit_write_byte_1_label(emit, PYBC_BREAK_LOOP, label);
453}
454
Damien415eb6f2013-10-05 12:19:06 +0100455static void emit_bc_continue_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100456 emit_pre(emit, 0);
457 emit_write_byte_1_label(emit, PYBC_CONTINUE_LOOP, label);
458}
459
Damien415eb6f2013-10-05 12:19:06 +0100460static void emit_bc_setup_with(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100461 emit_pre(emit, 7);
462 emit_write_byte_1_label(emit, PYBC_SETUP_WITH, label);
463}
464
Damien415eb6f2013-10-05 12:19:06 +0100465static void emit_bc_with_cleanup(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100466 emit_pre(emit, -7);
467 emit_write_byte_1(emit, PYBC_WITH_CLEANUP);
468}
469
Damien415eb6f2013-10-05 12:19:06 +0100470static void emit_bc_setup_except(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100471 emit_pre(emit, 6);
472 emit_write_byte_1_label(emit, PYBC_SETUP_EXCEPT, label);
473}
474
Damien415eb6f2013-10-05 12:19:06 +0100475static void emit_bc_setup_finally(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100476 emit_pre(emit, 6);
477 emit_write_byte_1_label(emit, PYBC_SETUP_FINALLY, label);
478}
479
Damien415eb6f2013-10-05 12:19:06 +0100480static void emit_bc_end_finally(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100481 emit_pre(emit, -1);
482 emit_write_byte_1(emit, PYBC_END_FINALLY);
483}
484
Damien415eb6f2013-10-05 12:19:06 +0100485static void emit_bc_get_iter(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100486 emit_pre(emit, 0);
487 emit_write_byte_1(emit, PYBC_GET_ITER);
488}
489
Damien415eb6f2013-10-05 12:19:06 +0100490static void emit_bc_for_iter(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100491 emit_pre(emit, 1);
492 emit_write_byte_1_label(emit, PYBC_FOR_ITER, label);
493}
494
Damien415eb6f2013-10-05 12:19:06 +0100495static void emit_bc_for_iter_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100496 emit_pre(emit, -1);
497}
498
Damien415eb6f2013-10-05 12:19:06 +0100499static void emit_bc_pop_block(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100500 emit_pre(emit, 0);
501 emit_write_byte_1(emit, PYBC_POP_BLOCK);
502}
503
Damien415eb6f2013-10-05 12:19:06 +0100504static void emit_bc_pop_except(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100505 emit_pre(emit, 0);
506 emit_write_byte_1(emit, PYBC_POP_EXCEPT);
507}
508
Damien415eb6f2013-10-05 12:19:06 +0100509static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100510 emit_pre(emit, 0);
511 emit_write_byte_1_byte(emit, PYBC_UNARY_OP, op);
512}
513
Damien415eb6f2013-10-05 12:19:06 +0100514static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100515 emit_pre(emit, -1);
516 emit_write_byte_1_byte(emit, PYBC_BINARY_OP, op);
517}
518
Damien415eb6f2013-10-05 12:19:06 +0100519static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100520 emit_pre(emit, -1);
521 emit_write_byte_1_byte(emit, PYBC_COMPARE_OP, op);
522}
523
Damien415eb6f2013-10-05 12:19:06 +0100524static void emit_bc_build_tuple(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100525 assert(n_args >= 0);
526 emit_pre(emit, 1 - n_args);
527 emit_write_byte_1_uint(emit, PYBC_BUILD_TUPLE, n_args);
528}
529
Damien415eb6f2013-10-05 12:19:06 +0100530static void emit_bc_build_list(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100531 assert(n_args >= 0);
532 emit_pre(emit, 1 - n_args);
533 emit_write_byte_1_uint(emit, PYBC_BUILD_LIST, n_args);
534}
535
Damien415eb6f2013-10-05 12:19:06 +0100536static void emit_bc_list_append(emit_t *emit, int list_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100537 assert(list_stack_index >= 0);
538 emit_pre(emit, -1);
539 emit_write_byte_1_uint(emit, PYBC_LIST_APPEND, list_stack_index);
540}
541
Damien415eb6f2013-10-05 12:19:06 +0100542static void emit_bc_build_map(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100543 assert(n_args >= 0);
544 emit_pre(emit, 1);
545 emit_write_byte_1_uint(emit, PYBC_BUILD_MAP, n_args);
546}
547
Damien415eb6f2013-10-05 12:19:06 +0100548static void emit_bc_store_map(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100549 emit_pre(emit, -2);
550 emit_write_byte_1(emit, PYBC_STORE_MAP);
551}
552
Damien415eb6f2013-10-05 12:19:06 +0100553static void emit_bc_map_add(emit_t *emit, int map_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100554 assert(map_stack_index >= 0);
555 emit_pre(emit, -2);
556 emit_write_byte_1_uint(emit, PYBC_MAP_ADD, map_stack_index);
557}
558
Damien415eb6f2013-10-05 12:19:06 +0100559static void emit_bc_build_set(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100560 assert(n_args >= 0);
561 emit_pre(emit, 1 - n_args);
562 emit_write_byte_1_uint(emit, PYBC_BUILD_SET, n_args);
563}
564
Damien415eb6f2013-10-05 12:19:06 +0100565static void emit_bc_set_add(emit_t *emit, int set_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100566 assert(set_stack_index >= 0);
567 emit_pre(emit, -1);
568 emit_write_byte_1_uint(emit, PYBC_SET_ADD, set_stack_index);
569}
570
Damien415eb6f2013-10-05 12:19:06 +0100571static void emit_bc_build_slice(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100572 assert(n_args >= 0);
573 emit_pre(emit, 1 - n_args);
574 emit_write_byte_1_uint(emit, PYBC_BUILD_SLICE, n_args);
575}
576
Damien415eb6f2013-10-05 12:19:06 +0100577static void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100578 assert(n_args >= 0);
579 emit_pre(emit, -1 + n_args);
580 emit_write_byte_1_uint(emit, PYBC_UNPACK_SEQUENCE, n_args);
581}
582
Damien415eb6f2013-10-05 12:19:06 +0100583static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
Damien429d7192013-10-04 19:53:11 +0100584 assert(n_left >=0 && n_right >= 0);
585 emit_pre(emit, -1 + n_left + n_right + 1);
586 emit_write_byte_1_uint(emit, PYBC_UNPACK_EX, n_left | (n_right << 8));
587}
588
Damien415eb6f2013-10-05 12:19:06 +0100589static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
Damien429d7192013-10-04 19:53:11 +0100590 assert(n_default_params == 0 && n_dict_params == 0);
591 emit_pre(emit, 1);
592 emit_write_byte_1_uint(emit, PYBC_MAKE_FUNCTION, scope->unique_code_id);
593}
594
Damien415eb6f2013-10-05 12:19:06 +0100595static void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
Damien429d7192013-10-04 19:53:11 +0100596 assert(0);
597 emit_pre(emit, -2 - n_default_params - 2 * n_dict_params);
598 if (emit->pass == PASS_3) {
599 printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
600 }
601}
602
Damien415eb6f2013-10-05 12:19:06 +0100603static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
Damien429d7192013-10-04 19:53:11 +0100604 int s = 0;
605 if (have_star_arg) {
606 s += 1;
607 }
608 if (have_dbl_star_arg) {
609 s += 1;
610 }
611 emit_pre(emit, -n_positional - 2 * n_keyword - s);
612 int op;
613 if (have_star_arg) {
614 if (have_dbl_star_arg) {
615 op = PYBC_CALL_FUNCTION_VAR_KW;
616 } else {
617 op = PYBC_CALL_FUNCTION_VAR;
618 }
619 } else {
620 if (have_dbl_star_arg) {
621 op = PYBC_CALL_FUNCTION_KW;
622 } else {
623 op = PYBC_CALL_FUNCTION;
624 }
625 }
626 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
627}
628
Damien415eb6f2013-10-05 12:19:06 +0100629static void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
Damien429d7192013-10-04 19:53:11 +0100630 int s = 0;
631 if (have_star_arg) {
632 s += 1;
633 }
634 if (have_dbl_star_arg) {
635 s += 1;
636 }
637 emit_pre(emit, -n_positional - 2 * n_keyword - s);
638 int op;
639 if (have_star_arg) {
640 if (have_dbl_star_arg) {
641 op = PYBC_CALL_METHOD_VAR_KW;
642 } else {
643 op = PYBC_CALL_METHOD_VAR;
644 }
645 } else {
646 if (have_dbl_star_arg) {
647 op = PYBC_CALL_METHOD_KW;
648 } else {
649 op = PYBC_CALL_METHOD;
650 }
651 }
652 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
653}
654
Damien415eb6f2013-10-05 12:19:06 +0100655static void emit_bc_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100656 emit_pre(emit, -1);
657 emit->last_emit_was_return_value = true;
658 emit_write_byte_1(emit, PYBC_RETURN_VALUE);
659}
660
Damien415eb6f2013-10-05 12:19:06 +0100661static void emit_bc_raise_varargs(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100662 assert(n_args >= 0);
663 emit_pre(emit, -n_args);
664 emit_write_byte_1_uint(emit, PYBC_RAISE_VARARGS, n_args);
665}
666
Damien415eb6f2013-10-05 12:19:06 +0100667static void emit_bc_yield_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100668 emit_pre(emit, 0);
669 if (emit->pass == PASS_2) {
670 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
671 }
672 emit_write_byte_1(emit, PYBC_YIELD_VALUE);
673}
674
Damien415eb6f2013-10-05 12:19:06 +0100675static void emit_bc_yield_from(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100676 emit_pre(emit, -1);
677 if (emit->pass == PASS_2) {
678 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
679 }
680 emit_write_byte_1(emit, PYBC_YIELD_FROM);
681}
682
Damien415eb6f2013-10-05 12:19:06 +0100683static const emit_method_table_t emit_bc_method_table = {
684 emit_bc_set_native_types,
685 emit_bc_start_pass,
686 emit_bc_end_pass,
687 emit_bc_last_emit_was_return_value,
688 emit_bc_get_stack_size,
689 emit_bc_set_stack_size,
690
691 emit_bc_label_new,
692 emit_bc_label_assign,
693 emit_bc_import_name,
694 emit_bc_import_from,
695 emit_bc_import_star,
696 emit_bc_load_const_tok,
697 emit_bc_load_const_small_int,
698 emit_bc_load_const_int,
699 emit_bc_load_const_dec,
700 emit_bc_load_const_id,
701 emit_bc_load_const_str,
702 emit_bc_load_const_verbatim_start,
703 emit_bc_load_const_verbatim_int,
704 emit_bc_load_const_verbatim_str,
705 emit_bc_load_const_verbatim_strn,
706 emit_bc_load_const_verbatim_quoted_str,
707 emit_bc_load_const_verbatim_end,
708 emit_bc_load_fast,
709 emit_bc_load_name,
710 emit_bc_load_global,
711 emit_bc_load_deref,
712 emit_bc_load_closure,
713 emit_bc_load_attr,
714 emit_bc_load_method,
715 emit_bc_load_build_class,
716 emit_bc_store_fast,
717 emit_bc_store_name,
718 emit_bc_store_global,
719 emit_bc_store_deref,
720 emit_bc_store_attr,
721 emit_bc_store_locals,
722 emit_bc_store_subscr,
723 emit_bc_delete_fast,
724 emit_bc_delete_name,
725 emit_bc_delete_global,
726 emit_bc_delete_deref,
727 emit_bc_delete_attr,
728 emit_bc_delete_subscr,
729 emit_bc_dup_top,
730 emit_bc_dup_top_two,
731 emit_bc_pop_top,
732 emit_bc_rot_two,
733 emit_bc_rot_three,
734 emit_bc_jump,
735 emit_bc_pop_jump_if_true,
736 emit_bc_pop_jump_if_false,
737 emit_bc_jump_if_true_or_pop,
738 emit_bc_jump_if_false_or_pop,
739 emit_bc_setup_loop,
740 emit_bc_break_loop,
741 emit_bc_continue_loop,
742 emit_bc_setup_with,
743 emit_bc_with_cleanup,
744 emit_bc_setup_except,
745 emit_bc_setup_finally,
746 emit_bc_end_finally,
747 emit_bc_get_iter,
748 emit_bc_for_iter,
749 emit_bc_for_iter_end,
750 emit_bc_pop_block,
751 emit_bc_pop_except,
752 emit_bc_unary_op,
753 emit_bc_binary_op,
754 emit_bc_compare_op,
755 emit_bc_build_tuple,
756 emit_bc_build_list,
757 emit_bc_list_append,
758 emit_bc_build_map,
759 emit_bc_store_map,
760 emit_bc_map_add,
761 emit_bc_build_set,
762 emit_bc_set_add,
763 emit_bc_build_slice,
764 emit_bc_unpack_sequence,
765 emit_bc_unpack_ex,
766 emit_bc_make_function,
767 emit_bc_make_closure,
768 emit_bc_call_function,
769 emit_bc_call_method,
770 emit_bc_return_value,
771 emit_bc_raise_varargs,
772 emit_bc_yield_value,
773 emit_bc_yield_from,
774};
775
776void emit_new_bc(emit_t **emit_out, const emit_method_table_t **emit_method_table_out) {
777 emit_t *emit = m_new(emit_t, 1);
778 emit->max_num_labels = 0;
779 emit->label_offsets = NULL;
780 emit->code_offset = 0;
781 emit->code_size = 0;
782 emit->code_base = NULL;
783
784 *emit_out = emit;
785 *emit_method_table_out = &emit_bc_method_table;
786}