emitbc.c 27.3 KB
Newer Older
Damien's avatar
Damien committed
1
2
3
4
5
6
7
8
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "misc.h"
9
#include "mpconfig.h"
10
#include "qstr.h"
Damien's avatar
Damien committed
11
12
13
#include "lexer.h"
#include "parse.h"
#include "scope.h"
14
#include "runtime0.h"
Damien's avatar
Damien committed
15
#include "emit.h"
16
#include "bc0.h"
Damien's avatar
Damien committed
17

18
19
struct _emit_t {
    pass_kind_t pass;
Damien's avatar
Damien committed
20
21
22
23
24
    int stack_size;
    bool last_emit_was_return_value;

    scope_t *scope;

25
26
27
    uint last_source_line_offset;
    uint last_source_line;

28
    uint max_num_labels;
Damien's avatar
Damien committed
29
30
    uint *label_offsets;

31
32
33
34
35
    uint code_info_offset;
    uint code_info_size;
    uint byte_code_offset;
    uint byte_code_size;
    byte *code_base; // stores both byte code and code info
Damien's avatar
Damien committed
36
37
38
    byte dummy_data[8];
};

39
emit_t *emit_bc_new(uint max_num_labels) {
40
    emit_t *emit = m_new0(emit_t, 1);
41
42
43
44
    emit->max_num_labels = max_num_labels;
    emit->label_offsets = m_new(uint, emit->max_num_labels);
    return emit;
}
45

46
void emit_bc_free(emit_t *emit) {
47
48
49
50
    m_del(uint, emit->label_offsets, emit->max_num_labels);
    m_del_obj(emit_t, emit);
}

51
// all functions must go through this one to emit code info
52
STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_write) {
53
54
55
56
57
58
59
60
61
62
    //printf("emit %d\n", num_bytes_to_write);
    if (emit->pass < PASS_3) {
        emit->code_info_offset += num_bytes_to_write;
        return emit->dummy_data;
    } else {
        assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
        byte *c = emit->code_base + emit->code_info_offset;
        emit->code_info_offset += num_bytes_to_write;
        return c;
    }
Damien's avatar
Damien committed
63
64
}

65
STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
66
67
68
69
70
71
    byte* c = emit_get_cur_to_write_code_info(emit, 4);
    // TODO variable length encoding for qstr
    c[0] = qstr & 0xff;
    c[1] = (qstr >> 8) & 0xff;
    c[2] = (qstr >> 16) & 0xff;
    c[3] = (qstr >> 24) & 0xff;
Damien's avatar
Damien committed
72
73
}

74
STATIC void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, uint lines_to_skip) {
75
76
77
78
79
80
81
    for (; bytes_to_skip > 31; bytes_to_skip -= 31) {
        *emit_get_cur_to_write_code_info(emit, 1) = 31;
    }
    for (; lines_to_skip > 7; lines_to_skip -= 7) {
        *emit_get_cur_to_write_code_info(emit, 1) = 7 << 5;
    }
    *emit_get_cur_to_write_code_info(emit, 1) = bytes_to_skip | (lines_to_skip << 5);
82
83
84
}

// all functions must go through this one to emit byte code
85
STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_write) {
Damien's avatar
Damien committed
86
87
    //printf("emit %d\n", num_bytes_to_write);
    if (emit->pass < PASS_3) {
88
        emit->byte_code_offset += num_bytes_to_write;
Damien's avatar
Damien committed
89
90
        return emit->dummy_data;
    } else {
91
92
93
        assert(emit->byte_code_offset + num_bytes_to_write <= emit->byte_code_size);
        byte *c = emit->code_base + emit->code_info_size + emit->byte_code_offset;
        emit->byte_code_offset += num_bytes_to_write;
Damien's avatar
Damien committed
94
95
96
97
        return c;
    }
}

98
STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) {
99
    byte* c = emit_get_cur_to_write_byte_code(emit, 1);
Damien's avatar
Damien committed
100
101
102
    c[0] = b1;
}

103
STATIC void emit_write_byte_code_byte_byte(emit_t* emit, byte b1, uint b2) {
Damien's avatar
Damien committed
104
    assert((b2 & (~0xff)) == 0);
105
    byte* c = emit_get_cur_to_write_byte_code(emit, 2);
Damien's avatar
Damien committed
106
107
108
109
    c[0] = b1;
    c[1] = b2;
}

