summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-05-31 20:44:51 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-05-31 20:44:51 -0700
commit917f2435e33e6865e6a8c42b3f2b56e257d31321 (patch)
treeb0bf31dbe17478c9457539ca163838ce9412e474
parent355919810f5e2ff881f9a1aa75818a0b68b8d134 (diff)
downloadtxr-917f2435e33e6865e6a8c42b3f2b56e257d31321.tar.gz
txr-917f2435e33e6865e6a8c42b3f2b56e257d31321.tar.bz2
txr-917f2435e33e6865e6a8c42b3f2b56e257d31321.zip
parser: gc bug in token.
The parser maintains some token objects for one parse job to the next in the tok_pushback and recent_tok arrays. When the recent_tok is assigned into the parser, it could be a wrong-way assignment: the parser is a gen 1 object, yet the token's semantic value of type val is a gen 0. * parser.c (lisp_parse_impl, txr_parse): Before re-enabling gc, indicate that the parser object may have been mutated by a wrong-way assignment using the mut macro. * txr.c (txr_main): Likewise.
-rw-r--r--parser.c2
-rw-r--r--txr.c1
2 files changed, 3 insertions, 0 deletions
diff --git a/parser.c b/parser.c
index 368ecebd..85b80202 100644
--- a/parser.c
+++ b/parser.c
@@ -665,6 +665,7 @@ static val lisp_parse_impl(val self, enum prime_parser prime,
for (;;) {
int gc = gc_state(0);
parse(pi, if3(std_error != std_null, name, lit("")), prime);
+ mut(parser);
gc_state(gc);
if (pi->syntax_tree == nao && pi->errors == 0 && !pi->eof)
@@ -823,6 +824,7 @@ val txr_parse(val source_in, val error_stream,
uw_unwind {
dyn_env = saved_dyn;
+ mut(parser_obj);
gc_state(gc);
if (!loading)
uw_release_deferred_warnings();
diff --git a/txr.c b/txr.c
index e5396b61..90d6d84e 100644
--- a/txr.c
+++ b/txr.c
@@ -1068,6 +1068,7 @@ int txr_main(int argc, char **argv)
val parser_obj = ensure_parser(parse_stream, spec_file_str);
parser_t *parser = parser_get_impl(prog_string, parser_obj);
parse_once_noerr(parse_stream, spec_file_str);
+ mut(parser_obj)
gc_state(gc);
close_stream(parse_stream, nil);