summaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-11-15 19:35:19 -0800
committerKaz Kylheku <kaz@kylheku.com>2023-11-15 19:35:19 -0800
commit7d6caf9959e5bf92c6714ca19fb2f628d3c72bfb (patch)
tree42456efc9567acf19a6da6015831671be79124df /struct.c
parentab7b3f9c872d103ffe21fa65f5b420dc94414f75 (diff)
downloadtxr-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.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/struct.c b/struct.c
index 3bcdd29a..5e8c7647 100644
--- a/struct.c
+++ b/struct.c
@@ -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];