110
STATIC void emit_write_byte_code_uint(emit_t* emit, uint num) {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    if (num <= 127) { // fits in 0x7f
        // fit argument in single byte
        byte* c = emit_get_cur_to_write_byte_code(emit, 1);
        c[0] = num;
    } else if (num <= 16383) { // fits in 0x3fff
        // fit argument in two bytes
        byte* c = emit_get_cur_to_write_byte_code(emit, 2);
        c[0] = (num >> 8) | 0x80;
        c[1] = num;
    } else {
        // larger numbers not implemented/supported
        assert(0);
    }
}

Damien's avatar
Damien committed
126
// integers (for small ints) are stored as 24 bits, in excess
127
STATIC void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t num) {
Damien's avatar
Damien committed
128
129
    num += 0x800000;
    assert(0 <= num && num <= 0xffffff);
130
    byte* c = emit_get_cur_to_write_byte_code(emit, 4);
Damien's avatar
Damien committed
131
132
133
    c[0] = b1;
    c[1] = num;
    c[2] = num >> 8;
134
    c[3] = num >> 16;
Damien's avatar
Damien committed
135
136
}

137
STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
138
139
    emit_write_byte_code_byte(emit, b);
    emit_write_byte_code_uint(emit, num);
Damien's avatar
Damien committed
140
141
}

142
/* currently unused
143
STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
144
145
146
147
148
149
    emit_write_byte_code_byte(emit, b);
    emit_write_byte_code_byte_uint(emit, num1);
    emit_write_byte_code_byte_uint(emit, num2);
}
*/

150
STATIC void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
151
    emit_write_byte_code_byte_uint(emit, b, qstr);
Damien's avatar
Damien committed
152
153
}

Damien's avatar
Damien committed
154
// unsigned labels are relative to ip following this instruction, stored as 16 bits
155
STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, int label) {
156
    uint byte_code_offset;
Damien's avatar
Damien committed
157
    if (emit->pass < PASS_3) {
158
        byte_code_offset = 0;
Damien's avatar
Damien committed
159
    } else {
160
        byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3;
Damien's avatar
Damien committed
161
    }
162
    byte* c = emit_get_cur_to_write_byte_code(emit, 3);
Damien's avatar
Damien committed
163
    c[0] = b1;
164
165
    c[1] = byte_code_offset;
    c[2] = byte_code_offset >> 8;
Damien's avatar
Damien committed
166
167
168
}

// signed labels are relative to ip following this instruction, stored as 16 bits, in excess
169
STATIC void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, int label) {
170
    int byte_code_offset;
Damien's avatar
Damien committed
171
    if (emit->pass < PASS_3) {
172
        byte_code_offset = 0;
Damien's avatar
Damien committed
173
    } else {
174
        byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3 + 0x8000;
Damien's avatar
Damien committed
175
    }
176
    byte* c = emit_get_cur_to_write_byte_code(emit, 3);
Damien's avatar
Damien committed
177
    c[0] = b1;
178
179
    c[1] = byte_code_offset;
    c[2] = byte_code_offset >> 8;
Damien's avatar
Damien committed
180
181
}

182
STATIC void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
Damien George's avatar
Damien George committed
183
184
}

185
STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
Damien George's avatar
Damien George committed
186
187
188
189
    emit->pass = pass;
    emit->stack_size = 0;
    emit->last_emit_was_return_value = false;
    emit->scope = scope;
190
191
    emit->last_source_line_offset = 0;
    emit->last_source_line = 1;
Damien George's avatar
Damien George committed
192
193
194
    if (pass == PASS_2) {
        memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
    }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    emit->byte_code_offset = 0;
    emit->code_info_offset = 0;

    // write code info size (don't know size at this stage in PASS_2 so need to use maximum space (4 bytes) to write it)
    {
        byte* c = emit_get_cur_to_write_code_info(emit, 4);
        machine_uint_t s = emit->code_info_size;
        c[0] = s & 0xff;
        c[1] = (s >> 8) & 0xff;
        c[2] = (s >> 16) & 0xff;
        c[3] = (s >> 24) & 0xff;
    }

    // code info
209
210
    emit_write_code_info_qstr(emit, scope->source_file);
    emit_write_code_info_qstr(emit, scope->simple_name);
Damien George's avatar
Damien George committed
211
212
213
214
215
216
217
218
219
220

    // prelude for initialising closed over variables
    int num_cell = 0;
    for (int i = 0; i < scope->id_info_len; i++) {
        id_info_t *id = &scope->id_info[i];
        if (id->kind == ID_INFO_KIND_CELL) {
            num_cell += 1;
        }
    }
    assert(num_cell <= 255);
221
    emit_write_byte_code_byte(emit, num_cell); // write number of locals that are cells
