diff options
author | Damien George <damien.p.george@gmail.com> | 2017-12-11 22:39:12 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-12-11 22:39:12 +1100 |
commit | 2759bec8587b0c0b7da1fa3a013e4f1b1530ad27 (patch) | |
tree | 42d424cc8f3a3024cc020cdcc3aee6e2bd9593e4 /py/parse.c | |
parent | 9c027073568d9be43bd1aabcac60a6ff208c4299 (diff) |
py: Extend nan-boxing config to have 47-bit small integers.
The nan-boxing representation has an extra 16-bits of space to store
small-int values, and making use of it allows to create and manipulate full
32-bit positive integers (ie up to 0xffffffff) without using the heap.
Diffstat (limited to 'py/parse.c')
-rw-r--r-- | py/parse.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/py/parse.c b/py/parse.c index f7fe30418..b80cc8fb1 100644 --- a/py/parse.c +++ b/py/parse.c @@ -369,6 +369,18 @@ STATIC mp_parse_node_t make_node_const_object(parser_t *parser, size_t src_line, return (mp_parse_node_t)pn; } +STATIC mp_parse_node_t mp_parse_node_new_small_int_checked(parser_t *parser, mp_obj_t o_val) { + (void)parser; + mp_int_t val = MP_OBJ_SMALL_INT_VALUE(o_val); + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D + // A parse node is only 32-bits and the small-int value must fit in 31-bits + if (((val ^ (val << 1)) & 0xffffffff80000000) != 0) { + return make_node_const_object(parser, 0, o_val); + } + #endif + return mp_parse_node_new_small_int(val); +} + STATIC void push_result_token(parser_t *parser, const rule_t *rule) { mp_parse_node_t pn; mp_lexer_t *lex = parser->lexer; @@ -380,7 +392,7 @@ STATIC void push_result_token(parser_t *parser, const rule_t *rule) { if (rule->rule_id == RULE_atom && (elem = mp_map_lookup(&parser->consts, MP_OBJ_NEW_QSTR(id), MP_MAP_LOOKUP)) != NULL) { if (MP_OBJ_IS_SMALL_INT(elem->value)) { - pn = mp_parse_node_new_small_int(MP_OBJ_SMALL_INT_VALUE(elem->value)); + pn = mp_parse_node_new_small_int_checked(parser, elem->value); } else { pn = make_node_const_object(parser, lex->tok_line, elem->value); } @@ -394,7 +406,7 @@ STATIC void push_result_token(parser_t *parser, const rule_t *rule) { } else if (lex->tok_kind == MP_TOKEN_INTEGER) { mp_obj_t o = mp_parse_num_integer(lex->vstr.buf, lex->vstr.len, 0, lex); if (MP_OBJ_IS_SMALL_INT(o)) { - pn = mp_parse_node_new_small_int(MP_OBJ_SMALL_INT_VALUE(o)); + pn = mp_parse_node_new_small_int_checked(parser, o); } else { pn = make_node_const_object(parser, lex->tok_line, o); } @@ -686,7 +698,7 @@ STATIC bool fold_constants(parser_t *parser, const rule_t *rule, size_t num_args pop_result(parser); } if (MP_OBJ_IS_SMALL_INT(arg0)) { - push_result_node(parser, mp_parse_node_new_small_int(MP_OBJ_SMALL_INT_VALUE(arg0))); + push_result_node(parser, mp_parse_node_new_small_int_checked(parser, arg0)); } else { // TODO reuse memory for parse node struct? push_result_node(parser, make_node_const_object(parser, 0, arg0)); |