From 6d6c9b6c5dffec88e609f09cbee9c53ec2878c6a Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 28 Feb 2018 18:48:44 -0800 Subject: bugfix: missing actions in reset-struct. * struct.c (reset_struct): Perform the post-init actions are performed, not only the init actions. Also, catch exceptions and call finalizers, just like in a new structure instantiation. * txr.1: Document the requirements for finalizers being called by reset-struct, and clarify the issue of possible duplicate finalization registration. Add compat notes. --- struct.c | 16 ++++++++++++++++ txr.1 | 31 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/struct.c b/struct.c index 6178340b..0e8b1080 100644 --- a/struct.c +++ b/struct.c @@ -726,14 +726,30 @@ val reset_struct(val strct) struct struct_inst *si = struct_handle(strct, self); struct struct_type *st = si->type; cnum i; + volatile val inited = nil; + int compat_190 = opt_compat && opt_compat <= 190; check_init_lazy_struct(strct, si); + uw_simple_catch_begin; + for (i = 0; i < st->nslots; i++) si->slot[i] = nil; call_initfun_chain(st, strct); + if (!compat_190) + call_postinitfun_chain(st, strct); + + inited = t; + + uw_unwind { + if (!inited && !compat_190) + gc_call_finalizers(strct); + } + + uw_catch_end; + return strct; } diff --git a/txr.1 b/txr.1 index 7264bb2e..a8a482b2 100644 --- a/txr.1 +++ b/txr.1 @@ -24773,7 +24773,8 @@ and no boa arguments. Note that finalizers registered against .meta struct-obj -are not invoked, and remain registered. +are not invoked prior to the reset operation, and remain registered. + If the structure has state which is cleaned up by finalizers, it is advisable to invoke them using .code call-finalizers @@ -24782,6 +24783,24 @@ prior to using or to take other measures to deal with the situation. +If the structure specifies +.code :fini +handlers, then the reinitialization will cause +these to registered, just like when a new object +it constructed. Thus if +.code call-finalizers +is not used prior to +.codn reset-struct , +this will result in the existence of duplicate registrations of the +finalization functions. + +Finalizers registered against +.meta struct-obj +.B are +invoked if an exception is thrown +during the reinitialization, just like when a new +structure is being constructed. + .coNP Function @ replace-struct .synb .mets (replace-struct < target-obj << source-obj ) @@ -63207,6 +63226,16 @@ of these version values, the described behaviors are provided if is given an argument which is equal or lower. For instance .code "-C 103" selects the behaviors described below for version 105, but not those for 102. +.IP 190 +Until \*(TX 190, the +.code reset-struct +function neglected to perform +.code :postinit +initializations, and didn't invoke finalization on the structure object +if an exception was thrown during reinitialization. Thus, contrary +to documented requirements, reinitialization of a structure didn't behave +like fresh construction. This behavior is replicated if compatibility +with 190 or earlier is requested. .IP 188 Until \*(TX 188, .codn equal -based -- cgit v1.2.3