Damien George's avatar
Damien George committed
222
223
224
    for (int i = 0; i < scope->id_info_len; i++) {
        id_info_t *id = &scope->id_info[i];
        if (id->kind == ID_INFO_KIND_CELL) {
225
            emit_write_byte_code_byte(emit, id->local_num); // write the local which should be converted to a cell
Damien George's avatar
Damien George committed
226
227
228
229
        }
    }
}

230
STATIC void emit_bc_end_pass(emit_t *emit) {
Damien George's avatar
Damien George committed
231
232
233
234
235
    // check stack is back to zero size
    if (emit->stack_size != 0) {
        printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
    }

236
    emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
237

Damien George's avatar
Damien George committed
238
239
    if (emit->pass == PASS_2) {
        // calculate size of code in bytes
240
241
242
        emit->code_info_size = emit->code_info_offset;
        emit->byte_code_size = emit->byte_code_offset;
        emit->code_base = m_new(byte, emit->code_info_size + emit->byte_code_size);
Damien George's avatar
Damien George committed
243
244

    } else if (emit->pass == PASS_3) {
245
        rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_info_size + emit->byte_code_size, emit->scope->num_params, emit->scope->num_locals, emit->scope->stack_size, (emit->scope->flags & SCOPE_FLAG_GENERATOR) != 0);
Damien George's avatar
Damien George committed
246
247
248
    }
}

249
bool emit_bc_last_emit_was_return_value(emit_t *emit) {
Damien's avatar
Damien committed
250
251
252
    return emit->last_emit_was_return_value;
}

253
int emit_bc_get_stack_size(emit_t *emit) {
Damien's avatar
Damien committed
254
255
256
    return emit->stack_size;
}

257
STATIC void emit_bc_set_stack_size(emit_t *emit, int size) {
258
    emit->stack_size = size;
Damien's avatar
Damien committed
259
260
}

261
STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) {
262
    //printf("source: line %d -> %d  offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->byte_code_offset);
263
#if MICROPY_ENABLE_SOURCE_LINE
264
    if (source_line > emit->last_source_line) {
265
266
267
        uint bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset;
        uint lines_to_skip = source_line - emit->last_source_line;
        emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
268
        //printf("  %d %d\n", bytes_to_skip, lines_to_skip);
269
270
271
        emit->last_source_line_offset = emit->byte_code_offset;
        emit->last_source_line = source_line;
    }
272
#endif
273
274
}

275
STATIC void emit_bc_load_id(emit_t *emit, qstr qstr) {
276
277
278
    emit_common_load_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

279
STATIC void emit_bc_store_id(emit_t *emit, qstr qstr) {
280
281
282
    emit_common_store_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

283
STATIC void emit_bc_delete_id(emit_t *emit, qstr qstr) {
284
285
286
    emit_common_delete_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

287
// TODO: module-polymorphic function (read: name clash if made global)
288
static void emit_pre(emit_t *emit, int stack_size_delta) {
289
290
291
    emit->stack_size += stack_size_delta;
    if (emit->stack_size > emit->scope->stack_size) {
        emit->scope->stack_size = emit->stack_size;
Damien's avatar
Damien committed
292
293
294
295
    }
    emit->last_emit_was_return_value = false;
}

296
STATIC void emit_bc_label_assign(emit_t *emit, int l) {
Damien's avatar
Damien committed
297
    emit_pre(emit, 0);
298
299
300
301
    assert(l < emit->max_num_labels);
    if (emit->pass == PASS_2) {
        // assign label offset
        assert(emit->label_offsets[l] == -1);
302
        emit->label_offsets[l] = emit->byte_code_offset;
303
304
    } else if (emit->pass == PASS_3) {
        // ensure label offset has not changed from PASS_2 to PASS_3
305
306
        //printf("l%d: (at %d vs %d)\n", l, emit->byte_code_offset, emit->label_offsets[l]);
        assert(emit->label_offsets[l] == emit->byte_code_offset);
Damien's avatar
Damien committed
307
308
309
    }
}

310
STATIC void emit_bc_import_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
311
    emit_pre(emit, -1);
312
    emit_write_byte_code_byte_qstr(emit, MP_BC_IMPORT_NAME, qstr);
Damien's avatar
Damien committed
313
314
}

315
STATIC void emit_bc_import_from(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
316
    emit_pre(emit, 1);
317
    emit_write_byte_code_byte_qstr(emit, MP_BC_IMPORT_FROM, qstr);
Damien's avatar
Damien committed
318
319
}

320
STATIC void emit_bc_import_star(emit_t *emit) {
Damien's avatar
Damien committed
321
    emit_pre(emit, -1);
322
    emit_write_byte_code_byte(emit, MP_BC_IMPORT_STAR);
Damien's avatar
Damien committed
323
324
}

325
STATIC void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
Damien's avatar
Damien committed
326
327
    emit_pre(emit, 1);
    switch (tok) {
328
329
330
331
        case MP_TOKEN_KW_FALSE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_FALSE); break;
        case MP_TOKEN_KW_NONE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_NONE); break;
        case MP_TOKEN_KW_TRUE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_TRUE); break;
        case MP_TOKEN_ELLIPSIS: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_ELLIPSIS); break;
