blob: 4cfd88ed4fb7fa8e3bcce7c8600d1b406d67b72e [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
Damien4b03e772013-10-05 14:17:09 +010035// forward declaration
36static const emit_method_table_t emit_bc_method_table;
37
Damien415eb6f2013-10-05 12:19:06 +010038uint emit_bc_get_code_size(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010039 return emit->code_size;
40}
41
Damien415eb6f2013-10-05 12:19:06 +010042void* emit_bc_get_code(emit_t* emit) {
Damien429d7192013-10-04 19:53:11 +010043 return emit->code_base;
44}
45
Damien415eb6f2013-10-05 12:19:06 +010046static void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
47}
48
49static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
Damien429d7192013-10-04 19:53:11 +010050 emit->pass = pass;
51 emit->next_label = 1;
52 emit->stack_size = 0;
53 emit->last_emit_was_return_value = false;
54 emit->scope = scope;
Damienb05d7072013-10-05 13:37:10 +010055 if (pass == PASS_2) {
56 memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
Damien429d7192013-10-04 19:53:11 +010057 }
58 emit->code_offset = 0;
59}
60
Damien415eb6f2013-10-05 12:19:06 +010061static void emit_bc_end_pass(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +010062 // check stack is back to zero size
63 if (emit->stack_size != 0) {
64 printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
65 }
66
Damienb05d7072013-10-05 13:37:10 +010067 if (emit->pass == PASS_2) {
Damien429d7192013-10-04 19:53:11 +010068 // calculate size of code in bytes
69 emit->code_size = emit->code_offset;
70 emit->code_base = m_new(byte, emit->code_size);
71 printf("code_size: %u\n", emit->code_size);
72
73 } else if (emit->pass == PASS_3) {
74 rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_size, emit->scope->num_params);
75 }
76}
77
78// all functions must go through this one to emit bytes
Damien415eb6f2013-10-05 12:19:06 +010079static byte* emit_get_cur_to_write_bytes(emit_t* emit, int num_bytes_to_write) {
Damien429d7192013-10-04 19:53:11 +010080 //printf("emit %d\n", num_bytes_to_write);
81 if (emit->pass < PASS_3) {
82 emit->code_offset += num_bytes_to_write;
83 return emit->dummy_data;
84 } else {
85 assert(emit->code_offset + num_bytes_to_write <= emit->code_size);
86 byte *c = emit->code_base + emit->code_offset;
87 emit->code_offset += num_bytes_to_write;
88 return c;
89 }
90}
91
Damien415eb6f2013-10-05 12:19:06 +010092static void emit_write_byte_1(emit_t* emit, byte b1) {
Damien429d7192013-10-04 19:53:11 +010093 byte* c = emit_get_cur_to_write_bytes(emit, 1);
94 c[0] = b1;
95}
96
Damien415eb6f2013-10-05 12:19:06 +010097static void emit_write_byte_1_byte(emit_t* emit, byte b1, uint b2) {
Damien429d7192013-10-04 19:53:11 +010098 assert((b2 & (~0xff)) == 0);
99 byte* c = emit_get_cur_to_write_bytes(emit, 2);
100 c[0] = b1;
101 c[1] = b2;
102}
103
Damien415eb6f2013-10-05 12:19:06 +0100104static void emit_write_byte_1_int(emit_t* emit, byte b1, int num) {
Damien429d7192013-10-04 19:53:11 +0100105 assert((num & (~0x7fff)) == 0 || (num & (~0x7fff)) == (~0x7fff));
106 byte* c = emit_get_cur_to_write_bytes(emit, 3);
107 c[0] = b1;
108 c[1] = num;
109 c[2] = num >> 8;
110}
111
Damien415eb6f2013-10-05 12:19:06 +0100112static void emit_write_byte_1_uint(emit_t* emit, byte b1, uint num) {
Damien429d7192013-10-04 19:53:11 +0100113 if (num <= 127) { // fits in 0x7f
114 // fit argument in single byte
115 byte* c = emit_get_cur_to_write_bytes(emit, 2);
116 c[0] = b1;
117 c[1] = num;
118 } else if (num <= 16383) { // fits in 0x3fff
119 // fit argument in two bytes
120 byte* c = emit_get_cur_to_write_bytes(emit, 3);
121 c[0] = b1;
122 c[1] = (num >> 8) | 0x80;
123 c[2] = num;
124 } else {
125 // larger numbers not implemented/supported
126 assert(0);
127 }
128}
129
Damien415eb6f2013-10-05 12:19:06 +0100130static void emit_write_byte_1_qstr(emit_t* emit, byte b1, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100131 emit_write_byte_1_uint(emit, b1, qstr);
132}
133
Damien415eb6f2013-10-05 12:19:06 +0100134static void emit_write_byte_1_label(emit_t* emit, byte b1, int label) {
Damien429d7192013-10-04 19:53:11 +0100135 uint code_offset;
136 if (emit->pass < PASS_3) {
137 code_offset = 0;
138 } else {
139 code_offset = emit->label_offsets[label];
140 }
141 emit_write_byte_1_uint(emit, b1, code_offset);
142}
143
Damien415eb6f2013-10-05 12:19:06 +0100144bool emit_bc_last_emit_was_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100145 return emit->last_emit_was_return_value;
146}
147
Damien415eb6f2013-10-05 12:19:06 +0100148int emit_bc_get_stack_size(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100149 return emit->stack_size;
150}
151
Damien415eb6f2013-10-05 12:19:06 +0100152static void emit_bc_set_stack_size(emit_t *emit, int size) {
Damienb05d7072013-10-05 13:37:10 +0100153 emit->stack_size = size;
Damien429d7192013-10-04 19:53:11 +0100154}
155
Damien4b03e772013-10-05 14:17:09 +0100156static void emit_bc_load_id(emit_t *emit, qstr qstr) {
157 emit_common_load_id(emit, &emit_bc_method_table, emit->scope, qstr);
158}
159
160static void emit_bc_store_id(emit_t *emit, qstr qstr) {
161 emit_common_store_id(emit, &emit_bc_method_table, emit->scope, qstr);
162}
163
164static void emit_bc_delete_id(emit_t *emit, qstr qstr) {
165 emit_common_delete_id(emit, &emit_bc_method_table, emit->scope, qstr);
166}
167
Damien415eb6f2013-10-05 12:19:06 +0100168static void emit_pre(emit_t *emit, int stack_size_delta) {
Damienb05d7072013-10-05 13:37:10 +0100169 emit->stack_size += stack_size_delta;
170 if (emit->stack_size > emit->scope->stack_size) {
171 emit->scope->stack_size = emit->stack_size;
Damien429d7192013-10-04 19:53:11 +0100172 }
173 emit->last_emit_was_return_value = false;
174}
175
Damien415eb6f2013-10-05 12:19:06 +0100176static void emit_bc_label_assign(emit_t *emit, int l) {
Damien429d7192013-10-04 19:53:11 +0100177 emit_pre(emit, 0);
Damienb05d7072013-10-05 13:37:10 +0100178 assert(l < emit->max_num_labels);
179 if (emit->pass == PASS_2) {
180 // assign label offset
181 assert(emit->label_offsets[l] == -1);
182 emit->label_offsets[l] = emit->code_offset;
183 } else if (emit->pass == PASS_3) {
184 // ensure label offset has not changed from PASS_2 to PASS_3
185 assert(emit->label_offsets[l] == emit->code_offset);
186 //printf("l%d: (at %d)\n", l, emit->code_offset);
Damien429d7192013-10-04 19:53:11 +0100187 }
188}
189
Damien415eb6f2013-10-05 12:19:06 +0100190static void emit_bc_import_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100191 emit_pre(emit, -1);
192 emit_write_byte_1_qstr(emit, PYBC_IMPORT_NAME, qstr);
193}
194
Damien415eb6f2013-10-05 12:19:06 +0100195static void emit_bc_import_from(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100196 emit_pre(emit, 1);
197 emit_write_byte_1_qstr(emit, PYBC_IMPORT_FROM, qstr);
198}
199
Damien415eb6f2013-10-05 12:19:06 +0100200static void emit_bc_import_star(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100201 emit_pre(emit, -1);
202 emit_write_byte_1(emit, PYBC_IMPORT_STAR);
203}
204
Damien415eb6f2013-10-05 12:19:06 +0100205static void emit_bc_load_const_tok(emit_t *emit, py_token_kind_t tok) {
Damien429d7192013-10-04 19:53:11 +0100206 emit_pre(emit, 1);
207 switch (tok) {
208 case PY_TOKEN_KW_FALSE: emit_write_byte_1(emit, PYBC_LOAD_CONST_FALSE); break;
209 case PY_TOKEN_KW_NONE: emit_write_byte_1(emit, PYBC_LOAD_CONST_NONE); break;
210 case PY_TOKEN_KW_TRUE: emit_write_byte_1(emit, PYBC_LOAD_CONST_TRUE); break;
211 default: assert(0);
212 }
213}
214
Damien415eb6f2013-10-05 12:19:06 +0100215static void emit_bc_load_const_small_int(emit_t *emit, int arg) {
Damien429d7192013-10-04 19:53:11 +0100216 emit_pre(emit, 1);
217 emit_write_byte_1_int(emit, PYBC_LOAD_CONST_SMALL_INT, arg);
218}
219
Damien415eb6f2013-10-05 12:19:06 +0100220static void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100221 emit_pre(emit, 1);
222 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_INT, qstr);
223}
224
Damien415eb6f2013-10-05 12:19:06 +0100225static void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100226 emit_pre(emit, 1);
227 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_DEC, qstr);
228}
229
Damien415eb6f2013-10-05 12:19:06 +0100230static void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100231 emit_pre(emit, 1);
232 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_ID, qstr);
233}
234
Damien415eb6f2013-10-05 12:19:06 +0100235static void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100236 emit_pre(emit, 1);
237 if (bytes) {
238 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_BYTES, qstr);
239 } else {
240 emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_STRING, qstr);
241 }
242}
243
Damien415eb6f2013-10-05 12:19:06 +0100244static void emit_bc_load_const_verbatim_start(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100245 emit_pre(emit, 1);
246 assert(0);
247}
248
Damien415eb6f2013-10-05 12:19:06 +0100249static void emit_bc_load_const_verbatim_int(emit_t *emit, int val) {
Damien429d7192013-10-04 19:53:11 +0100250 assert(0);
251}
252
Damien415eb6f2013-10-05 12:19:06 +0100253static void emit_bc_load_const_verbatim_str(emit_t *emit, const char *str) {
Damien429d7192013-10-04 19:53:11 +0100254 assert(0);
255}
256
Damien415eb6f2013-10-05 12:19:06 +0100257static void emit_bc_load_const_verbatim_strn(emit_t *emit, const char *str, int len) {
Damien429d7192013-10-04 19:53:11 +0100258 assert(0);
259}
260
Damien415eb6f2013-10-05 12:19:06 +0100261static void emit_bc_load_const_verbatim_quoted_str(emit_t *emit, qstr qstr, bool bytes) {
Damien429d7192013-10-04 19:53:11 +0100262 assert(0);
263}
264
Damien415eb6f2013-10-05 12:19:06 +0100265static void emit_bc_load_const_verbatim_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100266 assert(0);
267}
268
Damien415eb6f2013-10-05 12:19:06 +0100269static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100270 assert(local_num >= 0);
271 emit_pre(emit, 1);
272 switch (local_num) {
273 case 0: emit_write_byte_1(emit, PYBC_LOAD_FAST_0); break;
274 case 1: emit_write_byte_1(emit, PYBC_LOAD_FAST_1); break;
275 case 2: emit_write_byte_1(emit, PYBC_LOAD_FAST_2); break;
276 default: emit_write_byte_1_uint(emit, PYBC_LOAD_FAST_N, local_num); break;
277 }
278}
279
Damien415eb6f2013-10-05 12:19:06 +0100280static void emit_bc_load_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100281 emit_pre(emit, 1);
282 emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
283}
284
Damien415eb6f2013-10-05 12:19:06 +0100285static void emit_bc_load_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100286 emit_pre(emit, 1);
287 emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
288}
289
Damien415eb6f2013-10-05 12:19:06 +0100290static void emit_bc_load_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100291 emit_pre(emit, 1);
292 assert(0);
293}
294
Damien415eb6f2013-10-05 12:19:06 +0100295static void emit_bc_load_closure(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100296 emit_pre(emit, 1);
297 assert(0);
298}
299
Damien415eb6f2013-10-05 12:19:06 +0100300static void emit_bc_load_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100301 emit_pre(emit, 0);
302 emit_write_byte_1_qstr(emit, PYBC_LOAD_ATTR, qstr);
303}
304
Damien415eb6f2013-10-05 12:19:06 +0100305static void emit_bc_load_method(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100306 emit_pre(emit, 0);
307 emit_write_byte_1_qstr(emit, PYBC_LOAD_METHOD, qstr);
308}
309
Damien415eb6f2013-10-05 12:19:06 +0100310static void emit_bc_load_build_class(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100311 emit_pre(emit, 1);
312 emit_write_byte_1(emit, PYBC_LOAD_BUILD_CLASS);
313}
314
Damien415eb6f2013-10-05 12:19:06 +0100315static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100316 assert(local_num >= 0);
317 emit_pre(emit, -1);
318 switch (local_num) {
319 case 0: emit_write_byte_1(emit, PYBC_STORE_FAST_0); break;
320 case 1: emit_write_byte_1(emit, PYBC_STORE_FAST_1); break;
321 case 2: emit_write_byte_1(emit, PYBC_STORE_FAST_2); break;
322 default: emit_write_byte_1_uint(emit, PYBC_STORE_FAST_N, local_num); break;
323 }
324}
325
Damien415eb6f2013-10-05 12:19:06 +0100326static void emit_bc_store_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100327 emit_pre(emit, -1);
328 emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr);
329}
330
Damien415eb6f2013-10-05 12:19:06 +0100331static void emit_bc_store_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100332 emit_pre(emit, -1);
333 emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
334}
335
Damien415eb6f2013-10-05 12:19:06 +0100336static void emit_bc_store_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100337 emit_pre(emit, -1);
338 assert(0);
339}
340
Damien415eb6f2013-10-05 12:19:06 +0100341static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100342 emit_pre(emit, -2);
343 emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr);
344}
345
Damien415eb6f2013-10-05 12:19:06 +0100346static void emit_bc_store_locals(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100347 emit_pre(emit, -1);
348 emit_write_byte_1(emit, PYBC_STORE_LOCALS);
349}
350
Damien415eb6f2013-10-05 12:19:06 +0100351static void emit_bc_store_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100352 emit_pre(emit, -3);
353 emit_write_byte_1(emit, PYBC_STORE_SUBSCR);
354}
355
Damien415eb6f2013-10-05 12:19:06 +0100356static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
Damien429d7192013-10-04 19:53:11 +0100357 assert(local_num >= 0);
358 emit_pre(emit, 0);
359 emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
360}
361
Damien415eb6f2013-10-05 12:19:06 +0100362static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100363 emit_pre(emit, 0);
364 emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr);
365}
366
Damien415eb6f2013-10-05 12:19:06 +0100367static void emit_bc_delete_global(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100368 emit_pre(emit, 0);
369 emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
370}
371
Damien415eb6f2013-10-05 12:19:06 +0100372static void emit_bc_delete_deref(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100373 emit_pre(emit, 0);
374 emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, qstr);
375}
376
Damien415eb6f2013-10-05 12:19:06 +0100377static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
Damien429d7192013-10-04 19:53:11 +0100378 emit_pre(emit, -1);
379 emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr);
380}
381
Damien415eb6f2013-10-05 12:19:06 +0100382static void emit_bc_delete_subscr(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100383 emit_pre(emit, -2);
384 emit_write_byte_1(emit, PYBC_DELETE_SUBSCR);
385}
386
Damien415eb6f2013-10-05 12:19:06 +0100387static void emit_bc_dup_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100388 emit_pre(emit, 1);
389 emit_write_byte_1(emit, PYBC_DUP_TOP);
390}
391
Damien415eb6f2013-10-05 12:19:06 +0100392static void emit_bc_dup_top_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100393 emit_pre(emit, 2);
394 emit_write_byte_1(emit, PYBC_DUP_TOP_TWO);
395}
396
Damien415eb6f2013-10-05 12:19:06 +0100397static void emit_bc_pop_top(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100398 emit_pre(emit, -1);
399 emit_write_byte_1(emit, PYBC_POP_TOP);
400}
401
Damien415eb6f2013-10-05 12:19:06 +0100402static void emit_bc_rot_two(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100403 emit_pre(emit, 0);
404 emit_write_byte_1(emit, PYBC_ROT_TWO);
405}
406
Damien415eb6f2013-10-05 12:19:06 +0100407static void emit_bc_rot_three(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100408 emit_pre(emit, 0);
409 emit_write_byte_1(emit, PYBC_ROT_THREE);
410}
411
Damien415eb6f2013-10-05 12:19:06 +0100412static void emit_bc_jump(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100413 emit_pre(emit, 0);
414 emit_write_byte_1_label(emit, PYBC_JUMP, label);
415}
416
Damien415eb6f2013-10-05 12:19:06 +0100417static void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100418 emit_pre(emit, -1);
419 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_TRUE, label);
420}
421
Damien415eb6f2013-10-05 12:19:06 +0100422static void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100423 emit_pre(emit, -1);
424 emit_write_byte_1_label(emit, PYBC_POP_JUMP_IF_FALSE, label);
425}
426
Damien415eb6f2013-10-05 12:19:06 +0100427static void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100428 emit_pre(emit, -1);
429 emit_write_byte_1_label(emit, PYBC_JUMP_IF_TRUE_OR_POP, label);
430}
431
Damien415eb6f2013-10-05 12:19:06 +0100432static void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100433 emit_pre(emit, -1);
434 emit_write_byte_1_label(emit, PYBC_JUMP_IF_FALSE_OR_POP, label);
435}
436
Damien415eb6f2013-10-05 12:19:06 +0100437static void emit_bc_setup_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100438 emit_pre(emit, 0);
439 emit_write_byte_1_label(emit, PYBC_SETUP_LOOP, label);
440}
441
Damien415eb6f2013-10-05 12:19:06 +0100442static void emit_bc_break_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100443 emit_pre(emit, 0);
444 emit_write_byte_1_label(emit, PYBC_BREAK_LOOP, label);
445}
446
Damien415eb6f2013-10-05 12:19:06 +0100447static void emit_bc_continue_loop(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100448 emit_pre(emit, 0);
449 emit_write_byte_1_label(emit, PYBC_CONTINUE_LOOP, label);
450}
451
Damien415eb6f2013-10-05 12:19:06 +0100452static void emit_bc_setup_with(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100453 emit_pre(emit, 7);
454 emit_write_byte_1_label(emit, PYBC_SETUP_WITH, label);
455}
456
Damien415eb6f2013-10-05 12:19:06 +0100457static void emit_bc_with_cleanup(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100458 emit_pre(emit, -7);
459 emit_write_byte_1(emit, PYBC_WITH_CLEANUP);
460}
461
Damien415eb6f2013-10-05 12:19:06 +0100462static void emit_bc_setup_except(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100463 emit_pre(emit, 6);
464 emit_write_byte_1_label(emit, PYBC_SETUP_EXCEPT, label);
465}
466
Damien415eb6f2013-10-05 12:19:06 +0100467static void emit_bc_setup_finally(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100468 emit_pre(emit, 6);
469 emit_write_byte_1_label(emit, PYBC_SETUP_FINALLY, label);
470}
471
Damien415eb6f2013-10-05 12:19:06 +0100472static void emit_bc_end_finally(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100473 emit_pre(emit, -1);
474 emit_write_byte_1(emit, PYBC_END_FINALLY);
475}
476
Damien415eb6f2013-10-05 12:19:06 +0100477static void emit_bc_get_iter(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100478 emit_pre(emit, 0);
479 emit_write_byte_1(emit, PYBC_GET_ITER);
480}
481
Damien415eb6f2013-10-05 12:19:06 +0100482static void emit_bc_for_iter(emit_t *emit, int label) {
Damien429d7192013-10-04 19:53:11 +0100483 emit_pre(emit, 1);
484 emit_write_byte_1_label(emit, PYBC_FOR_ITER, label);
485}
486
Damien415eb6f2013-10-05 12:19:06 +0100487static void emit_bc_for_iter_end(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100488 emit_pre(emit, -1);
489}
490
Damien415eb6f2013-10-05 12:19:06 +0100491static void emit_bc_pop_block(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100492 emit_pre(emit, 0);
493 emit_write_byte_1(emit, PYBC_POP_BLOCK);
494}
495
Damien415eb6f2013-10-05 12:19:06 +0100496static void emit_bc_pop_except(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100497 emit_pre(emit, 0);
498 emit_write_byte_1(emit, PYBC_POP_EXCEPT);
499}
500
Damien415eb6f2013-10-05 12:19:06 +0100501static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100502 emit_pre(emit, 0);
503 emit_write_byte_1_byte(emit, PYBC_UNARY_OP, op);
504}
505
Damien415eb6f2013-10-05 12:19:06 +0100506static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100507 emit_pre(emit, -1);
508 emit_write_byte_1_byte(emit, PYBC_BINARY_OP, op);
509}
510
Damien415eb6f2013-10-05 12:19:06 +0100511static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) {
Damien429d7192013-10-04 19:53:11 +0100512 emit_pre(emit, -1);
513 emit_write_byte_1_byte(emit, PYBC_COMPARE_OP, op);
514}
515
Damien415eb6f2013-10-05 12:19:06 +0100516static void emit_bc_build_tuple(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100517 assert(n_args >= 0);
518 emit_pre(emit, 1 - n_args);
519 emit_write_byte_1_uint(emit, PYBC_BUILD_TUPLE, n_args);
520}
521
Damien415eb6f2013-10-05 12:19:06 +0100522static void emit_bc_build_list(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100523 assert(n_args >= 0);
524 emit_pre(emit, 1 - n_args);
525 emit_write_byte_1_uint(emit, PYBC_BUILD_LIST, n_args);
526}
527
Damien415eb6f2013-10-05 12:19:06 +0100528static void emit_bc_list_append(emit_t *emit, int list_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100529 assert(list_stack_index >= 0);
530 emit_pre(emit, -1);
531 emit_write_byte_1_uint(emit, PYBC_LIST_APPEND, list_stack_index);
532}
533
Damien415eb6f2013-10-05 12:19:06 +0100534static void emit_bc_build_map(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100535 assert(n_args >= 0);
536 emit_pre(emit, 1);
537 emit_write_byte_1_uint(emit, PYBC_BUILD_MAP, n_args);
538}
539
Damien415eb6f2013-10-05 12:19:06 +0100540static void emit_bc_store_map(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100541 emit_pre(emit, -2);
542 emit_write_byte_1(emit, PYBC_STORE_MAP);
543}
544
Damien415eb6f2013-10-05 12:19:06 +0100545static void emit_bc_map_add(emit_t *emit, int map_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100546 assert(map_stack_index >= 0);
547 emit_pre(emit, -2);
548 emit_write_byte_1_uint(emit, PYBC_MAP_ADD, map_stack_index);
549}
550
Damien415eb6f2013-10-05 12:19:06 +0100551static void emit_bc_build_set(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100552 assert(n_args >= 0);
553 emit_pre(emit, 1 - n_args);
554 emit_write_byte_1_uint(emit, PYBC_BUILD_SET, n_args);
555}
556
Damien415eb6f2013-10-05 12:19:06 +0100557static void emit_bc_set_add(emit_t *emit, int set_stack_index) {
Damien429d7192013-10-04 19:53:11 +0100558 assert(set_stack_index >= 0);
559 emit_pre(emit, -1);
560 emit_write_byte_1_uint(emit, PYBC_SET_ADD, set_stack_index);
561}
562
Damien415eb6f2013-10-05 12:19:06 +0100563static void emit_bc_build_slice(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100564 assert(n_args >= 0);
565 emit_pre(emit, 1 - n_args);
566 emit_write_byte_1_uint(emit, PYBC_BUILD_SLICE, n_args);
567}
568
Damien415eb6f2013-10-05 12:19:06 +0100569static void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100570 assert(n_args >= 0);
571 emit_pre(emit, -1 + n_args);
572 emit_write_byte_1_uint(emit, PYBC_UNPACK_SEQUENCE, n_args);
573}
574
Damien415eb6f2013-10-05 12:19:06 +0100575static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
Damien429d7192013-10-04 19:53:11 +0100576 assert(n_left >=0 && n_right >= 0);
577 emit_pre(emit, -1 + n_left + n_right + 1);
578 emit_write_byte_1_uint(emit, PYBC_UNPACK_EX, n_left | (n_right << 8));
579}
580
Damien415eb6f2013-10-05 12:19:06 +0100581static 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 +0100582 assert(n_default_params == 0 && n_dict_params == 0);
583 emit_pre(emit, 1);
584 emit_write_byte_1_uint(emit, PYBC_MAKE_FUNCTION, scope->unique_code_id);
585}
586
Damien415eb6f2013-10-05 12:19:06 +0100587static 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 +0100588 assert(0);
589 emit_pre(emit, -2 - n_default_params - 2 * n_dict_params);
590 if (emit->pass == PASS_3) {
591 printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
592 }
593}
594
Damien415eb6f2013-10-05 12:19:06 +0100595static 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 +0100596 int s = 0;
597 if (have_star_arg) {
598 s += 1;
599 }
600 if (have_dbl_star_arg) {
601 s += 1;
602 }
603 emit_pre(emit, -n_positional - 2 * n_keyword - s);
604 int op;
605 if (have_star_arg) {
606 if (have_dbl_star_arg) {
607 op = PYBC_CALL_FUNCTION_VAR_KW;
608 } else {
609 op = PYBC_CALL_FUNCTION_VAR;
610 }
611 } else {
612 if (have_dbl_star_arg) {
613 op = PYBC_CALL_FUNCTION_KW;
614 } else {
615 op = PYBC_CALL_FUNCTION;
616 }
617 }
618 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
619}
620
Damien415eb6f2013-10-05 12:19:06 +0100621static 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 +0100622 int s = 0;
623 if (have_star_arg) {
624 s += 1;
625 }
626 if (have_dbl_star_arg) {
627 s += 1;
628 }
629 emit_pre(emit, -n_positional - 2 * n_keyword - s);
630 int op;
631 if (have_star_arg) {
632 if (have_dbl_star_arg) {
633 op = PYBC_CALL_METHOD_VAR_KW;
634 } else {
635 op = PYBC_CALL_METHOD_VAR;
636 }
637 } else {
638 if (have_dbl_star_arg) {
639 op = PYBC_CALL_METHOD_KW;
640 } else {
641 op = PYBC_CALL_METHOD;
642 }
643 }
644 emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
645}
646
Damien415eb6f2013-10-05 12:19:06 +0100647static void emit_bc_return_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100648 emit_pre(emit, -1);
649 emit->last_emit_was_return_value = true;
650 emit_write_byte_1(emit, PYBC_RETURN_VALUE);
651}
652
Damien415eb6f2013-10-05 12:19:06 +0100653static void emit_bc_raise_varargs(emit_t *emit, int n_args) {
Damien429d7192013-10-04 19:53:11 +0100654 assert(n_args >= 0);
655 emit_pre(emit, -n_args);
656 emit_write_byte_1_uint(emit, PYBC_RAISE_VARARGS, n_args);
657}
658
Damien415eb6f2013-10-05 12:19:06 +0100659static void emit_bc_yield_value(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100660 emit_pre(emit, 0);
661 if (emit->pass == PASS_2) {
662 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
663 }
664 emit_write_byte_1(emit, PYBC_YIELD_VALUE);
665}
666
Damien415eb6f2013-10-05 12:19:06 +0100667static void emit_bc_yield_from(emit_t *emit) {
Damien429d7192013-10-04 19:53:11 +0100668 emit_pre(emit, -1);
669 if (emit->pass == PASS_2) {
670 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
671 }
672 emit_write_byte_1(emit, PYBC_YIELD_FROM);
673}
674
Damien415eb6f2013-10-05 12:19:06 +0100675static const emit_method_table_t emit_bc_method_table = {
676 emit_bc_set_native_types,
677 emit_bc_start_pass,
678 emit_bc_end_pass,
679 emit_bc_last_emit_was_return_value,
680 emit_bc_get_stack_size,
681 emit_bc_set_stack_size,
682
Damien4b03e772013-10-05 14:17:09 +0100683 emit_bc_load_id,
684 emit_bc_store_id,
685 emit_bc_delete_id,
686
Damien415eb6f2013-10-05 12:19:06 +0100687 emit_bc_label_assign,
688 emit_bc_import_name,
689 emit_bc_import_from,
690 emit_bc_import_star,
691 emit_bc_load_const_tok,
692 emit_bc_load_const_small_int,
693 emit_bc_load_const_int,
694 emit_bc_load_const_dec,
695 emit_bc_load_const_id,
696 emit_bc_load_const_str,
697 emit_bc_load_const_verbatim_start,
698 emit_bc_load_const_verbatim_int,
699 emit_bc_load_const_verbatim_str,
700 emit_bc_load_const_verbatim_strn,
701 emit_bc_load_const_verbatim_quoted_str,
702 emit_bc_load_const_verbatim_end,
703 emit_bc_load_fast,
704 emit_bc_load_name,
705 emit_bc_load_global,
706 emit_bc_load_deref,
707 emit_bc_load_closure,
708 emit_bc_load_attr,
709 emit_bc_load_method,
710 emit_bc_load_build_class,
711 emit_bc_store_fast,
712 emit_bc_store_name,
713 emit_bc_store_global,
714 emit_bc_store_deref,
715 emit_bc_store_attr,
716 emit_bc_store_locals,
717 emit_bc_store_subscr,
718 emit_bc_delete_fast,
719 emit_bc_delete_name,
720 emit_bc_delete_global,
721 emit_bc_delete_deref,
722 emit_bc_delete_attr,
723 emit_bc_delete_subscr,
724 emit_bc_dup_top,
725 emit_bc_dup_top_two,
726 emit_bc_pop_top,
727 emit_bc_rot_two,
728 emit_bc_rot_three,
729 emit_bc_jump,
730 emit_bc_pop_jump_if_true,
731 emit_bc_pop_jump_if_false,
732 emit_bc_jump_if_true_or_pop,
733 emit_bc_jump_if_false_or_pop,
734 emit_bc_setup_loop,
735 emit_bc_break_loop,
736 emit_bc_continue_loop,
737 emit_bc_setup_with,
738 emit_bc_with_cleanup,
739 emit_bc_setup_except,
740 emit_bc_setup_finally,
741 emit_bc_end_finally,
742 emit_bc_get_iter,
743 emit_bc_for_iter,
744 emit_bc_for_iter_end,
745 emit_bc_pop_block,
746 emit_bc_pop_except,
747 emit_bc_unary_op,
748 emit_bc_binary_op,
749 emit_bc_compare_op,
750 emit_bc_build_tuple,
751 emit_bc_build_list,
752 emit_bc_list_append,
753 emit_bc_build_map,
754 emit_bc_store_map,
755 emit_bc_map_add,
756 emit_bc_build_set,
757 emit_bc_set_add,
758 emit_bc_build_slice,
759 emit_bc_unpack_sequence,
760 emit_bc_unpack_ex,
761 emit_bc_make_function,
762 emit_bc_make_closure,
763 emit_bc_call_function,
764 emit_bc_call_method,
765 emit_bc_return_value,
766 emit_bc_raise_varargs,
767 emit_bc_yield_value,
768 emit_bc_yield_from,
769};
770
Damienb05d7072013-10-05 13:37:10 +0100771void emit_bc_new(emit_t **emit_out, const emit_method_table_t **emit_method_table_out, uint max_num_labels) {
Damien415eb6f2013-10-05 12:19:06 +0100772 emit_t *emit = m_new(emit_t, 1);
Damienb05d7072013-10-05 13:37:10 +0100773 emit->max_num_labels = max_num_labels;
774 emit->label_offsets = m_new(uint, emit->max_num_labels);
Damien415eb6f2013-10-05 12:19:06 +0100775 emit->code_offset = 0;
776 emit->code_size = 0;
777 emit->code_base = NULL;
778
779 *emit_out = emit;
780 *emit_method_table_out = &emit_bc_method_table;
781}