py/parse: Always free lexer even if an exception is raised.
Fixes issue #3843. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
c9089e71a1
commit
5e122b11ea
@ -1023,6 +1023,9 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
|
mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
|
||||||
|
// Set exception handler to free the lexer if an exception is raised.
|
||||||
|
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, mp_lexer_free, lex);
|
||||||
|
nlr_push_jump_callback(&ctx.callback, mp_call_function_1_from_nlr_jump_callback);
|
||||||
|
|
||||||
// initialise parser and allocate memory for its stacks
|
// initialise parser and allocate memory for its stacks
|
||||||
|
|
||||||
@ -1370,8 +1373,8 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
|
|||||||
m_del(rule_stack_t, parser.rule_stack, parser.rule_stack_alloc);
|
m_del(rule_stack_t, parser.rule_stack, parser.rule_stack_alloc);
|
||||||
m_del(mp_parse_node_t, parser.result_stack, parser.result_stack_alloc);
|
m_del(mp_parse_node_t, parser.result_stack, parser.result_stack_alloc);
|
||||||
|
|
||||||
// we also free the lexer on behalf of the caller
|
// Deregister exception handler and free the lexer.
|
||||||
mp_lexer_free(lex);
|
nlr_pop_jump_callback(true);
|
||||||
|
|
||||||
return parser.tree;
|
return parser.tree;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ user_files = {
|
|||||||
"/data.txt": b"some data in a text file",
|
"/data.txt": b"some data in a text file",
|
||||||
"/usermod1.py": b"print('in usermod1')\nimport usermod2",
|
"/usermod1.py": b"print('in usermod1')\nimport usermod2",
|
||||||
"/usermod2.py": b"print('in usermod2')",
|
"/usermod2.py": b"print('in usermod2')",
|
||||||
|
"/usermod3.py": b"syntax error",
|
||||||
}
|
}
|
||||||
os.mount(UserFS(user_files), "/userfs")
|
os.mount(UserFS(user_files), "/userfs")
|
||||||
|
|
||||||
@ -79,6 +80,12 @@ print(f.read())
|
|||||||
sys.path.append("/userfs")
|
sys.path.append("/userfs")
|
||||||
import usermod1
|
import usermod1
|
||||||
|
|
||||||
|
# import a .py file with a syntax error (file should be closed on error)
|
||||||
|
try:
|
||||||
|
import usermod3
|
||||||
|
except SyntaxError:
|
||||||
|
print("SyntaxError in usermod3")
|
||||||
|
|
||||||
# unmount and undo path addition
|
# unmount and undo path addition
|
||||||
os.umount("/userfs")
|
os.umount("/userfs")
|
||||||
sys.path.pop()
|
sys.path.pop()
|
||||||
|
@ -10,3 +10,8 @@ stat /usermod2.py
|
|||||||
open /usermod2.py rb
|
open /usermod2.py rb
|
||||||
ioctl 4 0
|
ioctl 4 0
|
||||||
in usermod2
|
in usermod2
|
||||||
|
stat /usermod3
|
||||||
|
stat /usermod3.py
|
||||||
|
open /usermod3.py rb
|
||||||
|
ioctl 4 0
|
||||||
|
SyntaxError in usermod3
|
||||||
|
Loading…
Reference in New Issue
Block a user