emitbc.c 28.7 KB
Newer Older
xbe's avatar
xbe committed
1
#include <stdbool.h>
Damien's avatar
Damien committed
2
3
4
5
6
7
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

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

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

    scope_t *scope;

24
25
26
    uint last_source_line_offset;
    uint last_source_line;

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

30
31
32
33
34
    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
35
36
37
    byte dummy_data[8];
};

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

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

50
// all functions must go through this one to emit code info
51
STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_write) {
52
53
54
55
56
57
58
59
60
61
    //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
62
63
}

64
STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
65
66
67
68
69
70
    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
71
72
}

73
STATIC void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, uint lines_to_skip) {
74
75
76
77
78
79
80
    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);
81
82
83
}

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

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

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

109
STATIC void emit_write_byte_code_uint(emit_t* emit, uint num) {
110
    // We store each 7 bits in a separate byte, and that's how many bytes needed
111
    byte buf[(BYTES_PER_WORD * 8 + 6) / 7];
112
113
114
115
116
117
118
119
120
    byte *p = buf + sizeof(buf);
    // We encode in little-ending order, but store in big-endian, to help decoding
    do {
        *--p = num & 0x7f;
        num >>= 7;
    } while (num != 0);
    byte* c = emit_get_cur_to_write_byte_code(emit, buf + sizeof(buf) - p);
    while (p != buf + sizeof(buf) - 1) {
        *c++ = *p++ | 0x80;
121
    }
122
    *c = *p;
123
124
}

125
// Similar to emit_write_byte_code_uint(), just some extra handling to encode sign
126
STATIC void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t num) {
127
128
129
    emit_write_byte_code_byte(emit, b1);

    // We store each 7 bits in a separate byte, and that's how many bytes needed
130
    byte buf[(BYTES_PER_WORD * 8 + 6) / 7];
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    byte *p = buf + sizeof(buf);
    // We encode in little-ending order, but store in big-endian, to help decoding
    do {
        *--p = num & 0x7f;
        num >>= 7;
    } while (num != 0 && num != -1);
    // Make sure that highest bit we stored (mask 0x40) matches sign
    // of the number. If not, store extra byte just to encode sign
    if (num == -1 && (*p & 0x40) == 0) {
        *--p = 0x7f;
    } else if (num == 0 && (*p & 0x40) != 0) {
        *--p = 0;
    }

    byte* c = emit_get_cur_to_write_byte_code(emit, buf + sizeof(buf) - p);
    while (p != buf + sizeof(buf) - 1) {
        *c++ = *p++ | 0x80;
    }
    *c = *p;
Damien's avatar
Damien committed
150
151
}

152
STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
153
154
    emit_write_byte_code_byte(emit, b);
    emit_write_byte_code_uint(emit, num);
Damien's avatar
Damien committed
155
156
}

157
/* currently unused
158
STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
159
160
161
162
163
164
    emit_write_byte_code_byte(emit, b);
    emit_write_byte_code_byte_uint(emit, num1);
    emit_write_byte_code_byte_uint(emit, num2);
}
*/

165
STATIC void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
166
    emit_write_byte_code_byte_uint(emit, b, qstr);
Damien's avatar
Damien committed
167
168
}

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

// signed labels are relative to ip following this instruction, stored as 16 bits, in excess
184
STATIC void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, int label) {
185
    int byte_code_offset;
Damien's avatar
Damien committed
186
    if (emit->pass < PASS_3) {
187
        byte_code_offset = 0;
Damien's avatar
Damien committed
188
    } else {
189
        byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3 + 0x8000;
Damien's avatar
Damien committed
190
    }
191
    byte* c = emit_get_cur_to_write_byte_code(emit, 3);
Damien's avatar
Damien committed
192
    c[0] = b1;
193
194
    c[1] = byte_code_offset;
    c[2] = byte_code_offset >> 8;
Damien's avatar
Damien committed
195
196
}

