Skip to content

Commit dff7445

Browse files
committed
Make parsing more memory flexible.
The parser attempts to allocate two large (~512 byte) chunks up front. If it couldn't, then it would error out. This change will cause it to try allocating half the previous attempt until its down to two copies. This is ok upfront because later code checks bounds and tries to extend the allocation if needed.
1 parent d201ac2 commit dff7445

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

py/parse.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,30 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
742742

743743
parser.rule_stack_alloc = MICROPY_ALLOC_PARSE_RULE_INIT;
744744
parser.rule_stack_top = 0;
745-
parser.rule_stack = m_new(rule_stack_t, parser.rule_stack_alloc);
745+
parser.rule_stack = NULL;
746+
while (parser.rule_stack_alloc > 1) {
747+
parser.rule_stack = m_new_maybe(rule_stack_t, parser.rule_stack_alloc);
748+
if (parser.rule_stack != NULL) {
749+
break;
750+
} else {
751+
parser.rule_stack_alloc /= 2;
752+
}
753+
}
746754

747755
parser.result_stack_alloc = MICROPY_ALLOC_PARSE_RESULT_INIT;
748756
parser.result_stack_top = 0;
749-
parser.result_stack = m_new(mp_parse_node_t, parser.result_stack_alloc);
757+
parser.result_stack = NULL;
758+
while (parser.result_stack_alloc > 1) {
759+
parser.result_stack = m_new_maybe(mp_parse_node_t, parser.result_stack_alloc);
760+
if (parser.result_stack != NULL) {
761+
break;
762+
} else {
763+
parser.result_stack_alloc /= 2;
764+
}
765+
}
766+
if (parser.rule_stack == NULL || parser.result_stack == NULL) {
767+
mp_raise_msg(&mp_type_MemoryError, "Unable to init parser");
768+
}
750769

751770
parser.lexer = lex;
752771

0 commit comments

Comments
 (0)