showbc.c 12.6 KB
Newer Older
1
2
3
4
#include <stdio.h>
#include <assert.h>

#include "misc.h"
5
#include "mpconfig.h"
6
#include "qstr.h"
7
#include "bc0.h"
8

9
#if MICROPY_DEBUG_PRINTERS
10

11
12
13
14
15
16
#define DECODE_UINT { \
    unum = 0; \
    do { \
        unum = (unum << 7) + (*ip & 0x7f); \
    } while ((*ip++ & 0x80) != 0); \
}
17
18
#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0)
19
20
21
22
23
24
#define DECODE_QSTR { \
    qstr = 0; \
    do { \
        qstr = (qstr << 7) + (*ip & 0x7f); \
    } while ((*ip++ & 0x80) != 0); \
}
25

26
void mp_byte_code_print(const byte *ip, int len) {
27
    const byte *ip_start = ip;
Damien George's avatar
Damien George committed
28

29
30
31
32
    // get code info size
    machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
    ip += code_info_size;

Damien George's avatar
Damien George committed
33
34
35
36
37
38
39
40
41
42
43
44
    // decode prelude
    {
        uint n_local = *ip++;
        printf("(NUM_LOCAL %u)\n", n_local);
        for (; n_local > 0; n_local--) {
            uint local_num = *ip++;
            printf("(INIT_CELL %u)\n", local_num);
        }
        len -= ip - ip_start;
        ip_start = ip;
    }

45
46
47
48
49
50
    machine_uint_t unum;
    qstr qstr;
    while (ip - ip_start < len) {
        printf("%02u ", (uint)(ip - ip_start));
        int op = *ip++;
        switch (op) {
51
            case MP_BC_LOAD_CONST_FALSE:
52
53
54
                printf("LOAD_CONST_FALSE");
                break;

55
            case MP_BC_LOAD_CONST_NONE:
56
57
58
                printf("LOAD_CONST_NONE");
                break;

59
            case MP_BC_LOAD_CONST_TRUE:
60
61
62
                printf("LOAD_CONST_TRUE");
                break;

Damien George's avatar
Damien George committed
63
64
65
66
            case MP_BC_LOAD_CONST_ELLIPSIS:
                printf("LOAD_CONST_ELLIPSIS");
                break;

67
            case MP_BC_LOAD_CONST_SMALL_INT: {
68
                machine_int_t num = 0;
69
70
71
72
73
74
75
                if ((ip[0] & 0x40) != 0) {
                    // Number is negative
                    num--;
                }
                do {
                    num = (num << 7) | (*ip & 0x7f);
                } while ((*ip++ & 0x80) != 0);
76
                printf("LOAD_CONST_SMALL_INT " INT_FMT, num);
77
                break;
78
            }
79

80
81
82
83
84
            case MP_BC_LOAD_CONST_INT:
                DECODE_QSTR;
                printf("LOAD_CONST_INT %s", qstr_str(qstr));
                break;

85
            case MP_BC_LOAD_CONST_DEC:
86
                DECODE_QSTR;
87
                printf("LOAD_CONST_DEC %s", qstr_str(qstr));
88
89
                break;

90
            case MP_BC_LOAD_CONST_ID:
91
                DECODE_QSTR;
Damien's avatar
Damien committed
92
                printf("LOAD_CONST_ID %s", qstr_str(qstr));
93
94
                break;

95
            case MP_BC_LOAD_CONST_STRING:
96
                DECODE_QSTR;
Damien's avatar
Damien committed
97
                printf("LOAD_CONST_STRING %s", qstr_str(qstr));
98
99
                break;

100
            case MP_BC_LOAD_FAST_0:
101
102
103
                printf("LOAD_FAST_0");
                break;

104
            case MP_BC_LOAD_FAST_1:
105
106
107
                printf("LOAD_FAST_1");
                break;

108
            case MP_BC_LOAD_FAST_2:
109
110
111
                printf("LOAD_FAST_2");
                break;

112
            case MP_BC_LOAD_FAST_N:
113
                DECODE_UINT;
114
                printf("LOAD_FAST_N " UINT_FMT, unum);
115
116
                break;

Damien George's avatar
Damien George committed
117
118
119
120
121
            case MP_BC_LOAD_DEREF:
                DECODE_UINT;
                printf("LOAD_DEREF " UINT_FMT, unum);
                break;

122
            case MP_BC_LOAD_NAME:
123
124
125
126
                DECODE_QSTR;
                printf("LOAD_NAME %s", qstr_str(qstr));
                break;

127
            case MP_BC_LOAD_GLOBAL:
128
129
130
131
                DECODE_QSTR;
                printf("LOAD_GLOBAL %s", qstr_str(qstr));
                break;

132
            case MP_BC_LOAD_ATTR:
133
                DECODE_QSTR;
Damien's avatar
Damien committed
134
                printf("LOAD_ATTR %s", qstr_str(qstr));
135
136
                break;

137
            case MP_BC_LOAD_METHOD:
138
139
140
141
                DECODE_QSTR;
                printf("LOAD_METHOD %s", qstr_str(qstr));
                break;

142
            case MP_BC_LOAD_BUILD_CLASS:
Damien's avatar
Damien committed
143
                printf("LOAD_BUILD_CLASS");
144
145
                break;

146
            case MP_BC_STORE_FAST_0:
147
148
149
                printf("STORE_FAST_0");
                break;

150
            case MP_BC_STORE_FAST_1:
151
152
153
                printf("STORE_FAST_1");
                break;

154
            case MP_BC_STORE_FAST_2:
155
156
157
                printf("STORE_FAST_2");
                break;

158
            case MP_BC_STORE_FAST_N:
159
                DECODE_UINT;
160
                printf("STORE_FAST_N " UINT_FMT, unum);
161
162
                break;

Damien George's avatar
Damien George committed
163
164
165
166
167
            case MP_BC_STORE_DEREF:
                DECODE_UINT;
                printf("STORE_DEREF " UINT_FMT, unum);
                break;

168
            case MP_BC_STORE_NAME:
169
170
171
172
                DECODE_QSTR;
                printf("STORE_NAME %s", qstr_str(qstr));
                break;

173
            case MP_BC_STORE_GLOBAL:
174
                DECODE_QSTR;
175
                printf("STORE_GLOBAL %s", qstr_str(qstr));
176
177
                break;

178
            case MP_BC_STORE_ATTR:
179
                DECODE_QSTR;
Damien's avatar
Damien committed
180
                printf("STORE_ATTR %s", qstr_str(qstr));
181
182
                break;

183
            case MP_BC_STORE_SUBSCR:
Damien's avatar
Damien committed
184
                printf("STORE_SUBSCR");
185
186
                break;

Damien George's avatar
Damien George committed
187
188
189
190
191
192
193
194
195
196
            case MP_BC_DELETE_FAST_N:
                DECODE_UINT;
                printf("DELETE_FAST_N " UINT_FMT, unum);
                break;

            case MP_BC_DELETE_NAME:
                DECODE_QSTR;
                printf("DELETE_NAME %s", qstr_str(qstr));
                break;

197
            case MP_BC_DUP_TOP:
198
                printf("DUP_TOP");
199
200
                break;

201
            case MP_BC_DUP_TOP_TWO:
Damien's avatar
Damien committed
202
                printf("DUP_TOP_TWO");
203
204
                break;

205
            case MP_BC_POP_TOP:
206
207
208
                printf("POP_TOP");
                break;

209
            case MP_BC_ROT_TWO:
210
                printf("ROT_TWO");
211
212
                break;

213
            case MP_BC_ROT_THREE:
Damien's avatar
Damien committed
214
                printf("ROT_THREE");
215
216
                break;

217
            case MP_BC_JUMP:
218
                DECODE_SLABEL;
219
                printf("JUMP " UINT_FMT, ip + unum - ip_start);
220
221
                break;

222
            case MP_BC_POP_JUMP_IF_TRUE:
223
                DECODE_SLABEL;
224
                printf("POP_JUMP_IF_TRUE " UINT_FMT, ip + unum - ip_start);
225
226
                break;

227
            case MP_BC_POP_JUMP_IF_FALSE:
228
                DECODE_SLABEL;
229
                printf("POP_JUMP_IF_FALSE " UINT_FMT, ip + unum - ip_start);
230
231
                break;

232
            case MP_BC_JUMP_IF_TRUE_OR_POP:
233
                DECODE_SLABEL;
234
                printf("JUMP_IF_TRUE_OR_POP " UINT_FMT, ip + unum - ip_start);
235
236
                break;

237
            case MP_BC_JUMP_IF_FALSE_OR_POP:
238
                DECODE_SLABEL;
239
                printf("JUMP_IF_FALSE_OR_POP " UINT_FMT, ip + unum - ip_start);
240
241
                break;

242
243
244
245
246
            case MP_BC_SETUP_LOOP:
                DECODE_ULABEL; // loop labels are always forward
                printf("SETUP_LOOP " UINT_FMT, ip + unum - ip_start);
                break;

247
248
249
250
251
252
253
254
255
            case MP_BC_SETUP_WITH:
                DECODE_ULABEL; // loop-like labels are always forward
                printf("SETUP_WITH " UINT_FMT, ip + unum - ip_start);
                break;

            case MP_BC_WITH_CLEANUP:
                printf("WITH_CLEANUP");
                break;

256
257
258
259
            case MP_BC_UNWIND_JUMP:
                DECODE_SLABEL;
                printf("UNWIND_JUMP " UINT_FMT " %d", ip + unum - ip_start, *ip);
                ip += 1;
260
261
                break;

262
            case MP_BC_SETUP_EXCEPT:
263
                DECODE_ULABEL; // except labels are always forward
264
                printf("SETUP_EXCEPT " UINT_FMT, ip + unum - ip_start);
265
266
                break;

267
268
269
270
271
            case MP_BC_SETUP_FINALLY:
                DECODE_ULABEL; // except labels are always forward
                printf("SETUP_FINALLY " UINT_FMT, ip + unum - ip_start);
                break;

272
            case MP_BC_END_FINALLY:
273
274
275
276
                // if TOS is an exception, reraises the exception (3 values on TOS)
                // if TOS is an integer, does something else
                // if TOS is None, just pops it and continues
                // else error
277
                printf("END_FINALLY");
278
279
                break;

280
            case MP_BC_GET_ITER:
Damien's avatar
Damien committed
281
                printf("GET_ITER");
282
283
                break;

284
            case MP_BC_FOR_ITER:
285
                DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
286
                printf("FOR_ITER " UINT_FMT, ip + unum - ip_start);
287
288
                break;

289
            case MP_BC_POP_BLOCK:
290
                // pops block and restores the stack
291
                printf("POP_BLOCK");
292
293
                break;

294
            case MP_BC_POP_EXCEPT:
295
                // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
296
                printf("POP_EXCEPT");
297
298
                break;

299
300
301
302
            case MP_BC_NOT:
                printf("NOT");
                break;

303
            case MP_BC_UNARY_OP:
304
                unum = *ip++;
305
                printf("UNARY_OP " UINT_FMT, unum);
306
307
                break;

308
            case MP_BC_BINARY_OP:
309
                unum = *ip++;
310
                printf("BINARY_OP " UINT_FMT, unum);
311
312
                break;

313
            case MP_BC_BUILD_TUPLE:
314
                DECODE_UINT;
315
                printf("BUILD_TUPLE " UINT_FMT, unum);
316
317
                break;

318
            case MP_BC_BUILD_LIST:
319
                DECODE_UINT;
320
                printf("BUILD_LIST " UINT_FMT, unum);
321
322
                break;

323
            case MP_BC_LIST_APPEND:
324
                DECODE_UINT;
325
                printf("LIST_APPEND " UINT_FMT, unum);
326
327
                break;

328
            case MP_BC_BUILD_MAP:
329
                DECODE_UINT;
330
                printf("BUILD_MAP " UINT_FMT, unum);
331
332
                break;

333
            case MP_BC_STORE_MAP:
334
                printf("STORE_MAP");
335
336
                break;

337
                /*
338
            case MP_BC_MAP_ADD:
339
340
341
342
343
                DECODE_UINT;
                // I think it's guaranteed by the compiler that sp[unum + 1] is a map
                rt_store_map(sp[unum + 1], sp[0], sp[1]);
                sp += 2;
                break;
344
                */
345

346
            case MP_BC_BUILD_SET:
347
                DECODE_UINT;
348
                printf("BUILD_SET " UINT_FMT, unum);
349
350
                break;

351
            case MP_BC_SET_ADD:
352
                DECODE_UINT;
353
                printf("SET_ADD " UINT_FMT, unum);
354
355
                break;

356
357
358
359
360
361
362
#if MICROPY_ENABLE_SLICE
            case MP_BC_BUILD_SLICE:
                DECODE_UINT;
                printf("BUILD_SLICE " UINT_FMT, unum);
                break;
#endif

363
            case MP_BC_UNPACK_SEQUENCE:
Damien's avatar
Damien committed
364
                DECODE_UINT;
365
                printf("UNPACK_SEQUENCE " UINT_FMT, unum);
Damien's avatar
Damien committed
366
367
                break;

368
            case MP_BC_MAKE_FUNCTION:
369
                DECODE_UINT;
370
                printf("MAKE_FUNCTION " UINT_FMT, unum);
371
372
                break;

373
374
375
376
377
            case MP_BC_MAKE_FUNCTION_DEFARGS:
                DECODE_UINT;
                printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum);
                break;

Damien George's avatar
Damien George committed
378
379
380
381
382
            case MP_BC_MAKE_CLOSURE:
                DECODE_UINT;
                printf("MAKE_CLOSURE " UINT_FMT, unum);
                break;

383
384
385
386
387
            case MP_BC_MAKE_CLOSURE_DEFARGS:
                DECODE_UINT;
                printf("MAKE_CLOSURE_DEFARGS " UINT_FMT, unum);
                break;

388
            case MP_BC_CALL_FUNCTION:
389
                DECODE_UINT;
390
                printf("CALL_FUNCTION n=" UINT_FMT " nkw=" UINT_FMT, unum & 0xff, (unum >> 8) & 0xff);
391
392
                break;

393
            case MP_BC_CALL_METHOD:
394
                DECODE_UINT;
395
                printf("CALL_METHOD n=" UINT_FMT " nkw=" UINT_FMT, unum & 0xff, (unum >> 8) & 0xff);
396
397
                break;

398
            case MP_BC_RETURN_VALUE:
399
400
401
                printf("RETURN_VALUE");
                break;

402
403
404
405
406
            case MP_BC_RAISE_VARARGS:
                unum = *ip++;
                printf("RAISE_VARARGS " UINT_FMT, unum);
                break;

407
            case MP_BC_YIELD_VALUE:
408
409
                printf("YIELD_VALUE");
                break;
410

Paul Sokolovsky's avatar
Paul Sokolovsky committed
411
412
413
414
            case MP_BC_YIELD_FROM:
                printf("YIELD_FROM");
                break;

415
416
            case MP_BC_IMPORT_NAME:
                DECODE_QSTR;
417
                printf("IMPORT_NAME %s", qstr_str(qstr));
418
419
420
421
                break;

            case MP_BC_IMPORT_FROM:
                DECODE_QSTR;
422
                printf("IMPORT_FROM %s", qstr_str(qstr));
423
424
                break;

425
426
427
428
            case MP_BC_IMPORT_STAR:
                printf("IMPORT_STAR");
                break;

429
430
431
432
433
434
435
436
            default:
                printf("code %p, byte code 0x%02x not implemented\n", ip, op);
                assert(0);
                return;
        }
        printf("\n");
    }
}
437

438
#endif // MICROPY_DEBUG_PRINTERS