197
STATIC void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
Damien George's avatar
Damien George committed
198
199
}

200
STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
Damien George's avatar
Damien George committed
201
202
203
204
    emit->pass = pass;
    emit->stack_size = 0;
    emit->last_emit_was_return_value = false;
    emit->scope = scope;
205
206
    emit->last_source_line_offset = 0;
    emit->last_source_line = 1;
Damien George's avatar
Damien George committed
207
208
209
    if (pass == PASS_2) {
        memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
    }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    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
224
225
    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
226

227
    // bytecode prelude: local state size and exception stack size; 16 bit uints for now
228
    {
229
230
231
232
233
234
        byte* c = emit_get_cur_to_write_byte_code(emit, 4);
        uint n_state = scope->num_locals + scope->stack_size;
        c[0] = n_state & 0xff;
        c[1] = (n_state >> 8) & 0xff;
        c[2] = scope->exc_stack_size & 0xff;
        c[3] = (scope->exc_stack_size >> 8) & 0xff;
235
236
237
    }

    // bytecode prelude: initialise closed over variables
Damien George's avatar
Damien George committed
238
239
240
241
242
243
244
245
    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);
246
    emit_write_byte_code_byte(emit, num_cell); // write number of locals that are cells
Damien George's avatar
Damien George committed
247
248
249
    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) {
250
            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
251
252
253
254
        }
    }
}

255
STATIC void emit_bc_end_pass(emit_t *emit) {
Damien George's avatar
Damien George committed
256
257
258
259
260
    // 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);
    }

261
    emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
262

Damien George's avatar
Damien George committed
263
264
    if (emit->pass == PASS_2) {
        // calculate size of code in bytes
265
266
267
        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
268
269

    } else if (emit->pass == PASS_3) {
270
271
272
273
274
275
276
277
        qstr *arg_names = m_new(qstr, emit->scope->num_params);
        for (int i = 0; i < emit->scope->num_params; i++) {
            arg_names[i] = emit->scope->id_info[i].qstr;
        }
        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->scope_flags, arg_names);
Damien George's avatar
Damien George committed
278
279
280
    }
}

281
bool emit_bc_last_emit_was_return_value(emit_t *emit) {
Damien's avatar
Damien committed
282
283
284
    return emit->last_emit_was_return_value;
}

285
int emit_bc_get_stack_size(emit_t *emit) {
Damien's avatar
Damien committed
286
287
288
    return emit->stack_size;
}

289
STATIC void emit_bc_set_stack_size(emit_t *emit, int size) {
290
    emit->stack_size = size;
Damien's avatar
Damien committed
291
292
}

293
STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) {
294
    //printf("source: line %d -> %d  offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->byte_code_offset);
295
#if MICROPY_ENABLE_SOURCE_LINE
296
    if (source_line > emit->last_source_line) {
297
298
299
        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);
300
        //printf("  %d %d\n", bytes_to_skip, lines_to_skip);
301
302
303
        emit->last_source_line_offset = emit->byte_code_offset;
        emit->last_source_line = source_line;
    }
304
#endif
305
306
}