Damien's avatar
Damien committed
332
333
334
335
        default: assert(0);
    }
}

336
STATIC void emit_bc_load_const_small_int(emit_t *emit, machine_int_t arg) {
Damien's avatar
Damien committed
337
    emit_pre(emit, 1);
338
    emit_write_byte_code_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg);
Damien's avatar
Damien committed
339
340
}

341
STATIC void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
342
    emit_pre(emit, 1);
343
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_INT, qstr);
Damien's avatar
Damien committed
344
345
}

346
STATIC void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
347
    emit_pre(emit, 1);
348
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr);
Damien's avatar
Damien committed
349
350
}

351
STATIC void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
352
    emit_pre(emit, 1);
353
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_ID, qstr);
Damien's avatar
Damien committed
354
355
}

356
STATIC void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
Damien's avatar
Damien committed
357
358
    emit_pre(emit, 1);
    if (bytes) {
359
        emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr);
Damien's avatar
Damien committed
360
    } else {
361
        emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr);
Damien's avatar
Damien committed
362
363
364
    }
}

365
STATIC void emit_bc_load_const_verbatim_str(emit_t *emit, const char *str) {
366
    // not needed/supported for BC
Damien's avatar
Damien committed
367
368
369
    assert(0);
}

370
STATIC void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
371
372
373
    assert(local_num >= 0);
    emit_pre(emit, 1);
    switch (local_num) {
374
375
376
377
        case 0: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_0); break;
        case 1: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_1); break;
        case 2: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_2); break;
        default: emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break;
Damien's avatar
Damien committed
378
379
380
    }
}

381
STATIC void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
382
    emit_pre(emit, 1);
383
    emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_DEREF, local_num);
Damien's avatar
Damien committed
384
385
}

386
STATIC void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
Damien George's avatar
Damien George committed
387
388
    // not needed/supported for BC
    assert(0);
Damien's avatar
Damien committed
389
390
}

391
STATIC void emit_bc_load_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
392
    emit_pre(emit, 1);
393
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_NAME, qstr);
Damien's avatar
Damien committed
394
395
}

396
STATIC void emit_bc_load_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
397
    emit_pre(emit, 1);
398
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_GLOBAL, qstr);
Damien's avatar
Damien committed
399
400
}

401
STATIC void emit_bc_load_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
402
    emit_pre(emit, 0);
403
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_ATTR, qstr);
Damien's avatar
Damien committed
404
405
}

406
STATIC void emit_bc_load_method(emit_t *emit, qstr qstr) {
407
    emit_pre(emit, 1);
408
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_METHOD, qstr);
Damien's avatar
Damien committed
409
410
}

411
STATIC void emit_bc_load_build_class(emit_t *emit) {
Damien's avatar
Damien committed
412
    emit_pre(emit, 1);
413
    emit_write_byte_code_byte(emit, MP_BC_LOAD_BUILD_CLASS);
Damien's avatar
Damien committed
414
415
}

416
STATIC void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
417
418
419
    assert(local_num >= 0);
    emit_pre(emit, -1);
    switch (local_num) {
420
421
422
423
        case 0: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_0); break;
        case 1: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_1); break;
        case 2: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_2); break;
        default: emit_write_byte_code_byte_uint(emit, MP_BC_STORE_FAST_N, local_num); break;
Damien's avatar
Damien committed
424
425
426
    }
}

427
STATIC void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
428
    emit_pre(emit, -1);
429
    emit_write_byte_code_byte_uint(emit, MP_BC_STORE_DEREF, local_num);
Damien's avatar
Damien committed
430
431
}

432
STATIC void emit_bc_store_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
433
    emit_pre(emit, -1);
434
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_NAME, qstr);
Damien's avatar
Damien committed
435
436
}

437
STATIC void emit_bc_store_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
438
    emit_pre(emit, -1);
439
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_GLOBAL, qstr);
Damien's avatar
Damien committed
440
441
}

442
STATIC void emit_bc_store_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
443
    emit_pre(emit, -2);
