summaryrefslogtreecommitdiff
path: root/py/compile.c
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2022-04-01 00:00:58 +1100
committerDamien George <damien@micropython.org>2022-04-01 09:20:42 +1100
commitbd556b69960cafc97353e736f825eca5c00b0c29 (patch)
treec92422308d39f738ecefeef4fed269b5fde2ddf7 /py/compile.c
parente3de723e2d955ca89c8b06bb2c4ae86724aad77b (diff)
py: Fix compiling and decoding of *args at large arg positions.
There were two issues with the existing code: 1. "1 << i" is computed as a 32-bit number so would overflow when executed on 64-bit machines (when mp_uint_t is 64-bit). This meant that *args beyond 32 positions would not be handled correctly. 2. star_args must fit as a positive small int so that it is encoded correctly in the emitted code. MP_SMALL_INT_BITS is too big because it overflows a small int by 1 bit. MP_SMALL_INT_BITS - 1 does not work because it produces a signed small int which is then sign extended when extracted (even by mp_obj_get_int_truncated), and this sign extension means that any position arg after *args is also treated as a star-arg. So the maximum bit position is MP_SMALL_INT_BITS - 2. This means that MP_OBJ_SMALL_INT_VALUE() can be used instead of mp_obj_get_int_truncated() to get the value of star_args. These issues are fixed by this commit, and a test added. Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/py/compile.c b/py/compile.c
index fc1106270..e4ead7f1a 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -2408,9 +2408,9 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
return;
}
#if MICROPY_DYNAMIC_COMPILER
- if (i > mp_dynamic_compiler.small_int_bits)
+ if (i >= (size_t)mp_dynamic_compiler.small_int_bits - 1)
#else
- if (i > MP_SMALL_INT_BITS)
+ if (i >= MP_SMALL_INT_BITS - 1)
#endif
{
// If there are not enough bits in a small int to fit the flag, then we consider
@@ -2419,7 +2419,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
return;
}
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
- star_args |= 1 << i;
+ star_args |= (mp_uint_t)1 << i;
compile_node(comp, pns_arg->nodes[0]);
n_positional++;
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {