Remove redundant tail call resolution

The `resolve_tail_calls` function is being called twice in some
execution paths, which is unnecessary and can lead to incorrect
behavior. This commit removes the redundant calls and simplifies the
execution flow.
This commit is contained in:
Michael Schimmel
2026-03-06 12:45:08 +01:00
parent 13dc6beb52
commit 1f5aefb216
2 changed files with 12 additions and 15 deletions
+6 -13
View File
@@ -497,11 +497,7 @@ impl Environment {
purity: Purity::Impure,
func: Rc::new(move |args| {
let mut vm = VM::new(global_values.clone());
let res = match vm.run_with_args(closure_obj.clone(), args) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error: {}", e),
};
match vm.resolve_tail_calls(&mut crate::ast::vm::NoOpObserver, Ok(res)) {
match vm.run_with_args(closure_obj.clone(), args) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error: {}", e),
}
@@ -519,21 +515,18 @@ impl Environment {
Err(e) => panic!("Myc Runtime Error: {}", e),
};
let mut final_res = res;
if let Value::Object(obj) = &final_res
if let Value::Object(obj) = &res
&& obj
.as_any()
.downcast_ref::<crate::ast::vm::Closure>()
.is_some()
{
final_res = match vm.run_with_args(obj.clone(), args) {
match vm.run_with_args(obj.clone(), args) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error (Closure): {}", e),
};
}
match vm.resolve_tail_calls(&mut crate::ast::vm::NoOpObserver, Ok(final_res)) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error: {}", e),
}
} else {
res
}
}),
})
+6 -2
View File
@@ -229,7 +229,9 @@ impl VM {
} else {
self.unpack(&closure.parameter_node, args, &mut 0)?;
}
self.eval(&closure.exec_node)
let result = self.eval(&closure.exec_node);
self.frames.pop();
self.resolve_tail_calls(&mut NoOpObserver, result)
}
pub fn run_with_args_observed<O: VMObserver>(
@@ -252,7 +254,9 @@ impl VM {
} else {
self.unpack(&closure.parameter_node, args, &mut 0)?;
}
self.eval_observed(observer, &closure.exec_node)
let result = self.eval_observed(observer, &closure.exec_node);
self.frames.pop();
self.resolve_tail_calls(observer, result)
}
pub fn run_with_observer<O: VMObserver>(