444
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_ATTR, qstr);
Damien's avatar
Damien committed
445
446
}

447
STATIC void emit_bc_store_subscr(emit_t *emit) {
Damien's avatar
Damien committed
448
    emit_pre(emit, -3);
449
    emit_write_byte_code_byte(emit, MP_BC_STORE_SUBSCR);
Damien's avatar
Damien committed
450
451
}

452
STATIC void emit_bc_store_locals(emit_t *emit) {
453
    // not needed
454
    emit_pre(emit, -1);
455
    emit_write_byte_code_byte(emit, MP_BC_POP_TOP);
456
457
}

458
STATIC void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
459
460
    assert(local_num >= 0);
    emit_pre(emit, 0);
461
    emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_FAST_N, local_num);
Damien's avatar
Damien committed
462
463
}

464
STATIC void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
465
    emit_pre(emit, 0);
466
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_DEREF, local_num);
Damien's avatar
Damien committed
467
468
}

469
STATIC void emit_bc_delete_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
470
    emit_pre(emit, 0);
471
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_NAME, qstr);
Damien's avatar
Damien committed
472
473
}

474
STATIC void emit_bc_delete_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
475
    emit_pre(emit, 0);
476
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_GLOBAL, qstr);
Damien's avatar
Damien committed
477
478
}

479
STATIC void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
480
    emit_pre(emit, -1);
481
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_ATTR, qstr);
Damien's avatar
Damien committed
482
483
}

484
STATIC void emit_bc_delete_subscr(emit_t *emit) {
Damien's avatar
Damien committed
485
    emit_pre(emit, -2);
486
    emit_write_byte_code_byte(emit, MP_BC_DELETE_SUBSCR);
Damien's avatar
Damien committed
487
488
}

489
STATIC void emit_bc_dup_top(emit_t *emit) {
Damien's avatar
Damien committed
490
    emit_pre(emit, 1);
491
    emit_write_byte_code_byte(emit, MP_BC_DUP_TOP);
Damien's avatar
Damien committed
492
493
}

494
STATIC void emit_bc_dup_top_two(emit_t *emit) {
Damien's avatar
Damien committed
495
    emit_pre(emit, 2);
496
    emit_write_byte_code_byte(emit, MP_BC_DUP_TOP_TWO);
Damien's avatar
Damien committed
497
498
}

499
STATIC void emit_bc_pop_top(emit_t *emit) {
Damien's avatar
Damien committed
500
    emit_pre(emit, -1);
501
    emit_write_byte_code_byte(emit, MP_BC_POP_TOP);
Damien's avatar
Damien committed
502
503
}

504
STATIC void emit_bc_rot_two(emit_t *emit) {
Damien's avatar
Damien committed
505
    emit_pre(emit, 0);
506
    emit_write_byte_code_byte(emit, MP_BC_ROT_TWO);
Damien's avatar
Damien committed
507
508
}

509
STATIC void emit_bc_rot_three(emit_t *emit) {
Damien's avatar
Damien committed
510
    emit_pre(emit, 0);
511
    emit_write_byte_code_byte(emit, MP_BC_ROT_THREE);
Damien's avatar
Damien committed
512
513
}

514
STATIC void emit_bc_jump(emit_t *emit, int label) {
Damien's avatar
Damien committed
515
    emit_pre(emit, 0);
516
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP, label);
Damien's avatar
Damien committed
517
518
}

519
STATIC void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
Damien's avatar
Damien committed
520
    emit_pre(emit, -1);
521
    emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label);
Damien's avatar
Damien committed
522
523
}

524
STATIC void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
Damien's avatar
Damien committed
525
    emit_pre(emit, -1);
526
    emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label);
Damien's avatar
Damien committed
527
528
}

529
STATIC void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
Damien's avatar
Damien committed
530
    emit_pre(emit, -1);
531
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label);
Damien's avatar
Damien committed
532
533
}

534
STATIC void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
Damien's avatar
Damien committed
535
    emit_pre(emit, -1);
536
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label);
Damien's avatar
Damien committed
537
538
}

539
STATIC void emit_bc_setup_loop(emit_t *emit, int label) {
Damien's avatar
Damien committed
540
    emit_pre(emit, 0);
541
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_LOOP, label);
Damien's avatar
Damien committed
542
543
}

544
STATIC void emit_bc_unwind_jump(emit_t *emit, int label, int except_depth) {
545
546
547
548
549
550
551
    if (except_depth == 0) {
        emit_bc_jump(emit, label);
    } else {
        emit_pre(emit, 0);
        emit_write_byte_code_byte_signed_label(emit, MP_BC_UNWIND_JUMP, label);
        emit_write_byte_code_byte(emit, except_depth);
    }
Damien's avatar
Damien committed
552
553
}

