Sharing the hook environment between mutually unaware hooks is awkward -- if the environment is cast to a particular struct pointer, all hooks need to account for the type, and it may need to box the environments for built-in hooks such as theft_hook_trial_post_print_result.
The heart of the problem is a lack of late binding -- without breaking reverse compatibility, theft could provide an optional, dynamically allocated environment, with some sort of magic tag to check before casting: the user could construct a key/value environment with defaults, and hook-specific state could be keyed by name:
theft_env_new(t); could construct an environment without any defaults (for other cases where a dynamic environment is useful).
This environment would have the same lifetime as the theft-instance, so (if used) it could be freed inside theft_run_free, or theft_env_free(t, hook_env); could be used explicitly.
The environment could be implemented with a relatively simple (const char * -> tagged(int | void *)) map type.
Sharing the hook environment between mutually unaware hooks is awkward -- if the environment is cast to a particular struct pointer, all hooks need to account for the type, and it may need to box the environments for built-in hooks such as
theft_hook_trial_post_print_result
.The heart of the problem is a lack of late binding -- without breaking reverse compatibility, theft could provide an optional, dynamically allocated environment, with some sort of magic tag to check before casting: the user could construct a key/value environment with defaults, and hook-specific state could be keyed by name:
Built-in hooks would have reserved keys.
The environment could tag the value with a general type internally, and have type-specific get/set functions. (Maybe just
void *
and int.)theft_env_new(t);
could construct an environment without any defaults (for other cases where a dynamic environment is useful).This environment would have the same lifetime as the theft-instance, so (if used) it could be freed inside
theft_run_free
, ortheft_env_free(t, hook_env);
could be used explicitly.The environment could be implemented with a relatively simple
(const char * -> tagged(int | void *)) map
type.