summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-06-19 06:42:59 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-06-19 06:42:59 -0700
commit95d5b41266ca3cd40dcd948ecad06d570be32812 (patch)
treef0d8860d3838051d7c48e0490ae1c32ec3b75a26
parentee639342a87cbb1db085f58f5f57cb2085832173 (diff)
downloadtxr-95d5b41266ca3cd40dcd948ecad06d570be32812.tar.gz
txr-95d5b41266ca3cd40dcd948ecad06d570be32812.tar.bz2
txr-95d5b41266ca3cd40dcd948ecad06d570be32812.zip
packages: generational gc bug.
* lib.c (make_package_common): The way the two hashes are assigned into the new package here is not correct. The problem is that the first make_hash can trigger gc. Then it is possible that the package object will move into the mature generation, after which the assignment of the second package is a wrong-way assignment requiring the set macro. Instead of bringing in that macro, the obvious way to solve it is to just allocate the hashes first, and then the package: exactly the way we build a cons cell from existing values.
-rw-r--r--lib.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/lib.c b/lib.c
index f1740e52..12863cf3 100644
--- a/lib.c
+++ b/lib.c
@@ -4940,13 +4940,13 @@ val gensym(val prefix)
static val make_package_common(val name)
{
+ val sh = make_hash(nil, nil, lit("t")); /* don't have t yet! */
+ val hh = make_hash(nil, nil, lit("t"));
val obj = make_obj();
obj->pk.type = PKG;
obj->pk.name = name;
- obj->pk.symhash = nil; /* make_hash calls below could trigger gc! */
- obj->pk.hidhash = nil;
- obj->pk.symhash = make_hash(nil, nil, lit("t")); /* don't have t yet! */
- obj->pk.hidhash = make_hash(nil, nil, lit("t"));
+ obj->pk.symhash = sh;
+ obj->pk.hidhash = hh;
return obj;
}