554
STATIC void emit_bc_setup_with(emit_t *emit, int label) {
Damien's avatar
Damien committed
555
    emit_pre(emit, 7);
556
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label);
Damien's avatar
Damien committed
557
558
}

559
STATIC void emit_bc_with_cleanup(emit_t *emit) {
Damien's avatar
Damien committed
560
    emit_pre(emit, -7);
561
    emit_write_byte_code_byte(emit, MP_BC_WITH_CLEANUP);
Damien's avatar
Damien committed
562
563
}

564
STATIC void emit_bc_setup_except(emit_t *emit, int label) {
Damien's avatar
Damien committed
565
    emit_pre(emit, 6);
566
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label);
Damien's avatar
Damien committed
567
568
}

569
STATIC void emit_bc_setup_finally(emit_t *emit, int label) {
Damien's avatar
Damien committed
570
    emit_pre(emit, 6);
571
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label);
Damien's avatar
Damien committed
572
573
}

574
STATIC void emit_bc_end_finally(emit_t *emit) {
Damien's avatar
Damien committed
575
    emit_pre(emit, -1);
576
    emit_write_byte_code_byte(emit, MP_BC_END_FINALLY);
Damien's avatar
Damien committed
577
578
}

579
STATIC void emit_bc_get_iter(emit_t *emit) {
Damien's avatar
Damien committed
580
    emit_pre(emit, 0);
581
    emit_write_byte_code_byte(emit, MP_BC_GET_ITER);
Damien's avatar
Damien committed
582
583
}

584
STATIC void emit_bc_for_iter(emit_t *emit, int label) {
Damien's avatar
Damien committed
585
    emit_pre(emit, 1);
586
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_FOR_ITER, label);
Damien's avatar
Damien committed
587
588
}

589
STATIC void emit_bc_for_iter_end(emit_t *emit) {
Damien's avatar
Damien committed
590
591
592
    emit_pre(emit, -1);
}

593
STATIC void emit_bc_pop_block(emit_t *emit) {
Damien's avatar
Damien committed
594
    emit_pre(emit, 0);
595
    emit_write_byte_code_byte(emit, MP_BC_POP_BLOCK);
Damien's avatar
Damien committed
596
597
}

598
STATIC void emit_bc_pop_except(emit_t *emit) {
Damien's avatar
Damien committed
599
    emit_pre(emit, 0);
600
    emit_write_byte_code_byte(emit, MP_BC_POP_EXCEPT);
Damien's avatar
Damien committed
601
602
}

603
STATIC void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
604
605
606
607
608
609
610
611
612
    if (op == RT_UNARY_OP_NOT) {
        emit_pre(emit, 0);
        emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, RT_UNARY_OP_BOOL);
        emit_pre(emit, 0);
        emit_write_byte_code_byte(emit, MP_BC_NOT);
    } else {
        emit_pre(emit, 0);
        emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, op);
    }
Damien's avatar
Damien committed
613
614
}

615
STATIC void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
616
617
618
619
620
621
622
623
    bool invert = false;
    if (op == RT_BINARY_OP_NOT_IN) {
        invert = true;
        op = RT_BINARY_OP_IN;
    } else if (op == RT_BINARY_OP_IS_NOT) {
        invert = true;
        op = RT_BINARY_OP_IS;
    }
Damien's avatar
Damien committed
624
    emit_pre(emit, -1);
625
    emit_write_byte_code_byte_byte(emit, MP_BC_BINARY_OP, op);
626
627
628
629
    if (invert) {
        emit_pre(emit, 0);
        emit_write_byte_code_byte(emit, MP_BC_NOT);
    }
Damien's avatar
Damien committed
630
631
}

632
STATIC void emit_bc_build_tuple(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
633
634
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
635
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_TUPLE, n_args);
Damien's avatar
Damien committed
636
637
}

638
STATIC void emit_bc_build_list(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
639
640
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
641
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_LIST, n_args);
Damien's avatar
Damien committed
642
643
}

644
STATIC void emit_bc_list_append(emit_t *emit, int list_stack_index) {
Damien's avatar
Damien committed
645
646
    assert(list_stack_index >= 0);
    emit_pre(emit, -1);
647
    emit_write_byte_code_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index);
Damien's avatar
Damien committed
648
649
}

650
STATIC void emit_bc_build_map(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
651
652
    assert(n_args >= 0);
    emit_pre(emit, 1);
653
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_MAP, n_args);
Damien's avatar
Damien committed
654
655
}