307
STATIC void emit_bc_load_id(emit_t *emit, qstr qstr) {
308
309
310
    emit_common_load_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

311
STATIC void emit_bc_store_id(emit_t *emit, qstr qstr) {
312
313
314
    emit_common_store_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

315
STATIC void emit_bc_delete_id(emit_t *emit, qstr qstr) {
316
317
318
    emit_common_delete_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

319
// TODO: module-polymorphic function (read: name clash if made global)
320
static void emit_pre(emit_t *emit, int stack_size_delta) {
321
322
323
    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
324
325
326
327
    }
    emit->last_emit_was_return_value = false;
}

328
STATIC void emit_bc_label_assign(emit_t *emit, int l) {
Damien's avatar
Damien committed
329
    emit_pre(emit, 0);
330
331
332
333
    assert(l < emit->max_num_labels);
    if (emit->pass == PASS_2) {
        // assign label offset
        assert(emit->label_offsets[l] == -1);
334
        emit->label_offsets[l] = emit->byte_code_offset;
335
336
    } else if (emit->pass == PASS_3) {
        // ensure label offset has not changed from PASS_2 to PASS_3
337
338
        //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
339
340
341
    }
}

342
STATIC void emit_bc_import_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
343
    emit_pre(emit, -1);
344
    emit_write_byte_code_byte_qstr(emit, MP_BC_IMPORT_NAME, qstr);
Damien's avatar
Damien committed
345
346
}

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

352
STATIC void emit_bc_import_star(emit_t *emit) {
Damien's avatar
Damien committed
353
    emit_pre(emit, -1);
354
    emit_write_byte_code_byte(emit, MP_BC_IMPORT_STAR);
Damien's avatar
Damien committed
355
356
}

357
STATIC void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
Damien's avatar
Damien committed
358
359
    emit_pre(emit, 1);
    switch (tok) {
360
361
362
363
        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
364
365
366
367
        default: assert(0);
    }
}

368
STATIC void emit_bc_load_const_small_int(emit_t *emit, machine_int_t arg) {
Damien's avatar
Damien committed
369
    emit_pre(emit, 1);
370
    emit_write_byte_code_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg);
Damien's avatar
Damien committed
371
372
}

373
STATIC void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
374
    emit_pre(emit, 1);
375
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_INT, qstr);
Damien's avatar
Damien committed
376
377
}

378
STATIC void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
379
    emit_pre(emit, 1);
380
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr);
Damien's avatar
Damien committed
381
382
}

383
STATIC void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
384
    emit_pre(emit, 1);
385
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_ID, qstr);
Damien's avatar
Damien committed
386
387
}

388
STATIC void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
Damien's avatar
Damien committed
389
390
    emit_pre(emit, 1);
    if (bytes) {
391
        emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr);
Damien's avatar
Damien committed
392
    } else {
393
        emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr);
Damien's avatar
Damien committed
394
395
396
    }
}

397
STATIC void emit_bc_load_const_verbatim_str(emit_t *emit, const char *str) {
398
    // not needed/supported for BC
Damien's avatar
Damien committed
399
400
401
    assert(0);
}

402
STATIC void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
403
404
405
    assert(local_num >= 0);
    emit_pre(emit, 1);
    switch (local_num) {
406
407
408
409
        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
410
411
412
    }
}

413
STATIC void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
414
    emit_pre(emit, 1);
415
    emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_DEREF, local_num);
Damien's avatar
Damien committed
416
417
}

418
STATIC void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
Damien George's avatar
Damien George committed
419
420
    // not needed/supported for BC
    assert(0);
Damien's avatar
Damien committed
421
422
}

423
STATIC void emit_bc_load_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
424
    emit_pre(emit, 1);
425
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_NAME, qstr);
Damien's avatar
Damien committed
426
427
}

428
STATIC void emit_bc_load_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
429
    emit_pre(emit, 1);
430
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_GLOBAL, qstr);
Damien's avatar
Damien committed
431
432
}

433
STATIC void emit_bc_load_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
434
    emit_pre(emit, 0);
435
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_ATTR, qstr);
Damien's avatar
Damien committed
436
437
}

438
STATIC void emit_bc_load_method(emit_t *emit, qstr qstr) {
439
    emit_pre(emit, 1);
440
    emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_METHOD, qstr);
Damien's avatar
Damien committed
441
442
}

443
STATIC void emit_bc_load_build_class(emit_t *emit) {
Damien's avatar
Damien committed
444
    emit_pre(emit, 1);
445
    emit_write_byte_code_byte(emit, MP_BC_LOAD_BUILD_CLASS);
Damien's avatar
Damien committed
446
447
}

