summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-09-03 07:28:46 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-09-03 07:28:46 -0700
commitc5985ee382ef9e11322346b25504216fa8a87510 (patch)
tree60f9cc1c6f97f3ec0a305244fbc847f4d25f18f6
parentee19313e53e3a98321e1a405e41c8a0489fc68ca (diff)
downloadtxr-c5985ee382ef9e11322346b25504216fa8a87510.tar.gz
txr-c5985ee382ef9e11322346b25504216fa8a87510.tar.bz2
txr-c5985ee382ef9e11322346b25504216fa8a87510.zip
load: scope change for load hooks.
* eval.c (run_load_hooks): Install the given environment as dyn_env temporarily, and don't restore it until after calling the hooks. Thus the specified environment is now in effect when running the hooks. Also, pass nil to lookup_var, in the spirit of the previous commit. The fact that load_dyn_env had to be passed to lookup_var previously, which is an anti-pattern, tells us that this scoping rule was a code smell. If the *load-hooks* value comes from a given dynamic environment, then those functions should be executed in exactly that environment. * txr.1: Documentation updated.
-rw-r--r--eval.c5
-rw-r--r--txr.131
2 files changed, 16 insertions, 20 deletions
diff --git a/eval.c b/eval.c
index e1580641..3dbbbf03 100644
--- a/eval.c
+++ b/eval.c
@@ -4600,7 +4600,8 @@ static val me_pop_after_load(val form, val menv)
void run_load_hooks(val load_dyn_env)
{
- val hooks_binding = lookup_var(load_dyn_env, load_hooks_s);
+ val saved_de = set_dyn_env(load_dyn_env);
+ val hooks_binding = lookup_var(nil, load_hooks_s);
val hooks = cdr(hooks_binding);
if (hooks) {
@@ -4608,6 +4609,8 @@ void run_load_hooks(val load_dyn_env)
funcall(car(hooks));
rplacd(hooks_binding, nil);
}
+
+ set_dyn_env(saved_de);
}
static void run_load_hooks_atexit(void)
diff --git a/txr.1 b/txr.1
index 2b657a4c..d1dfa23e 100644
--- a/txr.1
+++ b/txr.1
@@ -74594,19 +74594,14 @@ situation, the
variable which is accessed is that binding which was established by that
invocation of
.codn load .
-However, the functions are invoked in a dynamic environment in which that
-binding of the variable has already been removed. When the processing of
+The execution of the functions from the
.code *load-hooks*
-takes place due to the termination of
-.codn load ,
-all of the dynamic bindings established by that invocation of
-.code load
-have already been removed. Therefore, the
-.code *load-hooks*
-binding which is visible to these functions is whichever binding had been
-shadowed by the
+list takes place in the dynamic environment of the
+.codn load :
+all of the dynamic variable bindings established by that
.code load
-function.
+are still visible, including that of
+.codn *load-hooks* .
The
.code *load-hooks*
@@ -74614,20 +74609,18 @@ list is also processed after processing a \*(TX or \*(TL file that
is specified on the command line. If the interactive listener is
also being entered, this processing of
.code *load-hooks*
-occurs prior to entering the listener. In this situation, the top-level
-binding of
+occurs prior to entering the listener. This situation occurs in the
+context of the top-level dynamic environment, and so the global value of
.code *load-hooks*
-is used, and therefore that same binding is visible to the invoked
-functions.
+is referenced.
Lastly,
.code *load-hooks*
is also processed if the \*(TX process terminates normally, regardless
-of its exit status. In this situation, the current dynamic value of the
+of its exit status. This processing executes in whatever dynamic
+environment is current at the point of exit, using its value of the
.code *load-hooks*
-variable is used, from the dynamic environment as it exists at the
-time of exit, and that same environment is in effect over the execution
-of the functions. It is unspecified whether, at exit time, the
+variable is used. It is unspecified whether, at exit time, the
.code *load-hooks*
functions are executed first, or whether the functions registered by
.code at-exit-call