From 35c0cff92bea230f8e16a8a7cdd50ea5f6a9df03 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 31 Mar 2022 14:27:47 +1100 Subject: [PATCH] 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 --- py/mpconfig.h | 6 + py/parse.c | 147 ++++++++ tests/cmdline/cmd_showbc.py.exp | 644 ++++++++++++++++---------------- 3 files changed, 474 insertions(+), 323 deletions(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 22dfbb8675..c308c31bda 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -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) diff --git a/py/parse.c b/py/parse.c index 8f0a25cf2c..b8a40f4bb5 100644 --- a/py/parse.c +++ b/py/parse.c @@ -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); diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index 663bacda01..f3ca2eb634 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -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