448
STATIC void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
449
450
451
    assert(local_num >= 0);
    emit_pre(emit, -1);
    switch (local_num) {
452
453
454
455
        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
456
457
458
    }
}

459
STATIC void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
460
    emit_pre(emit, -1);
461
    emit_write_byte_code_byte_uint(emit, MP_BC_STORE_DEREF, local_num);
Damien's avatar
Damien committed
462
463
}

464
STATIC void emit_bc_store_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
465
    emit_pre(emit, -1);
466
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_NAME, qstr);
Damien's avatar
Damien committed
467
468
}

469
STATIC void emit_bc_store_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
470
    emit_pre(emit, -1);
471
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_GLOBAL, qstr);
Damien's avatar
Damien committed
472
473
}

474
STATIC void emit_bc_store_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
475
    emit_pre(emit, -2);
476
    emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_ATTR, qstr);
Damien's avatar
Damien committed
477
478
}

479
STATIC void emit_bc_store_subscr(emit_t *emit) {
Damien's avatar
Damien committed
480
    emit_pre(emit, -3);
481
    emit_write_byte_code_byte(emit, MP_BC_STORE_SUBSCR);
Damien's avatar
Damien committed
482
483
}

484
STATIC void emit_bc_store_locals(emit_t *emit) {
485
    // not needed
486
    emit_pre(emit, -1);
487
    emit_write_byte_code_byte(emit, MP_BC_POP_TOP);
488
489
}

490
STATIC void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
491
492
    assert(local_num >= 0);
    emit_pre(emit, 0);
493
    emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_FAST_N, local_num);
Damien's avatar
Damien committed
494
495
}

496
STATIC void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
497
    emit_pre(emit, 0);
498
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_DEREF, local_num);
Damien's avatar
Damien committed
499
500
}

501
STATIC void emit_bc_delete_name(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
502
    emit_pre(emit, 0);
503
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_NAME, qstr);
Damien's avatar
Damien committed
504
505
}

506
STATIC void emit_bc_delete_global(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
507
    emit_pre(emit, 0);
508
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_GLOBAL, qstr);
Damien's avatar
Damien committed
509
510
}

511
STATIC void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
Damien's avatar
Damien committed
512
    emit_pre(emit, -1);
513
    emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_ATTR, qstr);
Damien's avatar
Damien committed
514
515
}

516
STATIC void emit_bc_delete_subscr(emit_t *emit) {
Damien's avatar
Damien committed
517
    emit_pre(emit, -2);
518
    emit_write_byte_code_byte(emit, MP_BC_DELETE_SUBSCR);
Damien's avatar
Damien committed
519
520
}

521
STATIC void emit_bc_dup_top(emit_t *emit) {
Damien's avatar
Damien committed
522
    emit_pre(emit, 1);
523
    emit_write_byte_code_byte(emit, MP_BC_DUP_TOP);
Damien's avatar
Damien committed
524
525
}

526
STATIC void emit_bc_dup_top_two(emit_t *emit) {
Damien's avatar
Damien committed
527
    emit_pre(emit, 2);
528
    emit_write_byte_code_byte(emit, MP_BC_DUP_TOP_TWO);
Damien's avatar
Damien committed
529
530
}

531
STATIC void emit_bc_pop_top(emit_t *emit) {
Damien's avatar
Damien committed
532
    emit_pre(emit, -1);
533
    emit_write_byte_code_byte(emit, MP_BC_POP_TOP);
Damien's avatar
Damien committed
534
535
}

536
STATIC void emit_bc_rot_two(emit_t *emit) {
Damien's avatar
Damien committed
537
    emit_pre(emit, 0);
538
    emit_write_byte_code_byte(emit, MP_BC_ROT_TWO);
Damien's avatar
Damien committed
539
540
}