656
STATIC void emit_bc_store_map(emit_t *emit) {
Damien's avatar
Damien committed
657
    emit_pre(emit, -2);
658
    emit_write_byte_code_byte(emit, MP_BC_STORE_MAP);
Damien's avatar
Damien committed
659
660
}

661
STATIC void emit_bc_map_add(emit_t *emit, int map_stack_index) {
Damien's avatar
Damien committed
662
663
    assert(map_stack_index >= 0);
    emit_pre(emit, -2);
664
    emit_write_byte_code_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index);
Damien's avatar
Damien committed
665
666
}

667
STATIC void emit_bc_build_set(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
668
669
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
670
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SET, n_args);
Damien's avatar
Damien committed
671
672
}

673
STATIC void emit_bc_set_add(emit_t *emit, int set_stack_index) {
Damien's avatar
Damien committed
674
675
    assert(set_stack_index >= 0);
    emit_pre(emit, -1);
676
    emit_write_byte_code_byte_uint(emit, MP_BC_SET_ADD, set_stack_index);
Damien's avatar
Damien committed
677
678
}

679
STATIC void emit_bc_build_slice(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
680
681
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
682
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SLICE, n_args);
Damien's avatar
Damien committed
683
684
}

685
STATIC void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
686
687
    assert(n_args >= 0);
    emit_pre(emit, -1 + n_args);
688
    emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args);
Damien's avatar
Damien committed
689
690
}

691
STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
Damien's avatar
Damien committed
692
693
    assert(n_left >=0 && n_right >= 0);
    emit_pre(emit, -1 + n_left + n_right + 1);
694
    emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8));
Damien's avatar
Damien committed
695
696
}

697
STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
698
    assert(n_dict_params == 0);
699
700
701
702
    if (n_default_params == 0) {
        emit_pre(emit, 1);
        emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
    } else {
703
704
705
706
        emit_bc_build_tuple(emit, n_default_params);
        emit_pre(emit, 0);
        emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
    }
Damien's avatar
Damien committed
707
708
}

709
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
Damien's avatar
Damien committed
710
711
    assert(n_default_params == 0 && n_dict_params == 0);
    emit_pre(emit, 0);
712
    emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
Damien's avatar
Damien committed
713
714
}

715
STATIC void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
Damien's avatar
Damien committed
716
717
718
719
720
721
722
723
724
725
726
    int s = 0;
    if (have_star_arg) {
        s += 1;
    }
    if (have_dbl_star_arg) {
        s += 1;
    }
    emit_pre(emit, -n_positional - 2 * n_keyword - s);
    int op;
    if (have_star_arg) {
        if (have_dbl_star_arg) {
727
            op = MP_BC_CALL_FUNCTION_VAR_KW;
Damien's avatar
Damien committed
728
        } else {
729
            op = MP_BC_CALL_FUNCTION_VAR;
Damien's avatar
Damien committed
730
731
732
        }
    } else {
        if (have_dbl_star_arg) {
733
            op = MP_BC_CALL_FUNCTION_KW;
Damien's avatar
Damien committed
734
        } else {
735
            op = MP_BC_CALL_FUNCTION;
Damien's avatar
Damien committed
736
737
        }
    }
738
    emit_write_byte_code_byte_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
Damien's avatar
Damien committed
739
740
}

741
STATIC void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
Damien's avatar
Damien committed
742
743
744
745
746
747
748
    int s = 0;
    if (have_star_arg) {
        s += 1;
    }
    if (have_dbl_star_arg) {
        s += 1;
    }
749
    emit_pre(emit, -1 - n_positional - 2 * n_keyword - s);
Damien's avatar
Damien committed
750
751
752
    int op;
    if (have_star_arg) {
        if (have_dbl_star_arg) {
753
            op = MP_BC_CALL_METHOD_VAR_KW;
Damien's avatar
Damien committed
754
        } else {
755
            op = MP_BC_CALL_METHOD_VAR;
Damien's avatar
Damien committed
756
757
758
        }
    } else {
        if (have_dbl_star_arg) {
759
            op = MP_BC_CALL_METHOD_KW;
Damien's avatar
Damien committed
760
        } else {
761
            op = MP_BC_CALL_METHOD;
Damien's avatar
Damien committed
762
763
        }
    }
764
    emit_write_byte_code_byte_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
Damien's avatar
Damien committed
765
766
}

