diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-11-15 19:35:19 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-11-15 19:35:19 -0800 |
commit | 7d6caf9959e5bf92c6714ca19fb2f628d3c72bfb (patch) | |
tree | 42456efc9567acf19a6da6015831671be79124df /struct.c | |
parent | ab7b3f9c872d103ffe21fa65f5b420dc94414f75 (diff) | |
download | txr-7d6caf9959e5bf92c6714ca19fb2f628d3c72bfb.tar.gz txr-7d6caf9959e5bf92c6714ca19fb2f628d3c72bfb.tar.bz2 txr-7d6caf9959e5bf92c6714ca19fb2f628d3c72bfb.zip |
oop: segfault in special methods cache.
* struct.c (invalidate_special_slots): New static function.
(invalidate_special_slot_nonexistence): Move static function
up in file, to be next to invalidate_special_slots.
(make_struct_type, static_slot_ens_rec): Call the new
invalidate_special_slots function in addition to calling
static_slot_home_fixup whenever the stslots array is resized.
The spslot array contains pointers to the elements of stslots,
which become invalid when that is resized.
* tests/012/oop-seq.tl: Repro test case added.
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 31 |
1 files changed, 20 insertions, 11 deletions
@@ -332,6 +332,24 @@ static void static_slot_home_fixup(struct struct_type *st) } } +static void invalidate_special_slot_nonexistence(struct struct_type *st) +{ + if (st->spslot != 0) { + int i; + for (i = 0; i < num_special_slots; i++) { + if (st->spslot[i] == coerce(struct stslot *, -1)) + st->spslot[i] = 0; + } + } +} + +static void invalidate_special_slots(struct struct_type *st) +{ + if (st->spslot != 0) + memset(st->spslot, 0, sizeof *st->spslot * num_special_slots); +} + + static val get_all_supers(val supers, val self) { list_collect_decl (all_supers, ptail); @@ -572,6 +590,7 @@ val make_struct_type(val name, val supers, st->nslots = sl; st->nstslots = stsl; static_slot_home_fixup(st); + invalidate_special_slots(st); sethash(struct_type_hash, name, stype); @@ -1304,17 +1323,6 @@ val static_slot(val stype, val sym) no_such_static_slot(self, stype, sym); } -static void invalidate_special_slot_nonexistence(struct struct_type *st) -{ - if (st->spslot != 0) { - int i; - for (i = 0; i < num_special_slots; i++) { - if (st->spslot[i] == coerce(struct stslot *, -1)) - st->spslot[i] = 0; - } - } -} - val static_slot_set(val stype, val sym, val newval) { val self = lit("static-slot-set"); @@ -1444,6 +1452,7 @@ static val static_slot_ens_rec(val stype, val sym, val newval, sizeof *st->stslot, coerce(mem_t *, &null_ptr))); static_slot_home_fixup_rec(st); + invalidate_special_slots(st); set(mkloc(st->slots, stype), append2(st->slots, cons(sym, nil))); stsl = &st->stslot[st->nstslots]; |