summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-01-06 23:58:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-01-06 23:58:14 -0800
commit1d427b61be3f8f42a6e740b3080102f54f4d806b (patch)
treebd58be9dc17baf2f5143db3b146ba0357ae0ec4e
parent5464e5ab1ae7d1eeba1dfbea36bc5e81714d1694 (diff)
downloadtxr-1d427b61be3f8f42a6e740b3080102f54f4d806b.tar.gz
txr-1d427b61be3f8f42a6e740b3080102f54f4d806b.tar.bz2
txr-1d427b61be3f8f42a6e740b3080102f54f4d806b.zip
lib: review cobj calls for gc incorrectness and fix.
I looked at all cobj calls to see if there is a potential problem, looking for situations whereby the cobj call could trigger a gc that would destroy Lisp objects that the new object either stores, or that its continued initialization depends on. * stream.c (make_strlist_input_stream): call cobj earlier, then fill in the structure. Use chk_calloc to allocate the structure so any Lisp objects in it look like nil until it is initialized. * struct.c (make_struct_impl, make_lazy_struct): Use gc_hint on the type argument, to pin down the st structure that we use in initializations after the cobj call. If the type object were to disappear, the st structure would become invalid. * tree.c (copy_search_tree, make_similar_tree): Use gc_hint on the tree argument to pin down the otr structure that we reference in initializations (copy_tree_iter): Use gc_hint on iter, for similar reasons. * vm.c (vm_copy_closure): Use gc_hint on oclosure, to pin down the environment we are copying from it.
-rw-r--r--stream.c5
-rw-r--r--struct.c4
-rw-r--r--tree.c4
-rw-r--r--vm.c2
4 files changed, 13 insertions, 2 deletions
diff --git a/stream.c b/stream.c
index bf90613e..12644455 100644
--- a/stream.c
+++ b/stream.c
@@ -2243,12 +2243,13 @@ static struct strm_ops strlist_in_ops =
val make_strlist_input_stream(val list)
{
- struct strlist_in *s = coerce(struct strlist_in *, chk_malloc(sizeof *s));
+ struct strlist_in *s = coerce(struct strlist_in *, chk_calloc(sizeof *s, 1));
+ val stream = cobj(coerce(mem_t *, s), stream_cls, &strlist_in_ops.cobj_ops);
strm_base_init(&s->a);
s->string = car(list);
s->pos = zero;
s->list = cdr(list);
- return cobj(coerce(mem_t *, s), stream_cls, &strlist_in_ops.cobj_ops);
+ return stream;
}
struct string_out {
diff --git a/struct.c b/struct.c
index 5e8c7647..653311d3 100644
--- a/struct.c
+++ b/struct.c
@@ -856,6 +856,8 @@ static val make_struct_impl(val self, val type,
uw_catch_end;
+ gc_hint(type);
+
return sinst;
}
@@ -947,6 +949,8 @@ val make_lazy_struct(val type, val argfun)
bug_unless (type == st->self);
+ gc_hint(type);
+
si->slot[0] = argfun;
return sinst;
diff --git a/tree.c b/tree.c
index 01844931..8c0adb84 100644
--- a/tree.c
+++ b/tree.c
@@ -921,6 +921,7 @@ val copy_search_tree(val tree)
val ntree = cobj(coerce(mem_t *, ntr), tree_cls, &tree_ops);
*ntr = *otr;
ntr->root = nroot;
+ gc_hint(tree);
return ntree;
}
@@ -933,6 +934,7 @@ val make_similar_tree(val tree)
*ntr = *otr;
ntr->root = nil;
ntr->size = ntr->max_size = 0;
+ gc_hint(tree);
return ntree;
}
@@ -1014,6 +1016,8 @@ val copy_tree_iter(val iter)
memcpy(tdid->ti.path, tdis->ti.path, sizeof tdid->ti.path[0] * depth);
+ gc_hint(iter);
+
return iter_copy;
}
diff --git a/vm.c b/vm.c
index 60203554..4928d577 100644
--- a/vm.c
+++ b/vm.c
@@ -317,6 +317,8 @@ val vm_copy_closure(val oclosure)
}
}
+ gc_hint(oclosure);
+
return nclosure;
}