summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-06-19 06:28:53 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-06-19 06:28:53 -0700
commit06a91d0371b6c94ad0b9cb9be00401b5a0295bf6 (patch)
tree3da967385adf201335522f26ef66b1629bf70f7e
parenteab5fb01f5cc396fd0265c501527a3ac7470c86c (diff)
downloadtxr-06a91d0371b6c94ad0b9cb9be00401b5a0295bf6.tar.gz
txr-06a91d0371b6c94ad0b9cb9be00401b5a0295bf6.tar.bz2
txr-06a91d0371b6c94ad0b9cb9be00401b5a0295bf6.zip
structs: gc bug due to derived hook.
* struct.c (make_struct_type): The static slot lookup for for a derived method in the supertype can potentially allocate a cons cell when there is a cache miss, which can trigger gc. So we can't be doing this while a the new type object object is partially initialized, because then the garbage collector will visit uninitialized memory. We move the derived method lookup down farther to where that value is needed to do the derived call, just before we return the new type.
-rw-r--r--struct.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/struct.c b/struct.c
index 02fb0e44..2374a612 100644
--- a/struct.c
+++ b/struct.c
@@ -310,7 +310,6 @@ val make_struct_type(val name, val super,
val super_slots = if2(su, su->slots);
val all_slots = uniq(append2(super_slots, append2(static_slots, slots)));
val stype = cobj(coerce(mem_t *, st), struct_type_s, &struct_type_ops);
- struct stslot *dvmeth = if3(su, lookup_static_slot_desc(su, derived_s), 0);
val iter;
cnum sl, stsl;
cnum stsl_upb = c_num(plus(length(static_slots),
@@ -397,8 +396,11 @@ val make_struct_type(val name, val super,
uw_purge_deferred_warning(cons(struct_type_s, name));
- if (dvmeth)
- funcall2(stslot_place(dvmeth), su->self, stype);
+ if (su) {
+ struct stslot *dvmeth = lookup_static_slot_desc(su, derived_s);
+ if (dvmeth)
+ funcall2(stslot_place(dvmeth), su->self, stype);
+ }
return stype;
}