diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-12-16 07:11:28 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-12-16 07:11:28 -0800 |
commit | 954d698350e41df2bca00c4cba09dfe55f3a8e40 (patch) | |
tree | 4cfe48c1fd17644541ae82a4de3f125ed7aec714 /struct.c | |
parent | b860fe2ea8450109c4bcc0de755bccac40f377ef (diff) | |
download | txr-954d698350e41df2bca00c4cba09dfe55f3a8e40.tar.gz txr-954d698350e41df2bca00c4cba09dfe55f3a8e40.tar.bz2 txr-954d698350e41df2bca00c4cba09dfe55f3a8e40.zip |
Useful feature: object post-initialization.
Structs can now have code which executes after an object is
initialized, which is useful for doing work like registering
objects in global lists and whatever, when those actions need
access to the initialized slots of the object.
* share/txr/stdlib/struct.tl (defstruct): Handle :posinit
syntax, by generating lambda as eighth argument of sys:make-struct
call.
* struct.c (struct struct_type): New member, postinitfun.
(struct_init): Adjust registrations of make_struct_type
to account for new parameter. The user visible
make-struct-type is registered as having one optional
argument, for backward compat.
(make_struct_type): New argument, postinitfun. Store this
in the structure. For backward compatibility, the argument
is defaulted.
(struct_type_mark): Mark the new postinitfun member.
(call_postinitfun_chain): New static function.
(make_struct, lazy_struct_init): Call call_postinitfun_chain
after slots are initialized, and after the boa function is
called.
* struct.h (make_struct_type): Declaration updated.
* lib.c (time_init): Pass eighth argument to make_struct type.
* sysif.c (sysif_init): Likewise.
* unwind.c (uw_late_init): Likewise.
* tests/012/struct.tl: Update defstruct expansion test case.
* txr.1: Document new argument of make-struct-type,
and clarify ordering of initfun with regard to
other actions. Likewise, document :postinit, and clarify
ordering of :init actions with regard to other actions.
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -63,6 +63,7 @@ struct struct_type { val stinitfun; val initfun; val boactor; + val postinitfun; val dvtypes; val *stslot; }; @@ -105,10 +106,10 @@ void struct_init(void) func_n5(make_struct_type_compat)); else reg_fun(intern(lit("make-struct-type"), user_package), - func_n7(make_struct_type)); + func_n8o(make_struct_type, 7)); reg_fun(intern(lit("make-struct-type"), system_package), - func_n7(make_struct_type)); + func_n8(make_struct_type)); reg_fun(intern(lit("find-struct-type"), user_package), func_n1(find_struct_type)); reg_fun(intern(lit("struct-type-p"), user_package), func_n1(struct_type_p)); @@ -197,7 +198,8 @@ static struct struct_type *stype_handle(val *pobj, val ctx) val make_struct_type(val name, val super, val static_slots, val slots, - val static_initfun, val initfun, val boactor) + val static_initfun, val initfun, val boactor, + val postinitfun) { val self = lit("make-struct-type"); @@ -244,6 +246,7 @@ val make_struct_type(val name, val super, st->stinitfun = static_initfun; st->initfun = initfun; st->boactor = boactor; + st->postinitfun = default_bool_arg(postinitfun); st->dvtypes = nil; gc_finalize(stype, struct_type_finalize_f, nil); @@ -290,7 +293,7 @@ val make_struct_type(val name, val super, static val make_struct_type_compat(val name, val super, val slots, val initfun, val boactor) { - return make_struct_type(name, super, nil, slots, nil, initfun, boactor); + return make_struct_type(name, super, nil, slots, nil, initfun, boactor, nil); } val find_struct_type(val sym) @@ -338,6 +341,7 @@ static void struct_type_mark(val obj) gc_mark(st->stinitfun); gc_mark(st->initfun); gc_mark(st->boactor); + gc_mark(st->postinitfun); gc_mark(st->dvtypes); for (stsl = 0; stsl < st->nstslots; stsl++) @@ -354,6 +358,16 @@ static void call_initfun_chain(struct struct_type *st, val strct) } } +static void call_postinitfun_chain(struct struct_type *st, val strct) +{ + if (st) { + if (st->postinitfun) + funcall1(st->postinitfun, strct); + if (st->super) + call_postinitfun_chain(st->super_handle, strct); + } +} + val make_struct(val type, val plist, struct args *args) { val self = lit("make-struct"); @@ -395,6 +409,8 @@ val make_struct(val type, val plist, struct args *args) generic_funcall(st->boactor, args_copy); } + call_postinitfun_chain(st, sinst); + inited = t; uw_unwind { @@ -436,6 +452,8 @@ static void lazy_struct_init(val sinst, struct struct_inst *si) generic_funcall(st->boactor, argv); } + call_postinitfun_chain(st, sinst); + inited = t; uw_unwind { |