py/parse: Add MICROPY_COMP_CONST_TUPLE option to build const tuples.

This commit adds support to the parser so that tuples which contain only
constant elements (bool, int, str, bytes, etc) are immediately converted to
a tuple object.  This makes it more efficient to use tuples containing
constant data because they no longer need to be created at runtime by the
bytecode (or native code).

Furthermore, with this improvement constant tuples that are part of frozen
code are now able to be stored fully in ROM (this will be implemented in
later commits).

Code size is increased by about 400 bytes on Cortex-M4 platforms.

See related issue #722.

Signed-off-by: Damien George <damien@micropython.org>
pull/8504/head
Damien George 2022-03-31 14:27:47 +11:00
rodzic 24bc1f61f9
commit 35c0cff92b
3 zmienionych plików z 474 dodań i 323 usunięć

Wyświetl plik

@ -441,6 +441,12 @@
#define MICROPY_COMP_CONST_FOLDING (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES)
#endif
// Whether to compile constant tuples immediately to their respective objects; eg (1, True)
// Otherwise the tuple will be built at runtime
#ifndef MICROPY_COMP_CONST_TUPLE
#define MICROPY_COMP_CONST_TUPLE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES)
#endif
// Whether to enable optimisations for constant literals, eg OrderedDict
#ifndef MICROPY_COMP_CONST_LITERAL
#define MICROPY_COMP_CONST_LITERAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES)

Wyświetl plik

