stmhal: Improve handling of out-of-memory in REPL.
Addresses issue #558, but it's likely that other out-of-memory errors could crash the pyboard. Reason is that qstrs use m_new and can raise an exception within the parser.
This commit is contained in:
parent
e1199ecf10
commit
b0edec61ac
@ -163,7 +163,11 @@ raw_repl_reset:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
|
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
|
||||||
parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false);
|
if (lex == NULL) {
|
||||||
|
printf("MemoryError\n");
|
||||||
|
} else {
|
||||||
|
parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false);
|
||||||
|
}
|
||||||
|
|
||||||
// indicate end of output with EOF character
|
// indicate end of output with EOF character
|
||||||
stdout_tx_str("\004");
|
stdout_tx_str("\004");
|
||||||
@ -239,7 +243,11 @@ friendly_repl_reset:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
|
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
|
||||||
parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true);
|
if (lex == NULL) {
|
||||||
|
printf("MemoryError\n");
|
||||||
|
} else {
|
||||||
|
parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +55,13 @@ void readline_init(void) {
|
|||||||
memset(readline_hist, 0, READLINE_HIST_SIZE * sizeof(const char*));
|
memset(readline_hist, 0, READLINE_HIST_SIZE * sizeof(const char*));
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC char *str_dup(const char *str) {
|
STATIC char *str_dup_maybe(const char *str) {
|
||||||
uint32_t len = strlen(str);
|
uint32_t len = strlen(str);
|
||||||
char *s2 = m_new(char, len + 1);
|
char *s2 = m_new_maybe(char, len + 1);
|
||||||
memcpy(s2, str, len);
|
if (s2 == NULL) {
|
||||||
s2[len] = 0;
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(s2, str, len + 1);
|
||||||
return s2;
|
return s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,10 +94,13 @@ int readline(vstr_t *line, const char *prompt) {
|
|||||||
if (line->len > orig_line_len && (readline_hist[0] == NULL || strcmp(readline_hist[0], line->buf + orig_line_len) != 0)) {
|
if (line->len > orig_line_len && (readline_hist[0] == NULL || strcmp(readline_hist[0], line->buf + orig_line_len) != 0)) {
|
||||||
// a line which is not empty and different from the last one
|
// a line which is not empty and different from the last one
|
||||||
// so update the history
|
// so update the history
|
||||||
for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
|
char *most_recent_hist = str_dup_maybe(line->buf + orig_line_len);
|
||||||
readline_hist[i] = readline_hist[i - 1];
|
if (most_recent_hist != NULL) {
|
||||||
|
for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
|
||||||
|
readline_hist[i] = readline_hist[i - 1];
|
||||||
|
}
|
||||||
|
readline_hist[0] = most_recent_hist;
|
||||||
}
|
}
|
||||||
readline_hist[0] = str_dup(line->buf + orig_line_len);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (c == 27) {
|
} else if (c == 27) {
|
||||||
|
Loading…
Reference in New Issue
Block a user