blob: 5c566ccb8c7df783dbd2b77a49818fc47e668355 [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"
Damienb05d7072013-10-05 13:37:10 +010016#include "vm.h"
Damien429d7192013-10-04 19:53:11 +010017
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
Damienb05d7072013-10-05 13:37:10 +010026 uint max_num_labels;
Damien429d7192013-10-04 19:53:11 +010027 uint *label_offsets;
28
29 uint code_offset;
30 uint code_size;
31 byte *code_base;
32 byte dummy_data[8];
33};
34
Damien6cdd3af2013-10-05 18:08:26 +010035emit_t *emit_bc_new(uint max_num_labels) {
36 emit_t *emit = m_new(emit_t, 1);
37 emit->max_num_labels = max_num_labels;
38 emit->label_offsets = m_new(uint, emit->max_num_labels);
39 emit->code_offset = 0;
40 emit->code_size = 0;
41 emit->code_base = NULL;
42 return emit;
43}
Damien4b03e772013-10-05 14:17:09 +010044
Damien415eb6f2013-10-05 12:19:06 +010045uint emit_bc_get_code_size(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010046 return emit->code_size;
47}
48
Damien415eb6f2013-10-05 12:19:06 +010049void* emit_bc_get_code(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010050 return emit->code_base;
51}
52
Damien415eb6f2013-10-05 12:19:06 +010053static void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
54}
55
56static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
Damien429d7192013-10-04 19:53:11 +010057 emit->pass = pass;
58 emit->next_label = 1;
59 emit->stack_size = 0;
60 emit->last_emit_was_return_value = false;
61 emit->scope = scope;
Damienb05d7072013-10-05 13:37:10 +010062 if (pass == PASS_2) {
63 memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
Damien429d7192013-10-04 19:53:11 +010064 }
65 emit->code_offset = 0;
66}
67
Damien415eb6f2013-10-05 12:19:06 +010068static void emit_bc_end_pass(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +010069 // check stack is back to zero size
70 if (emit->stack_size != 0) {
71 printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
72 }
73
Damienb05d7072013-10-05 13:37:10 +010074 if (emit->pass == PASS_2) {
Damien429d7192013-10-04 19:53:11 +010075 // calculate size of code in bytes
76 emit->code_size = emit->code_offset;
77 emit->code_base = m_new(byte, emit->code_size);
78 printf("code_size: %u\n", emit->code_size);
79
80 } else if (emit->pass == PASS_3) {
81 rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_size, emit->scope->num_params);
82 }
83}
84
85// all functions must go through this one to emit bytes
Damien415eb6f2013-10-05 12:19:06 +010086static byte* emit_get_cur_to_write_bytes(emit_t* emit, int num_bytes_to_write) {
Damien429d7192013-10-04 19:53:11 +010087 //printf("emit %d\n", num_bytes_to_write);
88 if (emit->pass < PASS_3) {
89 emit->code_offset += num_bytes_to_write;
90 return emit->dummy_data;
91 } else {
92 assert(emit->code_offset + num_bytes_to_write <= emit->code_size);
93 byte *c = emit->code_base + emit->code_offset;
94 emit->code_offset += num_bytes_to_write;
95 return c;
96 }
97}
98
Damien415eb6f2013-10-05 12:19:06 +010099static void emit_write_byte_1(emit_t* emit, byte b1) {
Damien429d7192013-10-04 19:53:11 +0100100 byte* c = emit_get_cur_to_write_bytes(emit, 1);
101 c[0] = b1;
102}
103
Damien415eb6f2013-10-05 12:19:06 +0100104static void emit_write_byte_1_byte(emit_t* emit, byte b1, uint b2) {
Damien429d7192013-10-04 19:53:11 +0100105 assert((b2 & (~0xff)) == 0);
106 byte* c = emit_get_cur_to_write_bytes(emit, 2);
107 c[0] = b1;
108 c[1] = b2;
109}
110
Damien415eb6f2013-10-05 12:19:06 +0100111static void emit_write_byte_1_int(emit_t* emit, byte b1, int num) {
Damien429d7192013-10-04 19:53:11 +0100112 assert((num & (~0x7fff)) == 0 || (num & (~0x7fff)) == (~0x7fff));
113 byte* c = emit_get_cur_to_write_bytes(emit, 3);
114 c[0] = b1;
115 c[1] = num;
116 c[2] = num >> 8;
117}
118
Damien415eb6f2013-10-05 12:19:06 +0100119static void emit_write_byte_1_uint(emit_t* emit, byte b1, uint num) {
Damien429d7192013-10-04 19:53:11 +0100120 if (num <= 127) { // fits in 0x7f
121 // fit argument in single byte
122 byte* c = emit_get_cur_to_write_bytes(emit, 2);
123 c[0] = b1;
124 c[1] = num;
125 } else if (num <= 16383) { // fits in 0x3fff
126 // fit argument in two bytes
127 byte* c = emit_get_cur_to_write_bytes(emit, 3);
128 c[0] = b1;
129 c[1] = (num >> 8) | 0x80;
130 c[2] = num;
131 } else {
132 // larger numbers not implemented/supported
133 assert(0);
134 }
135}
136
Damien415eb6f2013-10-05 12:19:06 +0100137static void emit_write_byte_1_qstr(emit_t* emit, byte b1, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100138 emit_write_byte_1_uint(emit, b1, qstr);
139}
140
Damien415eb6f2013-10-05 12:19:06 +0100141static void emit_write_byte_1_label(emit_t* emit, byte b1, int label) {
Damien429d7192013-10-04 19:53:11 +0100142 uint code_offset;
143 if (emit->pass < PASS_3) {
144 code_offset = 0;
145 } else {
146 code_offset = emit->label_offsets[label];
147 }
148 emit_write_byte_1_uint(emit, b1, code_offset);
149}
150
Damien415eb6f2013-10-05 12:19:06 +0100151bool emit_bc_last_emit_was_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100152 return emit->last_emit_was_return_value;
153}
154
Damien415eb6f2013-10-05 12:19:06 +0100155int emit_bc_get_stack_size(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100156 return emit->stack_size;
157}
158
Damien415eb6f2013-10-05 12:19:06 +0100159static void emit_bc_set_stack_size(emit_t *emit, int size) {
Damienb05d7072013-10-05 13:37:10 +0100160 emit->stack_size = size;
Damien429d7192013-10-04 19:53:11 +0100161}
162
Damien4b03e772013-10-05 14:17:09 +0100163static void emit_bc_load_id(emit_t *emit, qstr qstr) {
164 emit_common_load_id(emit, &emit_bc_method_table, emit->scope, qstr);
165}
166
167static void emit_bc_store_id(emit_t *emit, qstr qstr) {
168 emit_common_store_id(emit, &emit_bc_method_table, emit->scope, qstr);
169}
170
171static void emit_bc_delete_id(emit_t *emit, qstr qstr) {
172 emit_common_delete_id(emit, &emit_bc_method_table, emit->scope, qstr);
173}
174
Damien415eb6f2013-10-05 12:19:06 +0100175static void emit_pre(emit_t *emit, int stack_size_delta) {
Damienb05d7072013-10-05 13:37:10 +0100176 emit->stack_size += stack_size_delta;
177 if (emit->stack_size > emit->scope->stack_size) {
178 emit->scope->stack_size = emit->stack_size;
Damien429d7192013-10-04 19:53:11 +0100179 }
180 emit->last_emit_was_return_value = false;
181}
182
Damien415eb6f2013-10-05 12:19:06 +0100183static void emit_bc_label_assign(emit_t *emit, int l) {
Damien429d7192013-10-04 19:53:11 +0100184 emit_pre(emit, 0);
Damienb05d7072013-10-05 13:37:10 +0100185 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);
Damien429d7192013-10-04 19:53:11 +0100194 }
195}
196
Damien415eb6f2013-10-05 12:19:06 +0100197static void emit_bc_import_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100198 emit_pre(emit, -1);
199 emit_write_byte_1_qstr(emit, PYBC_IMPORT_NAME, qstr);
200}
201
Damien415eb6f2013-10-05 12:19:06 +0100202static void emit_bc_import_from(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100203 emit_pre(emit, 1);
204 emit_write_byte_1_qstr(emit, PYBC_IMPORT_FROM, qstr);
205}
206
Damien415eb6f2013-10-05 12:19:06 +0100207static void emit_bc_import_star(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100208 emit_pre(emit, -1);
209 emit_write_byte_1(emit, PYBC_IMPORT_STAR);
210}
211
Damien415eb6f2013-10-05 12:19:06 +0100212static void emit_bc_load_const_tok(emit_t *emit, py_token_kind_t tok) {
Damien429d7192013-10-04 19:53:11 +0100213 emit_pre(emit, 1);
214 switch (tok) {
215 case PY_TOKEN_KW_FALSE: emit_write_byte_1(emit, PYBC_LOAD_CONST_FALSE); break;
216 case PY_TOKEN_KW_NONE: emit_write_byte_1(emit, PYBC_LOAD_CONST_NONE); break;
217 case PY_TOKEN_KW_TRUE: emit_write_byte_1(emit, PYBC_LOAD_CONST_TRUE); break;
218 default: assert(0);
219 }
220}
221
Damien415eb6f2013-10-05 12:19:06 +0100222static void emit_bc_load_const_small_int(emit_t *emit, int arg) {
Damien429d7192013-10-04 19:53:11 +0100223 emit_pre(emit, 1);
224 emit_write_byte_1_int(emit, PYBC_LOAD_CONST_SMALL_INT, arg);
225}
226
Damien415eb6f2013-10-05 12:19:06 +0100227static void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100228 emit_pre(emit, 1);
229 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_INT, qstr);
230}
231
Damien415eb6f2013-10-05 12:19:06 +0100232static void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100233 emit_pre(emit, 1);
234 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_DEC, qstr);
235}
236
Damien415eb6f2013-10-05 12:19:06 +0100237static void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100238 emit_pre(emit, 1);
239 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_ID, qstr);
240}
241
Damien415eb6f2013-10-05 12:19:06 +0100242static void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100243 emit_pre(emit, 1);
244 if (bytes) {
245 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_BYTES, qstr);
246 } else {
247 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_STRING, qstr);
248 }
249}
250
Damien415eb6f2013-10-05 12:19:06 +0100251static void emit_bc_load_const_verbatim_start(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100252 emit_pre(emit, 1);
253 assert(0);
254}
255
Damien415eb6f2013-10-05 12:19:06 +0100256static void emit_bc_load_const_verbatim_int(emit_t *emit, int val) {
Damien429d7192013-10-04 19:53:11 +0100257 assert(0);
258}
259
Damien415eb6f2013-10-05 12:19:06 +0100260static void emit_bc_load_const_verbatim_str(emit_t *emit, const char *str) {
Damien429d7192013-10-04 19:53:11 +0100261 assert(0);
262}
263
Damien415eb6f2013-10-05 12:19:06 +0100264static void emit_bc_load_const_verbatim_strn(emit_t *emit, const char *str, int len) {
Damien429d7192013-10-04 19:53:11 +0100265 assert(0);
266}
267
Damien415eb6f2013-10-05 12:19:06 +0100268static void emit_bc_load_const_verbatim_quoted_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100269 assert(0);
270}
271
Damien415eb6f2013-10-05 12:19:06 +0100272static void emit_bc_load_const_verbatim_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100273 assert(0);
274}
275
Damien415eb6f2013-10-05 12:19:06 +0100276static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100277 assert(local_num >= 0);
278 emit_pre(emit, 1);
279 switch (local_num) {
280 case 0: emit_write_byte_1(emit, PYBC_LOAD_FAST_0); break;
281 case 1: emit_write_byte_1(emit, PYBC_LOAD_FAST_1); break;
282 case 2: emit_write_byte_1(emit, PYBC_LOAD_FAST_2); break;
283 default: emit_write_byte_1_uint(emit, PYBC_LOAD_FAST_N, local_num); break;
284 }
285}
286
Damien415eb6f2013-10-05 12:19:06 +0100287static void emit_bc_load_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100288 emit_pre(emit, 1);
289 emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
290}
291
Damien415eb6f2013-10-05 12:19:06 +0100292static void emit_bc_load_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100293 emit_pre(emit, 1);
294 emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
295}
296
Damien415eb6f2013-10-05 12:19:06 +0100297static void emit_bc_load_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100298 emit_pre(emit, 1);
299 assert(0);
300}
301
Damien415eb6f2013-10-05 12:19:06 +0100302static void emit_bc_load_closure(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100303 emit_pre(emit, 1);
304 assert(0);
305}
306
Damien415eb6f2013-10-05 12:19:06 +0100307static void emit_bc_load_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100308 emit_pre(emit, 0);
309 emit_write_byte_1_qstr(emit, PYBC_LOAD_ATTR, qstr);
310}
311
Damien415eb6f2013-10-05 12:19:06 +0100312static void emit_bc_load_method(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100313 emit_pre(emit, 0);
314 emit_write_byte_1_qstr(emit, PYBC_LOAD_METHOD, qstr);
315}
316
Damien415eb6f2013-10-05 12:19:06 +0100317static void emit_bc_load_build_class(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100318 emit_pre(emit, 1);
319 emit_write_byte_1(emit, PYBC_LOAD_BUILD_CLASS);
320}
321
Damien415eb6f2013-10-05 12:19:06 +0100322static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100323 assert(local_num >= 0);
324 emit_pre(emit, -1);
325 switch (local_num) {
326 case 0: emit_write_byte_1(emit, PYBC_STORE_FAST_0); break;
327 case 1: emit_write_byte_1(emit, PYBC_STORE_FAST_1); break;
328 case 2: emit_write_byte_1(emit, PYBC_STORE_FAST_2); break;
329 default: emit_write_byte_1_uint(emit, PYBC_STORE_FAST_N, local_num); break;
330 }
331}
332
Damien415eb6f2013-10-05 12:19:06 +0100333static void emit_bc_store_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100334 emit_pre(emit, -1);
335 emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr);
336}
337
Damien415eb6f2013-10-05 12:19:06 +0100338static void emit_bc_store_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100339 emit_pre(emit, -1);
340 emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
341}
342
Damien415eb6f2013-10-05 12:19:06 +0100343static void emit_bc_store_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100344 emit_pre(emit, -1);
345 assert(0);
346}
347
Damien415eb6f2013-10-05 12:19:06 +0100348static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100349 emit_pre(emit, -2);
350 emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr);
351}
352
Damien415eb6f2013-10-05 12:19:06 +0100353static void emit_bc_store_locals(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100354 emit_pre(emit, -1);
355 emit_write_byte_1(emit, PYBC_STORE_LOCALS);
356}
357
Damien415eb6f2013-10-05 12:19:06 +0100358static void emit_bc_store_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100359 emit_pre(emit, -3);
360 emit_write_byte_1(emit, PYBC_STORE_SUBSCR);
361}
362
Damien415eb6f2013-10-05 12:19:06 +0100363static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100364 assert(local_num >= 0);
365 emit_pre(emit, 0);
366 emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
367}
368
Damien415eb6f2013-10-05 12:19:06 +0100369static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100370 emit_pre(emit, 0);
371 emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr);
372}
373
Damien415eb6f2013-10-05 12:19:06 +0100374static void emit_bc_delete_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100375 emit_pre(emit, 0);
376 emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
377}
378
Damien415eb6f2013-10-05 12:19:06 +0100379static void emit_bc_delete_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100380 emit_pre(emit, 0);
381 emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, qstr);
382}
383
Damien415eb6f2013-10-05 12:19:06 +0100384static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100385 emit_pre(emit, -1);
386 emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr);
387}
388
Damien415eb6f2013-10-05 12:19:06 +0100389static void emit_bc_delete_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100390 emit_pre(emit, -2);
391 emit_write_byte_1(emit, PYBC_DELETE_SUBSCR);
392}
393
Damien415eb6f2013-10-05 12:19:06 +0100394static void emit_bc_dup_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100395 emit_pre(emit, 1);
396 emit_write_byte_1(emit, PYBC_DUP_TOP);
397}
398
Damien415eb6f2013-10-05 12:19:06 +0100399static void emit_bc_dup_top_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100400 emit_pre(emit, 2);
401 emit_write_byte_1(emit, PYBC_DUP_TOP_TWO);
402}
403
Damien415eb6f2013-10-05 12:19:06 +0100404static void emit_bc_pop_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100405 emit_pre(emit, -1);
406 emit_write_byte_1(emit, PYBC_POP_TOP);
407}
408
Damien415eb6f2013-10-05 12:19:06 +0100409static void emit_bc_rot_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100410 emit_pre(emit, 0);
411 emit_write_byte_1(emit, PYBC_ROT_TWO);
412}
413
Damien415eb6f2013-10-05 12:19:06 +0100414static void emit_bc_rot_three(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100415 emit_pre(emit, 0);
416 emit_write_byte_1(emit, PYBC_ROT_THREE);
417}
418
Damien415eb6f2013-10-05 12:19:06 +0100419static void emit_bc_jump(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100420 emit_pre(emit, 0);
421 emit_write_byte_1_label(emit, PYBC_JUMP, label);
422}
423
Damien415eb6f2013-10-05 12:19:06 +0100424static void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100425 emit_pre(emit, -1);
426 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_TRUE, label);
427}
428
Damien415eb6f2013-10-05 12:19:06 +0100429static void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100430 emit_pre(emit, -1);
431 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_FALSE, label);
432}
433
Damien415eb6f2013-10-05 12:19:06 +0100434static void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100435 emit_pre(emit, -1);
436 emit_write_byte_1_label(emit, PYBC_JUMP_IF_TRUE_OR_POP, label);
437}
438
Damien415eb6f2013-10-05 12:19:06 +0100439static void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100440 emit_pre(emit, -1);
441 emit_write_byte_1_label(emit, PYBC_JUMP_IF_FALSE_OR_POP, label);
442}
443
Damien415eb6f2013-10-05 12:19:06 +0100444static void emit_bc_setup_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100445 emit_pre(emit, 0);
446 emit_write_byte_1_label(emit, PYBC_SETUP_LOOP, label);
447}
448
Damien415eb6f2013-10-05 12:19:06 +0100449static void emit_bc_break_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100450 emit_pre(emit, 0);
451 emit_write_byte_1_label(emit, PYBC_BREAK_LOOP, label);
452}
453
Damien415eb6f2013-10-05 12:19:06 +0100454static void emit_bc_continue_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100455 emit_pre(emit, 0);
456 emit_write_byte_1_label(emit, PYBC_CONTINUE_LOOP, label);
457}
458
Damien415eb6f2013-10-05 12:19:06 +0100459static void emit_bc_setup_with(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100460 emit_pre(emit, 7);
461 emit_write_byte_1_label(emit, PYBC_SETUP_WITH, label);
462}
463
Damien415eb6f2013-10-05 12:19:06 +0100464static void emit_bc_with_cleanup(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100465 emit_pre(emit, -7);
466 emit_write_byte_1(emit, PYBC_WITH_CLEANUP);
467}
468
Damien415eb6f2013-10-05 12:19:06 +0100469static void emit_bc_setup_except(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100470 emit_pre(emit, 6);
471 emit_write_byte_1_label(emit, PYBC_SETUP_EXCEPT, label);
472}
473
Damien415eb6f2013-10-05 12:19:06 +0100474static void emit_bc_setup_finally(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100475 emit_pre(emit, 6);
476 emit_write_byte_1_label(emit, PYBC_SETUP_FINALLY, label);
477}
478
Damien415eb6f2013-10-05 12:19:06 +0100479static void emit_bc_end_finally(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100480 emit_pre(emit, -1);
481 emit_write_byte_1(emit, PYBC_END_FINALLY);
482}
483
Damien415eb6f2013-10-05 12:19:06 +0100484static void emit_bc_get_iter(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100485 emit_pre(emit, 0);
486 emit_write_byte_1(emit, PYBC_GET_ITER);
487}
488
Damien415eb6f2013-10-05 12:19:06 +0100489static void emit_bc_for_iter(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100490 emit_pre(emit, 1);
491 emit_write_byte_1_label(emit, PYBC_FOR_ITER, label);
492}
493
Damien415eb6f2013-10-05 12:19:06 +0100494static void emit_bc_for_iter_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100495 emit_pre(emit, -1);
496}
497
Damien415eb6f2013-10-05 12:19:06 +0100498static void emit_bc_pop_block(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100499 emit_pre(emit, 0);
500 emit_write_byte_1(emit, PYBC_POP_BLOCK);
501}
502
Damien415eb6f2013-10-05 12:19:06 +0100503static void emit_bc_pop_except(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100504 emit_pre(emit, 0);
505 emit_write_byte_1(emit, PYBC_POP_EXCEPT);
506}
507
Damien415eb6f2013-10-05 12:19:06 +0100508static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100509 emit_pre(emit, 0);
510 emit_write_byte_1_byte(emit, PYBC_UNARY_OP, op);
511}
512
Damien415eb6f2013-10-05 12:19:06 +0100513static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100514 emit_pre(emit, -1);
515 emit_write_byte_1_byte(emit, PYBC_BINARY_OP, op);
516}
517
Damien415eb6f2013-10-05 12:19:06 +0100518static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100519 emit_pre(emit, -1);
520 emit_write_byte_1_byte(emit, PYBC_COMPARE_OP, op);
521}
522
Damien415eb6f2013-10-05 12:19:06 +0100523static void emit_bc_build_tuple(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100524 assert(n_args >= 0);
525 emit_pre(emit, 1 - n_args);
526 emit_write_byte_1_uint(emit, PYBC_BUILD_TUPLE, n_args);
527}
528
Damien415eb6f2013-10-05 12:19:06 +0100529static void emit_bc_build_list(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100530 assert(n_args >= 0);
531 emit_pre(emit, 1 - n_args);
532 emit_write_byte_1_uint(emit, PYBC_BUILD_LIST, n_args);
533}
534
Damien415eb6f2013-10-05 12:19:06 +0100535static void emit_bc_list_append(emit_t *emit, int list_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100536 assert(list_stack_index >= 0);
537 emit_pre(emit, -1);
538 emit_write_byte_1_uint(emit, PYBC_LIST_APPEND, list_stack_index);
539}
540
Damien415eb6f2013-10-05 12:19:06 +0100541static void emit_bc_build_map(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100542 assert(n_args >= 0);
543 emit_pre(emit, 1);
544 emit_write_byte_1_uint(emit, PYBC_BUILD_MAP, n_args);
545}
546
Damien415eb6f2013-10-05 12:19:06 +0100547static void emit_bc_store_map(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100548 emit_pre(emit, -2);
549 emit_write_byte_1(emit, PYBC_STORE_MAP);
550}
551
Damien415eb6f2013-10-05 12:19:06 +0100552static void emit_bc_map_add(emit_t *emit, int map_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100553 assert(map_stack_index >= 0);
554 emit_pre(emit, -2);
555 emit_write_byte_1_uint(emit, PYBC_MAP_ADD, map_stack_index);
556}
557
Damien415eb6f2013-10-05 12:19:06 +0100558static void emit_bc_build_set(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100559 assert(n_args >= 0);
560 emit_pre(emit, 1 - n_args);
561 emit_write_byte_1_uint(emit, PYBC_BUILD_SET, n_args);
562}
563
Damien415eb6f2013-10-05 12:19:06 +0100564static void emit_bc_set_add(emit_t *emit, int set_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100565 assert(set_stack_index >= 0);
566 emit_pre(emit, -1);
567 emit_write_byte_1_uint(emit, PYBC_SET_ADD, set_stack_index);
568}
569
Damien415eb6f2013-10-05 12:19:06 +0100570static void emit_bc_build_slice(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100571 assert(n_args >= 0);
572 emit_pre(emit, 1 - n_args);
573 emit_write_byte_1_uint(emit, PYBC_BUILD_SLICE, n_args);
574}
575
Damien415eb6f2013-10-05 12:19:06 +0100576static void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100577 assert(n_args >= 0);
578 emit_pre(emit, -1 + n_args);
579 emit_write_byte_1_uint(emit, PYBC_UNPACK_SEQUENCE, n_args);
580}
581
Damien415eb6f2013-10-05 12:19:06 +0100582static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
Damien429d7192013-10-04 19:53:11 +0100583 assert(n_left >=0 && n_right >= 0);
584 emit_pre(emit, -1 + n_left + n_right + 1);
585 emit_write_byte_1_uint(emit, PYBC_UNPACK_EX, n_left | (n_right << 8));
586}
587
Damien415eb6f2013-10-05 12:19:06 +0100588static 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 +0100589 assert(n_default_params == 0 && n_dict_params == 0);
590 emit_pre(emit, 1);
591 emit_write_byte_1_uint(emit, PYBC_MAKE_FUNCTION, scope->unique_code_id);
592}
593
Damien415eb6f2013-10-05 12:19:06 +0100594static 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 +0100595 assert(0);
596 emit_pre(emit, -2 - n_default_params - 2 * n_dict_params);
597 if (emit->pass == PASS_3) {
598 printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
599 }
600}
601
Damien415eb6f2013-10-05 12:19:06 +0100602static 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 +0100603 int s = 0;
604 if (have_star_arg) {
605 s += 1;
606 }
607 if (have_dbl_star_arg) {
608 s += 1;
609 }
610 emit_pre(emit, -n_positional - 2 * n_keyword - s);
611 int op;
612 if (have_star_arg) {
613 if (have_dbl_star_arg) {
614 op = PYBC_CALL_FUNCTION_VAR_KW;
615 } else {
616 op = PYBC_CALL_FUNCTION_VAR;
617 }
618 } else {
619 if (have_dbl_star_arg) {
620 op = PYBC_CALL_FUNCTION_KW;
621 } else {
622 op = PYBC_CALL_FUNCTION;
623 }
624 }
625 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
626}
627
Damien415eb6f2013-10-05 12:19:06 +0100628static 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 +0100629 int s = 0;
630 if (have_star_arg) {
631 s += 1;
632 }
633 if (have_dbl_star_arg) {
634 s += 1;
635 }
636 emit_pre(emit, -n_positional - 2 * n_keyword - s);
637 int op;
638 if (have_star_arg) {
639 if (have_dbl_star_arg) {
640 op = PYBC_CALL_METHOD_VAR_KW;
641 } else {
642 op = PYBC_CALL_METHOD_VAR;
643 }
644 } else {
645 if (have_dbl_star_arg) {
646 op = PYBC_CALL_METHOD_KW;
647 } else {
648 op = PYBC_CALL_METHOD;
649 }
650 }
651 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
652}
653
Damien415eb6f2013-10-05 12:19:06 +0100654static void emit_bc_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100655 emit_pre(emit, -1);
656 emit->last_emit_was_return_value = true;
657 emit_write_byte_1(emit, PYBC_RETURN_VALUE);
658}
659
Damien415eb6f2013-10-05 12:19:06 +0100660static void emit_bc_raise_varargs(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100661 assert(n_args >= 0);
662 emit_pre(emit, -n_args);
663 emit_write_byte_1_uint(emit, PYBC_RAISE_VARARGS, n_args);
664}
665
Damien415eb6f2013-10-05 12:19:06 +0100666static void emit_bc_yield_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100667 emit_pre(emit, 0);
668 if (emit->pass == PASS_2) {
669 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
670 }
671 emit_write_byte_1(emit, PYBC_YIELD_VALUE);
672}
673
Damien415eb6f2013-10-05 12:19:06 +0100674static void emit_bc_yield_from(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100675 emit_pre(emit, -1);
676 if (emit->pass == PASS_2) {
677 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
678 }
679 emit_write_byte_1(emit, PYBC_YIELD_FROM);
680}
681
Damien6cdd3af2013-10-05 18:08:26 +0100682const emit_method_table_t emit_bc_method_table = {
Damien415eb6f2013-10-05 12:19:06 +0100683 emit_bc_set_native_types,
684 emit_bc_start_pass,
685 emit_bc_end_pass,
686 emit_bc_last_emit_was_return_value,
687 emit_bc_get_stack_size,
688 emit_bc_set_stack_size,
689
Damien4b03e772013-10-05 14:17:09 +0100690 emit_bc_load_id,
691 emit_bc_store_id,
692 emit_bc_delete_id,
693
Damien415eb6f2013-10-05 12:19:06 +0100694 emit_bc_label_assign,
695 emit_bc_import_name,
696 emit_bc_import_from,
697 emit_bc_import_star,
698 emit_bc_load_const_tok,
699 emit_bc_load_const_small_int,
700 emit_bc_load_const_int,
701 emit_bc_load_const_dec,
702 emit_bc_load_const_id,
703 emit_bc_load_const_str,
704 emit_bc_load_const_verbatim_start,
705 emit_bc_load_const_verbatim_int,
706 emit_bc_load_const_verbatim_str,
707 emit_bc_load_const_verbatim_strn,
708 emit_bc_load_const_verbatim_quoted_str,
709 emit_bc_load_const_verbatim_end,
710 emit_bc_load_fast,
711 emit_bc_load_name,
712 emit_bc_load_global,
713 emit_bc_load_deref,
714 emit_bc_load_closure,
715 emit_bc_load_attr,
716 emit_bc_load_method,
717 emit_bc_load_build_class,
718 emit_bc_store_fast,
719 emit_bc_store_name,
720 emit_bc_store_global,
721 emit_bc_store_deref,
722 emit_bc_store_attr,
723 emit_bc_store_locals,
724 emit_bc_store_subscr,
725 emit_bc_delete_fast,
726 emit_bc_delete_name,
727 emit_bc_delete_global,
728 emit_bc_delete_deref,
729 emit_bc_delete_attr,
730 emit_bc_delete_subscr,
731 emit_bc_dup_top,
732 emit_bc_dup_top_two,
733 emit_bc_pop_top,
734 emit_bc_rot_two,
735 emit_bc_rot_three,
736 emit_bc_jump,
737 emit_bc_pop_jump_if_true,
738 emit_bc_pop_jump_if_false,
739 emit_bc_jump_if_true_or_pop,
740 emit_bc_jump_if_false_or_pop,
741 emit_bc_setup_loop,
742 emit_bc_break_loop,
743 emit_bc_continue_loop,
744 emit_bc_setup_with,
745 emit_bc_with_cleanup,
746 emit_bc_setup_except,
747 emit_bc_setup_finally,
748 emit_bc_end_finally,
749 emit_bc_get_iter,
750 emit_bc_for_iter,
751 emit_bc_for_iter_end,
752 emit_bc_pop_block,
753 emit_bc_pop_except,
754 emit_bc_unary_op,
755 emit_bc_binary_op,
756 emit_bc_compare_op,
757 emit_bc_build_tuple,
758 emit_bc_build_list,
759 emit_bc_list_append,
760 emit_bc_build_map,
761 emit_bc_store_map,
762 emit_bc_map_add,
763 emit_bc_build_set,
764 emit_bc_set_add,
765 emit_bc_build_slice,
766 emit_bc_unpack_sequence,
767 emit_bc_unpack_ex,
768 emit_bc_make_function,
769 emit_bc_make_closure,
770 emit_bc_call_function,
771 emit_bc_call_method,
772 emit_bc_return_value,
773 emit_bc_raise_varargs,
774 emit_bc_yield_value,
775 emit_bc_yield_from,
776};