@ -291,6 +291,16 @@ STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) {
return ret;
}
#if MICROPY_COMP_CONST_TUPLE
STATIC void parser_free_parse_node_struct(parser_t *parser, mp_parse_node_struct_t *pns) {
mp_parse_chunk_t *chunk = parser->cur_chunk;
if (chunk->data <= (byte *)pns && (byte *)pns < chunk->data + chunk->union_.used) {
size_t num_bytes = sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
chunk->union_.used -= num_bytes;
}
}
#endif
STATIC void push_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t arg_i) {
if (parser->rule_stack_top >= parser->rule_stack_alloc) {
rule_stack_t *rs = m_renew(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc + MICROPY_ALLOC_PARSE_RULE_INC);
@ -317,6 +327,13 @@ STATIC uint8_t pop_rule(parser_t *parser, size_t *arg_i, size_t *src_line) {
return rule_id;
}
#if MICROPY_COMP_CONST_TUPLE
STATIC uint8_t peek_rule(parser_t *parser, size_t n) {
assert(parser->rule_stack_top > n);
return parser->rule_stack[parser->rule_stack_top - 1 - n].rule_id;
}
#endif
bool mp_parse_node_is_const_false(mp_parse_node_t pn) {
return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_FALSE)
|| (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) == 0);
@ -340,6 +357,76 @@ bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) {
}
}
#if MICROPY_COMP_CONST_TUPLE
STATIC bool mp_parse_node_is_const(mp_parse_node_t pn) {
if (MP_PARSE_NODE_IS_SMALL_INT(pn)) {
// Small integer.
return true;
} else if (MP_PARSE_NODE_IS_LEAF(pn)) {
// Possible str, or constant literal.
uintptr_t kind = MP_PARSE_NODE_LEAF_KIND(pn);
if (kind == MP_PARSE_NODE_STRING) {
return true;
} else if (kind == MP_PARSE_NODE_TOKEN) {
uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn);
return arg == MP_TOKEN_KW_NONE
|| arg == MP_TOKEN_KW_FALSE
|| arg == MP_TOKEN_KW_TRUE
|| arg == MP_TOKEN_ELLIPSIS;
}
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) {
// Constant object.
return true;
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_atom_paren)) {
// Possible empty tuple.
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn;
return MP_PARSE_NODE_IS_NULL(pns->nodes[0]);
}
return false;
}
STATIC mp_obj_t mp_parse_node_convert_to_obj(mp_parse_node_t pn) {
assert(mp_parse_node_is_const(pn));
if (MP_PARSE_NODE_IS_SMALL_INT(pn)) {
mp_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pn);
#if MICROPY_DYNAMIC_COMPILER
mp_uint_t sign_mask = -((mp_uint_t)1 << (mp_dynamic_compiler.small_int_bits - 1));
if (!((arg & sign_mask) == 0 || (arg & sign_mask) == sign_mask)) {
// Integer doesn't fit in a small-int, so create a multi-precision int object.
return mp_obj_new_int_from_ll(arg);
}
#endif
return MP_OBJ_NEW_SMALL_INT(arg);
} else if (MP_PARSE_NODE_IS_LEAF(pn)) {
uintptr_t kind = MP_PARSE_NODE_LEAF_KIND(pn);
uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn);
if (kind == MP_PARSE_NODE_STRING) {
return MP_OBJ_NEW_QSTR(arg);
} else {
assert(MP_PARSE_NODE_LEAF_KIND(pn) == MP_PARSE_NODE_TOKEN);
switch (arg) {
case MP_TOKEN_KW_NONE:
return mp_const_none;
case MP_TOKEN_KW_FALSE:
return mp_const_false;
case MP_TOKEN_KW_TRUE:
return mp_const_true;
default:
assert(arg == MP_TOKEN_ELLIPSIS);
return MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj);
}
}
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn;
return mp_parse_node_extract_const_object(pns);
} else {
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_atom_paren));
assert(MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t *)pn)->nodes[0]));
return mp_const_empty_tuple;
}
}
#endif
size_t mp_parse_node_extract_list(mp_parse_node_t *pn, size_t pn_kind, mp_parse_node_t **nodes) {
if (MP_PARSE_NODE_IS_NULL(*pn)) {
*nodes = NULL;
@ -791,6 +878,59 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
}
#endif
#if MICROPY_COMP_CONST_TUPLE
STATIC bool build_tuple_from_stack(parser_t *parser, size_t src_line, size_t num_args) {
for (size_t i = num_args; i > 0;) {
mp_parse_node_t pn = peek_result(parser, --i);
if (!mp_parse_node_is_const(pn)) {
return false;
}
}
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_args, NULL));
for (size_t i = num_args; i > 0;) {
mp_parse_node_t pn = pop_result(parser);
tuple->items[--i] = mp_parse_node_convert_to_obj(pn);
if (MP_PARSE_NODE_IS_STRUCT(pn)) {
parser_free_parse_node_struct(parser, (mp_parse_node_struct_t *)pn);
}
}
push_result_node(parser, make_node_const_object(parser, src_line, MP_OBJ_FROM_PTR(tuple)));
return true;
}
STATIC bool build_tuple(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args) {
if (rule_id == RULE_testlist_comp) {
if (peek_rule(parser, 0) == RULE_atom_paren) {
// Tuple of the form "(a,)".
return build_tuple_from_stack(parser, src_line, num_args);
}
}
if (rule_id == RULE_testlist_comp_3c) {
assert(peek_rule(parser, 0) == RULE_testlist_comp_3b);
assert(peek_rule(parser, 1) == RULE_testlist_comp);
if (peek_rule(parser, 2) == RULE_atom_paren) {
// Tuple of the form "(a, b)".
if (build_tuple_from_stack(parser, src_line, num_args)) {
parser->rule_stack_top -= 2; // discard 2 rules
return true;
}
}
}
if (rule_id == RULE_testlist_star_expr
|| rule_id == RULE_testlist
|| rule_id == RULE_subscriptlist) {
// Tuple of the form:
// - x = a, b
// - return a, b
// - for x in a, b: pass
// - x[a, b]
return build_tuple_from_stack(parser, src_line, num_args);
}
return false;
}
#endif
STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args) {
// Simplify and optimise certain rules, to reduce memory usage and simplify the compiler.
if (rule_id == RULE_atom_paren) {
@ -847,6 +987,13 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id,
}
#endif
#if MICROPY_COMP_CONST_TUPLE
if (build_tuple(parser, src_line, rule_id, num_args)) {
// we built a tuple from this rule so return straightaway
return;
}
#endif
mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * num_args);
pn->source_line = src_line;
pn->kind_num_nodes = (rule_id & 0xff) | (num_args << 8);

Wyświetl plik