541
STATIC void emit_bc_rot_three(emit_t *emit) {
Damien's avatar
Damien committed
542
    emit_pre(emit, 0);
543
    emit_write_byte_code_byte(emit, MP_BC_ROT_THREE);
Damien's avatar
Damien committed
544
545
}

546
STATIC void emit_bc_jump(emit_t *emit, int label) {
Damien's avatar
Damien committed
547
    emit_pre(emit, 0);
548
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP, label);
Damien's avatar
Damien committed
549
550
}

551
STATIC void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
Damien's avatar
Damien committed
552
    emit_pre(emit, -1);
553
    emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label);
Damien's avatar
Damien committed
554
555
}

556
STATIC void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
Damien's avatar
Damien committed
557
    emit_pre(emit, -1);
558
    emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label);
Damien's avatar
Damien committed
559
560
}

561
STATIC void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
Damien's avatar
Damien committed
562
    emit_pre(emit, -1);
563
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label);
Damien's avatar
Damien committed
564
565
}

566
STATIC void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
Damien's avatar
Damien committed
567
    emit_pre(emit, -1);
568
    emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label);
Damien's avatar
Damien committed
569
570
}

571
STATIC void emit_bc_setup_loop(emit_t *emit, int label) {
Damien's avatar
Damien committed
572
    emit_pre(emit, 0);
573
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_LOOP, label);
Damien's avatar
Damien committed
574
575
}

576
STATIC void emit_bc_unwind_jump(emit_t *emit, int label, int except_depth) {
577
578
579
580
581
582
583
    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
584
585
}

586
STATIC void emit_bc_setup_with(emit_t *emit, int label) {
Damien's avatar
Damien committed
587
    emit_pre(emit, 7);
588
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label);
Damien's avatar
Damien committed
589
590
}

591
STATIC void emit_bc_with_cleanup(emit_t *emit) {
Damien's avatar
Damien committed
592
    emit_pre(emit, -7);
593
    emit_write_byte_code_byte(emit, MP_BC_WITH_CLEANUP);
Damien's avatar
Damien committed
594
595
}

596
STATIC void emit_bc_setup_except(emit_t *emit, int label) {
Damien's avatar
Damien committed
597
    emit_pre(emit, 6);
598
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label);
Damien's avatar
Damien committed
599
600
}

601
STATIC void emit_bc_setup_finally(emit_t *emit, int label) {
Damien's avatar
Damien committed
602
    emit_pre(emit, 6);
603
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label);
Damien's avatar
Damien committed
604
605
}

606
STATIC void emit_bc_end_finally(emit_t *emit) {
Damien's avatar
Damien committed
607
    emit_pre(emit, -1);
608
    emit_write_byte_code_byte(emit, MP_BC_END_FINALLY);
Damien's avatar
Damien committed
609
610
}

611
STATIC void emit_bc_get_iter(emit_t *emit) {
Damien's avatar
Damien committed
612
    emit_pre(emit, 0);
613
    emit_write_byte_code_byte(emit, MP_BC_GET_ITER);
Damien's avatar
Damien committed
614
615
}

616
STATIC void emit_bc_for_iter(emit_t *emit, int label) {
Damien's avatar
Damien committed
617
    emit_pre(emit, 1);
618
    emit_write_byte_code_byte_unsigned_label(emit, MP_BC_FOR_ITER, label);
Damien's avatar
Damien committed
619
620
}

621
STATIC void emit_bc_for_iter_end(emit_t *emit) {
Damien's avatar
Damien committed
622
623
624
    emit_pre(emit, -1);
}

625
STATIC void emit_bc_pop_block(emit_t *emit) {
Damien's avatar
Damien committed
626
    emit_pre(emit, 0);
627
    emit_write_byte_code_byte(emit, MP_BC_POP_BLOCK);
Damien's avatar
Damien committed
628
629
}

630
STATIC void emit_bc_pop_except(emit_t *emit) {
Damien's avatar
Damien committed
631
    emit_pre(emit, 0);
632
    emit_write_byte_code_byte(emit, MP_BC_POP_EXCEPT);
Damien's avatar
Damien committed
633
634
}

