summaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-05-14 17:24:15 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-05-14 17:24:15 -0700
commitb691d5d10d7bd646cb2ab6805cbaf7303c45a4f2 (patch)
tree06832510fdf26a50d70a18d10884837a750bc011 /struct.c
parent400acf8d0a8df38401b5711894e9e342f6403d56 (diff)
downloadtxr-b691d5d10d7bd646cb2ab6805cbaf7303c45a4f2.tar.gz
txr-b691d5d10d7bd646cb2ab6805cbaf7303c45a4f2.tar.bz2
txr-b691d5d10d7bd646cb2ab6805cbaf7303c45a4f2.zip
Fix generational-GC bug in struct code.
* struct.c (static_slot_ensure): In the case when we grow the array of static slots, we were allowing chk_manage_vec to initialize the newly added element. This is wrong, because it is just a plain assignment, which causes a mature object to point to a baby object. This bug caused static slots to contain junk.
Diffstat (limited to 'struct.c')
-rw-r--r--struct.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/struct.c b/struct.c
index 2cda3cbd..7cfdee24 100644
--- a/struct.c
+++ b/struct.c
@@ -819,12 +819,14 @@ val static_slot_ensure(val stype, val sym, val newval, val no_error_p)
st->eqmslot = 0;
if (nullocp((ptr = lookup_static_slot(stype, st, sym)))) {
+ val null_ptr = 0;
if (!memq(sym, st->slots)) {
st->stslot = coerce(val *, chk_manage_vec(coerce(mem_t *, st->stslot),
st->nstslots, st->nstslots + 1,
sizeof (val),
- coerce(mem_t *, &newval)));
+ coerce(mem_t *, &null_ptr)));
set(mkloc(st->slots, stype), append2(st->slots, cons(sym, nil)));
+ ptr = mkloc(st->stslot[st->nstslots], stype);
sethash(slot_hash, cons(sym, num_fast(st->id)),
num(st->nstslots++ + STATIC_SLOT_BASE));
} else {
@@ -832,10 +834,10 @@ val static_slot_ensure(val stype, val sym, val newval, val no_error_p)
uw_throwf(error_s, lit("~a: ~s is an instance slot of ~s"),
self, sym, stype, nao);
}
- } else {
- set(ptr, newval);
}
+ set(ptr, newval);
+
{
val iter;
for (iter = st->dvtypes; iter; iter = cdr(iter))