diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-06-19 06:28:53 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-06-19 06:28:53 -0700 |
commit | 5b0d68a85dd9e9dca020ac4bfbbcf72cf8347a2b (patch) | |
tree | 3da967385adf201335522f26ef66b1629bf70f7e /struct.c | |
parent | cd2620a2a3455a127d938819a673c3bc1c97d612 (diff) | |
download | txr-5b0d68a85dd9e9dca020ac4bfbbcf72cf8347a2b.tar.gz txr-5b0d68a85dd9e9dca020ac4bfbbcf72cf8347a2b.tar.bz2 txr-5b0d68a85dd9e9dca020ac4bfbbcf72cf8347a2b.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.
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -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; } |