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
52
53
54
55
56
57
58
59
60
61
62
// all functions must go through this one to emit code info
static byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_write) {
    //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
66
67
68
69
70
71
static void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
    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
75
76
77
78
79
80
81
static void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, uint lines_to_skip) {
    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
85
}

// all functions must go through this one to emit byte code
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
99
static void emit_write_byte_code_byte(emit_t* emit, byte b1) {
    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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
static void emit_write_byte_code_uint(emit_t* emit, uint num) {
    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
138
139
static void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
    emit_write_byte_code_byte(emit, b);
    emit_write_byte_code_uint(emit, num);
Damien's avatar
Damien committed
140
141
}

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

static void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
    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
156
static void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, int label) {
    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
170
static void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, int label) {
    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
}

Damien George's avatar
Damien George committed
182
183
184
185
186
187
188
189
static void emit_bc_set_native_types(emit_t *emit, bool do_native_types) {
}

static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
    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
231
232
233
234
235
        }
    }
}

static void emit_bc_end_pass(emit_t *emit) {
    // 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
276
277
278
279
280
281
282
283
284
285
286
static void emit_bc_load_id(emit_t *emit, qstr qstr) {
    emit_common_load_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

static void emit_bc_store_id(emit_t *emit, qstr qstr) {
    emit_common_store_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

static void emit_bc_delete_id(emit_t *emit, qstr qstr) {
    emit_common_delete_id(emit, &emit_bc_method_table, emit->scope, qstr);
}

287
static void emit_pre(emit_t *emit, int stack_size_delta) {
288
289
290
    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
291
292
293
294
    }
    emit->last_emit_was_return_value = false;
}

295
static void emit_bc_label_assign(emit_t *emit, int l) {
Damien's avatar
Damien committed
296
    emit_pre(emit, 0);
297
298
299
300
    assert(l < emit->max_num_labels);
    if (emit->pass == PASS_2) {
        // assign label offset
        assert(emit->label_offsets[l] == -1);
301
        emit->label_offsets[l] = emit->byte_code_offset;
302
303
    } else if (emit->pass == PASS_3) {
        // ensure label offset has not changed from PASS_2 to PASS_3
304
305
        //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
306
307
308
    }
}

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

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

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

324
static void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
Damien's avatar
Damien committed
325
326
    emit_pre(emit, 1);
    switch (tok) {
327
328
329
330
        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
331
332
333
334
        default: assert(0);
    }
}

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

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

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

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

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

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

369
static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
370
371
372
    assert(local_num >= 0);
    emit_pre(emit, 1);
    switch (local_num) {
373
374
375
376
        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
377
378
379
    }
}

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

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

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

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

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

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

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

415
static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
Damien's avatar
Damien committed
416
417
418
    assert(local_num >= 0);
    emit_pre(emit, -1);
    switch (local_num) {
419
420
421
422
        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
423
424
425
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

543
544
545
546
547
548
549
550
static void emit_bc_unwind_jump(emit_t *emit, int label, int except_depth) {
    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
551
552
}

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

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

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

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

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

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

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

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

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

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

602
static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
603
604
605
606
607
608
609
610
611
    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
612
613
}

614
static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
615
616
617
618
619
620
621
622
    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
623
    emit_pre(emit, -1);
624
    emit_write_byte_code_byte_byte(emit, MP_BC_BINARY_OP, op);
625
626
627
628
    if (invert) {
        emit_pre(emit, 0);
        emit_write_byte_code_byte(emit, MP_BC_NOT);
    }
Damien's avatar
Damien committed
629
630
}

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

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

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

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

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

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

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

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

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

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

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

696
static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
697
    assert(n_dict_params == 0);
698
699
700
701
    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 {
702
703
704
705
        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
706
707
}

708
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
709
710
    assert(n_default_params == 0 && n_dict_params == 0);
    emit_pre(emit, 0);
711
    emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
Damien's avatar
Damien committed
712
713
}

714
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
715
716
717
718
719
720
721
722
723
724
725
    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) {
726
            op = MP_BC_CALL_FUNCTION_VAR_KW;
Damien's avatar
Damien committed
727
        } else {
728
            op = MP_BC_CALL_FUNCTION_VAR;
Damien's avatar
Damien committed
729
730
731
        }
    } else {
        if (have_dbl_star_arg) {
732
            op = MP_BC_CALL_FUNCTION_KW;
Damien's avatar
Damien committed
733
        } else {
734
            op = MP_BC_CALL_FUNCTION;
Damien's avatar
Damien committed
735
736
        }
    }
737
    emit_write_byte_code_byte_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
Damien's avatar
Damien committed
738
739
}

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

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

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

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

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

794
const emit_method_table_t emit_bc_method_table = {
795
796
797
798
799
800
    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,
801
    emit_bc_set_source_line,
802

803
804
805
806
    emit_bc_load_id,
    emit_bc_store_id,
    emit_bc_delete_id,

807
808
809
810
811
812
813
814
815
816
817
818
819
820
    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
821
822
    emit_bc_load_name,
    emit_bc_load_global,
823
824
825
826
    emit_bc_load_attr,
    emit_bc_load_method,
    emit_bc_load_build_class,
    emit_bc_store_fast,
Damien's avatar
Damien committed
827
    emit_bc_store_deref,
828
829
830
831
    emit_bc_store_name,
    emit_bc_store_global,
    emit_bc_store_attr,
    emit_bc_store_subscr,
832
    emit_bc_store_locals,
833
    emit_bc_delete_fast,
Damien's avatar
Damien committed
834
    emit_bc_delete_deref,
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    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,
850
851
    emit_bc_unwind_jump,
    emit_bc_unwind_jump,
852
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
    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,
};