635
STATIC void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
636
637
638
639
640
641
642
643
644
    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
645
646
}

647
STATIC void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
648
649
650
651
652
653
654
655
    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
656
    emit_pre(emit, -1);
657
    emit_write_byte_code_byte_byte(emit, MP_BC_BINARY_OP, op);
658
659
660
661
    if (invert) {
        emit_pre(emit, 0);
        emit_write_byte_code_byte(emit, MP_BC_NOT);
    }
Damien's avatar
Damien committed
662
663
}

664
STATIC void emit_bc_build_tuple(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
665
666
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
667
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_TUPLE, n_args);
Damien's avatar
Damien committed
668
669
}

670
STATIC void emit_bc_build_list(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
671
672
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
673
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_LIST, n_args);
Damien's avatar
Damien committed
674
675
}

676
STATIC void emit_bc_list_append(emit_t *emit, int list_stack_index) {
Damien's avatar
Damien committed
677
678
    assert(list_stack_index >= 0);
    emit_pre(emit, -1);
679
    emit_write_byte_code_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index);
Damien's avatar
Damien committed
680
681
}

682
STATIC void emit_bc_build_map(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
683
684
    assert(n_args >= 0);
    emit_pre(emit, 1);
685
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_MAP, n_args);
Damien's avatar
Damien committed
686
687
}

688
STATIC void emit_bc_store_map(emit_t *emit) {
Damien's avatar
Damien committed
689
    emit_pre(emit, -2);
690
    emit_write_byte_code_byte(emit, MP_BC_STORE_MAP);
Damien's avatar
Damien committed
691
692
}

693
STATIC void emit_bc_map_add(emit_t *emit, int map_stack_index) {
Damien's avatar
Damien committed
694
695
    assert(map_stack_index >= 0);
    emit_pre(emit, -2);
696
    emit_write_byte_code_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index);
Damien's avatar
Damien committed
697
698
}

699
STATIC void emit_bc_build_set(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
700
701
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
702
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SET, n_args);
Damien's avatar
Damien committed
703
704
}

705
STATIC void emit_bc_set_add(emit_t *emit, int set_stack_index) {
Damien's avatar
Damien committed
706
707
    assert(set_stack_index >= 0);
    emit_pre(emit, -1);
708
    emit_write_byte_code_byte_uint(emit, MP_BC_SET_ADD, set_stack_index);
Damien's avatar
Damien committed
709
710
}

711
STATIC void emit_bc_build_slice(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
712
713
    assert(n_args >= 0);
    emit_pre(emit, 1 - n_args);
714
    emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SLICE, n_args);
Damien's avatar
Damien committed
715
716
}

717
STATIC void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
Damien's avatar
Damien committed
718
719
    assert(n_args >= 0);
    emit_pre(emit, -1 + n_args);
720
    emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args);
Damien's avatar
Damien committed
721
722
}

723
STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
Damien's avatar
Damien committed
724
725
    assert(n_left >=0 && n_right >= 0);
    emit_pre(emit, -1 + n_left + n_right + 1);
726
    emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8));
Damien's avatar
Damien committed
727
728
}

729
STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
730
    assert(n_dict_params == 0);
731
732
733
734
    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 {
735
736
737
        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
738
739
}

740
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
741
742
743
744
745
746
747
748
    assert(n_dict_params == 0);
    if (n_default_params == 0) {
        emit_pre(emit, 0);
        emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
    } else {
        emit_pre(emit, -1);
        emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
    }
Damien's avatar
Damien committed
749
750
}