@ -47,9 +47,9 @@ arg names:
42 IMPORT_STAR
43 LOAD_CONST_NONE
44 RETURN_VALUE
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 45\[68\] bytes)
Raw bytecode (code_info_size=8\[46\], bytecode_size=372):
a8 12 9\[bf\] 03 02 60 60 26 22 24 64 22 26 25 25 24
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 45\[46\] bytes)
Raw bytecode (code_info_size=8\[46\], bytecode_size=370):
a8 12 9\[bf\] 03 02 60 60 26 22 24 64 22 24 25 25 24
26 23 63 22 22 25 23 23 2f 6c 25 65 25 25 69 68
26 65 27 6a 62 20 23 62 2a 29 69 24 25 28 67 26
########
@ -68,77 +68,77 @@ arg names:
bc=12 line=10
bc=16 line=13
bc=18 line=14
bc=24 line=15
bc=29 line=16
bc=34 line=17
bc=38 line=18
bc=44 line=19
bc=47 line=20
bc=50 line=23
bc=52 line=24
bc=54 line=25
bc=59 line=26
bc=62 line=27
bc=65 line=28
bc=80 line=29
bc=92 line=32
bc=97 line=33
bc=102 line=36
bc=107 line=37
bc=112 line=38
bc=121 line=41
bc=129 line=44
bc=135 line=45
bc=140 line=48
bc=147 line=49
bc=157 line=52
bc=159 line=55
bc=159 line=56
bc=162 line=57
bc=164 line=60
bc=174 line=61
bc=183 line=62
bc=192 line=65
bc=196 line=66
bc=201 line=67
bc=209 line=68
bc=216 line=71
bc=222 line=72
bc=229 line=73
bc=239 line=74
bc=247 line=77
bc=250 line=78
bc=255 line=80
bc=258 line=81
bc=260 line=82
bc=266 line=83
bc=268 line=84
bc=274 line=85
bc=279 line=88
bc=285 line=89
bc=289 line=92
bc=293 line=93
bc=295 line=94
bc=22 line=15
bc=27 line=16
bc=32 line=17
bc=36 line=18
bc=42 line=19
bc=45 line=20
bc=48 line=23
bc=50 line=24
bc=52 line=25
bc=57 line=26
bc=60 line=27
bc=63 line=28
bc=78 line=29
bc=90 line=32
bc=95 line=33
bc=100 line=36
bc=105 line=37
bc=110 line=38
bc=119 line=41
bc=127 line=44
bc=133 line=45
bc=138 line=48
bc=145 line=49
bc=155 line=52
bc=157 line=55
bc=157 line=56
bc=160 line=57
bc=162 line=60
bc=172 line=61
bc=181 line=62
bc=190 line=65
bc=194 line=66
bc=199 line=67
bc=207 line=68
bc=214 line=71
bc=220 line=72
bc=227 line=73
bc=237 line=74
bc=245 line=77
bc=248 line=78
bc=253 line=80
bc=256 line=81
bc=258 line=82
bc=264 line=83
bc=266 line=84
bc=272 line=85
bc=277 line=88
bc=283 line=89
bc=287 line=92
bc=291 line=93
bc=293 line=94
########
bc=303 line=96
bc=310 line=98
bc=313 line=99
bc=315 line=100
bc=317 line=101
bc=301 line=96
bc=308 line=98
bc=311 line=99
bc=313 line=100
bc=315 line=101
########
bc=323 line=103
bc=329 line=106
bc=333 line=107
bc=339 line=110
bc=342 line=111
bc=348 line=114
bc=348 line=117
bc=353 line=118
bc=365 line=121
bc=365 line=122
bc=366 line=123
bc=368 line=126
bc=370 line=127
bc=321 line=103
bc=327 line=106
bc=331 line=107
bc=337 line=110
bc=340 line=111
bc=346 line=114
bc=346 line=117
bc=351 line=118
bc=363 line=121
bc=363 line=122
bc=364 line=123
bc=366 line=126
bc=368 line=127
00 LOAD_CONST_NONE
01 LOAD_CONST_FALSE
02 BINARY_OP 27 __add__
@ -153,258 +153,256 @@ arg names:
15 STORE_FAST 0
16 LOAD_CONST_SMALL_INT 1
17 STORE_FAST 0
18 LOAD_CONST_SMALL_INT 1
19 LOAD_CONST_SMALL_INT 2
20 BUILD_TUPLE 2
22 STORE_DEREF 14
24 LOAD_CONST_SMALL_INT 1
25 LOAD_CONST_SMALL_INT 2
26 BUILD_LIST 2
28 STORE_FAST 1
29 LOAD_CONST_SMALL_INT 1
30 LOAD_CONST_SMALL_INT 2
31 BUILD_SET 2
33 STORE_FAST 2
34 BUILD_MAP 0
36 STORE_DEREF 15
38 BUILD_MAP 1
40 LOAD_CONST_SMALL_INT 2
41 LOAD_CONST_SMALL_INT 1
42 STORE_MAP
43 STORE_FAST 3
44 LOAD_CONST_STRING 'a'
46 STORE_FAST 4
47 LOAD_CONST_OBJ \.\+=b'a'
49 STORE_FAST 5
50 LOAD_CONST_SMALL_INT 1
51 STORE_FAST 6
52 LOAD_CONST_SMALL_INT 2
53 STORE_FAST 7
54 LOAD_FAST 0
55 LOAD_DEREF 14
57 BINARY_OP 27 __add__
58 STORE_FAST 8
59 LOAD_FAST 0
60 UNARY_OP 1 __neg__
61 STORE_FAST 9
62 LOAD_FAST 0
63 UNARY_OP 3
64 STORE_FAST 10
65 LOAD_FAST 0
66 LOAD_DEREF 14
68 DUP_TOP
69 ROT_THREE
70 BINARY_OP 2 __eq__
71 JUMP_IF_FALSE_OR_POP 77
73 LOAD_FAST 1
74 BINARY_OP 2 __eq__
75 JUMP 79
77 ROT_TWO
78 POP_TOP
79 STORE_FAST 10
80 LOAD_FAST 0
81 LOAD_DEREF 14
83 BINARY_OP 2 __eq__
84 JUMP_IF_FALSE_OR_POP 90
86 LOAD_DEREF 14
88 LOAD_FAST 1
89 BINARY_OP 2 __eq__
90 UNARY_OP 3
91 STORE_FAST 10
92 LOAD_DEREF 14
94 LOAD_ATTR c
96 STORE_FAST 11
97 LOAD_FAST 11
98 LOAD_DEREF 14
100 STORE_ATTR c
102 LOAD_DEREF 14
104 LOAD_CONST_SMALL_INT 0
105 LOAD_SUBSCR
106 STORE_FAST 12
107 LOAD_FAST 12
108 LOAD_DEREF 14
110 LOAD_CONST_SMALL_INT 0
111 STORE_SUBSCR
112 LOAD_DEREF 14
114 LOAD_CONST_SMALL_INT 0
115 DUP_TOP_TWO
116 LOAD_SUBSCR
117 LOAD_FAST 12
118 BINARY_OP 14 __iadd__
119 ROT_THREE
120 STORE_SUBSCR
121 LOAD_DEREF 14
123 LOAD_CONST_NONE
124 LOAD_CONST_NONE
125 BUILD_SLICE 2
127 LOAD_SUBSCR
128 STORE_FAST 0
129 LOAD_FAST 1
130 UNPACK_SEQUENCE 2
132 STORE_FAST 0
133 STORE_DEREF 14
135 LOAD_FAST 0
136 UNPACK_EX 1
138 STORE_FAST 0
139 STORE_FAST 0
140 LOAD_DEREF 14
142 LOAD_FAST 0
143 ROT_TWO
144 STORE_FAST 0
145 STORE_DEREF 14
147 LOAD_FAST 1
148 LOAD_DEREF 14
150 LOAD_FAST 0
151 ROT_THREE
152 ROT_TWO
153 STORE_FAST 0
154 STORE_DEREF 14
156 STORE_FAST 1
157 DELETE_FAST 0
159 LOAD_FAST 0
160 STORE_GLOBAL gl
162 DELETE_GLOBAL gl
164 LOAD_FAST 14
165 LOAD_FAST 15
166 MAKE_CLOSURE \.\+ 2
169 LOAD_FAST 2
170 GET_ITER
171 CALL_FUNCTION n=1 nkw=0
173 STORE_FAST 0
174 LOAD_FAST 14
175 LOAD_FAST 15
176 MAKE_CLOSURE \.\+ 2
179 LOAD_FAST 2
180 CALL_FUNCTION n=1 nkw=0
182 STORE_FAST 0
183 LOAD_FAST 14
184 LOAD_FAST 15
185 MAKE_CLOSURE \.\+ 2
188 LOAD_FAST 2
189 CALL_FUNCTION n=1 nkw=0
191 STORE_FAST 0
192 LOAD_FAST 0
193 CALL_FUNCTION n=0 nkw=0
195 POP_TOP
196 LOAD_FAST 0
197 LOAD_CONST_SMALL_INT 1
198 CALL_FUNCTION n=1 nkw=0
200 POP_TOP
201 LOAD_FAST 0
202 LOAD_CONST_STRING 'b'
204 LOAD_CONST_SMALL_INT 1
205 CALL_FUNCTION n=0 nkw=1
208 POP_TOP
209 LOAD_FAST 0
210 LOAD_DEREF 14
212 LOAD_CONST_SMALL_INT 1
213 CALL_FUNCTION_VAR_KW n=1 nkw=0
215 POP_TOP
216 LOAD_FAST 0
217 LOAD_METHOD b
219 CALL_METHOD n=0 nkw=0
221 POP_TOP
222 LOAD_FAST 0
223 LOAD_METHOD b
225 LOAD_CONST_SMALL_INT 1
226 CALL_METHOD n=1 nkw=0
228 POP_TOP
229 LOAD_FAST 0
230 LOAD_METHOD b
232 LOAD_CONST_STRING 'c'
234 LOAD_CONST_SMALL_INT 1
235 CALL_METHOD n=0 nkw=1
238 POP_TOP
239 LOAD_FAST 0
240 LOAD_METHOD b
242 LOAD_FAST 1
243 LOAD_CONST_SMALL_INT 1
244 CALL_METHOD_VAR_KW n=1 nkw=0
246 POP_TOP
247 LOAD_FAST 0
248 POP_JUMP_IF_FALSE 255
250 LOAD_DEREF 16
252 POP_TOP
253 JUMP 258
255 LOAD_GLOBAL y
257 POP_TOP
258 JUMP 263
260 LOAD_DEREF 14
262 POP_TOP
263 LOAD_FAST 0
264 POP_JUMP_IF_TRUE 260
266 JUMP 271
268 LOAD_DEREF 14
270 POP_TOP
271 LOAD_FAST 0
272 POP_JUMP_IF_FALSE 268
274 LOAD_FAST 0
275 JUMP_IF_TRUE_OR_POP 278
277 LOAD_FAST 0
278 STORE_FAST 0
279 LOAD_DEREF 14
281 GET_ITER_STACK
282 FOR_ITER 289
284 STORE_FAST 0
285 LOAD_FAST 1
286 POP_TOP
287 JUMP 282
289 SETUP_FINALLY 310
291 SETUP_EXCEPT 302
293 JUMP 297
295 JUMP 300
297 LOAD_FAST 0
298 POP_JUMP_IF_TRUE 295
300 POP_EXCEPT_JUMP 309
302 POP_TOP
303 LOAD_DEREF 14
305 POP_TOP
306 POP_EXCEPT_JUMP 309
308 END_FINALLY
309 LOAD_CONST_NONE
310 LOAD_FAST 1
311 POP_TOP
312 END_FINALLY
313 JUMP 326
315 SETUP_EXCEPT 322
317 UNWIND_JUMP 329 1
320 POP_EXCEPT_JUMP 326
322 POP_TOP
323 POP_EXCEPT_JUMP 326
325 END_FINALLY
326 LOAD_FAST 0
327 POP_JUMP_IF_TRUE 315
329 LOAD_FAST 0
330 SETUP_WITH 337
332 POP_TOP
333 LOAD_DEREF 14
335 POP_TOP
336 LOAD_CONST_NONE
337 WITH_CLEANUP
338 END_FINALLY
339 LOAD_CONST_SMALL_INT 1
340 STORE_DEREF 16
342 LOAD_FAST_N 16
344 MAKE_CLOSURE \.\+ 1
347 STORE_FAST 13
348 LOAD_CONST_SMALL_INT 0
349 LOAD_CONST_NONE
350 IMPORT_NAME 'a'
352 STORE_FAST 0
353 LOAD_CONST_SMALL_INT 0
354 LOAD_CONST_STRING 'b'
356 BUILD_TUPLE 1
358 IMPORT_NAME 'a'
360 IMPORT_FROM 'b'
362 STORE_DEREF 14
364 POP_TOP
365 RAISE_LAST
366 LOAD_CONST_SMALL_INT 1
367 RAISE_OBJ
368 LOAD_CONST_NONE
18 LOAD_CONST_OBJ \.\+=(1, 2)
20 STORE_DEREF 14
22 LOAD_CONST_SMALL_INT 1
23 LOAD_CONST_SMALL_INT 2
24 BUILD_LIST 2
26 STORE_FAST 1
27 LOAD_CONST_SMALL_INT 1
28 LOAD_CONST_SMALL_INT 2
29 BUILD_SET 2
31 STORE_FAST 2
32 BUILD_MAP 0
34 STORE_DEREF 15
36 BUILD_MAP 1
38 LOAD_CONST_SMALL_INT 2
39 LOAD_CONST_SMALL_INT 1
40 STORE_MAP
41 STORE_FAST 3
42 LOAD_CONST_STRING 'a'
44 STORE_FAST 4
45 LOAD_CONST_OBJ \.\+=b'a'
47 STORE_FAST 5
48 LOAD_CONST_SMALL_INT 1
49 STORE_FAST 6
50 LOAD_CONST_SMALL_INT 2
51 STORE_FAST 7
52 LOAD_FAST 0
53 LOAD_DEREF 14
55 BINARY_OP 27 __add__
56 STORE_FAST 8
57 LOAD_FAST 0
58 UNARY_OP 1 __neg__
59 STORE_FAST 9
60 LOAD_FAST 0
61 UNARY_OP 3
62 STORE_FAST 10
63 LOAD_FAST 0
64 LOAD_DEREF 14
66 DUP_TOP
67 ROT_THREE
68 BINARY_OP 2 __eq__
69 JUMP_IF_FALSE_OR_POP 75
71 LOAD_FAST 1
72 BINARY_OP 2 __eq__
73 JUMP 77
75 ROT_TWO
76 POP_TOP
77 STORE_FAST 10
78 LOAD_FAST 0
79 LOAD_DEREF 14
81 BINARY_OP 2 __eq__
82 JUMP_IF_FALSE_OR_POP 88
84 LOAD_DEREF 14
86 LOAD_FAST 1
87 BINARY_OP 2 __eq__
88 UNARY_OP 3
89 STORE_FAST 10
90 LOAD_DEREF 14
92 LOAD_ATTR c
94 STORE_FAST 11
95 LOAD_FAST 11
96 LOAD_DEREF 14
98 STORE_ATTR c
100 LOAD_DEREF 14
102 LOAD_CONST_SMALL_INT 0
103 LOAD_SUBSCR
104 STORE_FAST 12
105 LOAD_FAST 12
106 LOAD_DEREF 14
108 LOAD_CONST_SMALL_INT 0
109 STORE_SUBSCR
110 LOAD_DEREF 14
112 LOAD_CONST_SMALL_INT 0
113 DUP_TOP_TWO
114 LOAD_SUBSCR
115 LOAD_FAST 12
116 BINARY_OP 14 __iadd__
117 ROT_THREE
118 STORE_SUBSCR
119 LOAD_DEREF 14
121 LOAD_CONST_NONE
122 LOAD_CONST_NONE
123 BUILD_SLICE 2
125 LOAD_SUBSCR
126 STORE_FAST 0
127 LOAD_FAST 1
128 UNPACK_SEQUENCE 2
130 STORE_FAST 0
131 STORE_DEREF 14
133 LOAD_FAST 0
134 UNPACK_EX 1
136 STORE_FAST 0
137 STORE_FAST 0
138 LOAD_DEREF 14
140 LOAD_FAST 0
141 ROT_TWO
142 STORE_FAST 0
143 STORE_DEREF 14
145 LOAD_FAST 1
146 LOAD_DEREF 14
148 LOAD_FAST 0
149 ROT_THREE
150 ROT_TWO
151 STORE_FAST 0
152 STORE_DEREF 14
154 STORE_FAST 1
155 DELETE_FAST 0
157 LOAD_FAST 0
158 STORE_GLOBAL gl
160 DELETE_GLOBAL gl
162 LOAD_FAST 14
163 LOAD_FAST 15
164 MAKE_CLOSURE \.\+ 2
167 LOAD_FAST 2
168 GET_ITER
169 CALL_FUNCTION n=1 nkw=0
171 STORE_FAST 0
172 LOAD_FAST 14
173 LOAD_FAST 15
174 MAKE_CLOSURE \.\+ 2
177 LOAD_FAST 2
178 CALL_FUNCTION n=1 nkw=0
180 STORE_FAST 0
181 LOAD_FAST 14
182 LOAD_FAST 15
183 MAKE_CLOSURE \.\+ 2
186 LOAD_FAST 2
187 CALL_FUNCTION n=1 nkw=0
189 STORE_FAST 0
190 LOAD_FAST 0
191 CALL_FUNCTION n=0 nkw=0
193 POP_TOP
194 LOAD_FAST 0
195 LOAD_CONST_SMALL_INT 1
196 CALL_FUNCTION n=1 nkw=0
198 POP_TOP
199 LOAD_FAST 0
200 LOAD_CONST_STRING 'b'
202 LOAD_CONST_SMALL_INT 1
203 CALL_FUNCTION n=0 nkw=1
206 POP_TOP
207 LOAD_FAST 0
208 LOAD_DEREF 14
210 LOAD_CONST_SMALL_INT 1
211 CALL_FUNCTION_VAR_KW n=1 nkw=0
213 POP_TOP
214 LOAD_FAST 0
215 LOAD_METHOD b
217 CALL_METHOD n=0 nkw=0
219 POP_TOP
220 LOAD_FAST 0
221 LOAD_METHOD b
223 LOAD_CONST_SMALL_INT 1
224 CALL_METHOD n=1 nkw=0
226 POP_TOP
227 LOAD_FAST 0
228 LOAD_METHOD b
230 LOAD_CONST_STRING 'c'
232 LOAD_CONST_SMALL_INT 1
233 CALL_METHOD n=0 nkw=1
236 POP_TOP
237 LOAD_FAST 0
238 LOAD_METHOD b
240 LOAD_FAST 1
241 LOAD_CONST_SMALL_INT 1
242 CALL_METHOD_VAR_KW n=1 nkw=0
244 POP_TOP
245 LOAD_FAST 0
246 POP_JUMP_IF_FALSE 253
248 LOAD_DEREF 16
250 POP_TOP
251 JUMP 256
253 LOAD_GLOBAL y
255 POP_TOP
256 JUMP 261
258 LOAD_DEREF 14
260 POP_TOP
261 LOAD_FAST 0
262 POP_JUMP_IF_TRUE 258
264 JUMP 269
266 LOAD_DEREF 14
268 POP_TOP
269 LOAD_FAST 0
270 POP_JUMP_IF_FALSE 266
272 LOAD_FAST 0
273 JUMP_IF_TRUE_OR_POP 276
275 LOAD_FAST 0
276 STORE_FAST 0
277 LOAD_DEREF 14
279 GET_ITER_STACK
280 FOR_ITER 287
282 STORE_FAST 0
283 LOAD_FAST 1
284 POP_TOP
285 JUMP 280
287 SETUP_FINALLY 308
289 SETUP_EXCEPT 300
291 JUMP 295
293 JUMP 298
295 LOAD_FAST 0
296 POP_JUMP_IF_TRUE 293
298 POP_EXCEPT_JUMP 307
300 POP_TOP
301 LOAD_DEREF 14
303 POP_TOP
304 POP_EXCEPT_JUMP 307
306 END_FINALLY
307 LOAD_CONST_NONE
308 LOAD_FAST 1
309 POP_TOP
310 END_FINALLY
311 JUMP 324
313 SETUP_EXCEPT 320
315 UNWIND_JUMP 327 1
318 POP_EXCEPT_JUMP 324
320 POP_TOP
321 POP_EXCEPT_JUMP 324
323 END_FINALLY
324 LOAD_FAST 0
325 POP_JUMP_IF_TRUE 313
327 LOAD_FAST 0
328 SETUP_WITH 335
330 POP_TOP
331 LOAD_DEREF 14
333 POP_TOP
334 LOAD_CONST_NONE
335 WITH_CLEANUP
336 END_FINALLY
337 LOAD_CONST_SMALL_INT 1
338 STORE_DEREF 16
340 LOAD_FAST_N 16
342 MAKE_CLOSURE \.\+ 1
345 STORE_FAST 13
346 LOAD_CONST_SMALL_INT 0
347 LOAD_CONST_NONE
348 IMPORT_NAME 'a'
350 STORE_FAST 0
351 LOAD_CONST_SMALL_INT 0
352 LOAD_CONST_STRING 'b'
354 BUILD_TUPLE 1
356 IMPORT_NAME 'a'
358 IMPORT_FROM 'b'
360 STORE_DEREF 14
362 POP_TOP
363 RAISE_LAST
364 LOAD_CONST_SMALL_INT 1
365 RAISE_OBJ
366 LOAD_CONST_NONE
367 RETURN_VALUE
368 LOAD_CONST_SMALL_INT 1
369 RETURN_VALUE
370 LOAD_CONST_SMALL_INT 1
371 RETURN_VALUE
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 59 bytes)
Raw bytecode (code_info_size=8, bytecode_size=51):
a8 10 0a 02 80 82 34 38 81 57 c0 57 c1 57 c2 57