767
STATIC void emit_bc_return_value(emit_t *emit) {
Damien's avatar
Damien committed
768
769
    emit_pre(emit, -1);
    emit->last_emit_was_return_value = true;
770
    emit_write_byte_code_byte(emit, MP_BC_RETURN_VALUE);
Damien's avatar
Damien committed
771
772
}

773
STATIC void emit_bc_raise_varargs(emit_t *emit, int n_args) {
774
    assert(0 <= n_args && n_args <= 2);
Damien's avatar
Damien committed
775
    emit_pre(emit, -n_args);
776
    emit_write_byte_code_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args);
Damien's avatar
Damien committed
777
778
}

779
STATIC void emit_bc_yield_value(emit_t *emit) {
Damien's avatar
Damien committed
780
781
782
783
    emit_pre(emit, 0);
    if (emit->pass == PASS_2) {
        emit->scope->flags |= SCOPE_FLAG_GENERATOR;
    }
784
    emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE);
Damien's avatar
Damien committed
785
786
}

787
STATIC void emit_bc_yield_from(emit_t *emit) {
Damien's avatar
Damien committed
788
789
790
791
    emit_pre(emit, -1);
    if (emit->pass == PASS_2) {
        emit->scope->flags |= SCOPE_FLAG_GENERATOR;
    }
792
    emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM);
Damien's avatar
Damien committed
793
794
}

795
const emit_method_table_t emit_bc_method_table = {
796
797
798
799
800
801
    emit_bc_set_native_types,
    emit_bc_start_pass,
    emit_bc_end_pass,
    emit_bc_last_emit_was_return_value,
    emit_bc_get_stack_size,
    emit_bc_set_stack_size,
802
    emit_bc_set_source_line,
803

804
805
806
807
    emit_bc_load_id,
    emit_bc_store_id,
    emit_bc_delete_id,

808
809
810
811
812
813
814
815
816
817
818
819
820
821
    emit_bc_label_assign,
    emit_bc_import_name,
    emit_bc_import_from,
    emit_bc_import_star,
    emit_bc_load_const_tok,
    emit_bc_load_const_small_int,
    emit_bc_load_const_int,
    emit_bc_load_const_dec,
    emit_bc_load_const_id,
    emit_bc_load_const_str,
    emit_bc_load_const_verbatim_str,
    emit_bc_load_fast,
    emit_bc_load_deref,
    emit_bc_load_closure,
Damien's avatar
Damien committed
822
823
    emit_bc_load_name,
    emit_bc_load_global,
824
825
826
827
    emit_bc_load_attr,
    emit_bc_load_method,
    emit_bc_load_build_class,
    emit_bc_store_fast,
Damien's avatar
Damien committed
828
    emit_bc_store_deref,
829
830
831
832
    emit_bc_store_name,
    emit_bc_store_global,
    emit_bc_store_attr,
    emit_bc_store_subscr,
833
    emit_bc_store_locals,
834
    emit_bc_delete_fast,
Damien's avatar
Damien committed
835
    emit_bc_delete_deref,
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
    emit_bc_delete_name,
    emit_bc_delete_global,
    emit_bc_delete_attr,
    emit_bc_delete_subscr,
    emit_bc_dup_top,
    emit_bc_dup_top_two,
    emit_bc_pop_top,
    emit_bc_rot_two,
    emit_bc_rot_three,
    emit_bc_jump,
    emit_bc_pop_jump_if_true,
    emit_bc_pop_jump_if_false,
    emit_bc_jump_if_true_or_pop,
    emit_bc_jump_if_false_or_pop,
    emit_bc_setup_loop,
851
852
    emit_bc_unwind_jump,
    emit_bc_unwind_jump,
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
    emit_bc_setup_with,
    emit_bc_with_cleanup,
    emit_bc_setup_except,
    emit_bc_setup_finally,
    emit_bc_end_finally,
    emit_bc_get_iter,
    emit_bc_for_iter,
    emit_bc_for_iter_end,
    emit_bc_pop_block,
    emit_bc_pop_except,
    emit_bc_unary_op,
    emit_bc_binary_op,
    emit_bc_build_tuple,
    emit_bc_build_list,
    emit_bc_list_append,
    emit_bc_build_map,
    emit_bc_store_map,
    emit_bc_map_add,
    emit_bc_build_set,
    emit_bc_set_add,
    emit_bc_build_slice,
    emit_bc_unpack_sequence,
    emit_bc_unpack_ex,
    emit_bc_make_function,
    emit_bc_make_closure,
    emit_bc_call_function,
    emit_bc_call_method,
    emit_bc_return_value,
    emit_bc_raise_varargs,
    emit_bc_yield_value,
    emit_bc_yield_from,
};