751
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
752
753
754
755
756
757
758
759
760
761
762
    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) {
763
            op = MP_BC_CALL_FUNCTION_VAR_KW;
Damien's avatar
Damien committed
764
        } else {
765
            op = MP_BC_CALL_FUNCTION_VAR;
Damien's avatar
Damien committed
766
767
768
        }
    } else {
        if (have_dbl_star_arg) {
769
            op = MP_BC_CALL_FUNCTION_KW;
Damien's avatar
Damien committed
770
        } else {
771
            op = MP_BC_CALL_FUNCTION;
Damien's avatar
Damien committed
772
773
        }
    }
774
    emit_write_byte_code_byte_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
Damien's avatar
Damien committed
775
776
}

777
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
778
779
780
781
782
783
784
    int s = 0;
    if (have_star_arg) {
        s += 1;
    }
    if (have_dbl_star_arg) {
        s += 1;
    }
785
    emit_pre(emit, -1 - n_positional - 2 * n_keyword - s);
Damien's avatar
Damien committed
786
787
788
    int op;
    if (have_star_arg) {
        if (have_dbl_star_arg) {
789
            op = MP_BC_CALL_METHOD_VAR_KW;
Damien's avatar
Damien committed
790
        } else {
791
            op = MP_BC_CALL_METHOD_VAR;
Damien's avatar
Damien committed
792
793
794
        }
    } else {
        if (have_dbl_star_arg) {
795
            op = MP_BC_CALL_METHOD_KW;
Damien's avatar
Damien committed
796
        } else {
797
            op = MP_BC_CALL_METHOD;
Damien's avatar
Damien committed
798
799
        }
    }
800
    emit_write_byte_code_byte_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
Damien's avatar
Damien committed
801
802
}

803
STATIC void emit_bc_return_value(emit_t *emit) {
Damien's avatar
Damien committed
804
805
    emit_pre(emit, -1);
    emit->last_emit_was_return_value = true;
806
    emit_write_byte_code_byte(emit, MP_BC_RETURN_VALUE);
Damien's avatar
Damien committed
807
808
}

809
STATIC void emit_bc_raise_varargs(emit_t *emit, int n_args) {
810
    assert(0 <= n_args && n_args <= 2);
Damien's avatar
Damien committed
811
    emit_pre(emit, -n_args);
812
    emit_write_byte_code_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args);
Damien's avatar
Damien committed
813
814
}

815
STATIC void emit_bc_yield_value(emit_t *emit) {
Damien's avatar
Damien committed
816
817
    emit_pre(emit, 0);
    if (emit->pass == PASS_2) {
818
        emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
Damien's avatar
Damien committed
819
    }
820
    emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE);
Damien's avatar
Damien committed
821
822
}

823
STATIC void emit_bc_yield_from(emit_t *emit) {
Damien's avatar
Damien committed
824
825
    emit_pre(emit, -1);
    if (emit->pass == PASS_2) {
826
        emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
Damien's avatar
Damien committed
827
    }
828
    emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM);
Damien's avatar
Damien committed
829
830
}

831
const emit_method_table_t emit_bc_method_table = {
832
833
834
835
836
837
    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,
838
    emit_bc_set_source_line,
839

840
841
842
843
    emit_bc_load_id,
    emit_bc_store_id,
    emit_bc_delete_id,

844
845
846
847
848
849
850
851
852
853
854
855
856
857
    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
858
859
    emit_bc_load_name,
    emit_bc_load_global,
860
861
862
863
    emit_bc_load_attr,
    emit_bc_load_method,
    emit_bc_load_build_class,
    emit_bc_store_fast,
Damien's avatar
Damien committed
864
    emit_bc_store_deref,
865
866
867
868
    emit_bc_store_name,
    emit_bc_store_global,
    emit_bc_store_attr,
    emit_bc_store_subscr,
869
    emit_bc_store_locals,
870
    emit_bc_delete_fast,
Damien's avatar
Damien committed
871
    emit_bc_delete_deref,
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    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,
887
888
    emit_bc_unwind_jump,
    emit_bc_unwind_jump,
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
    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,
};