refactor(tvix/eval): return call frame result from VM::call

Previously, "calling" (setting up the VM run loop for executing a call
frame) and "running" (running this loop to completion) were separate
operations.

This was basically an attempt to avoid nesting `VM::run` invocations.
However, doing things this way introduced some tricky bugs for exiting
out of the call frames of thunks vs. builtins & closures.

For now, we unify the two operations and always return the value to
the caller directly. For now this makes calls a little less effective,
but it gives us a chance to nail down some other strange behaviours
and then re-optimise this afterwards.

To make sure we tackle this again further down I've added it to the
list of known possible optimisations.

Change-Id: I96828ab6a628136e0bac1bf03555faa4e6b74ece
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6415
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-09-02 21:49:11 +03:00 committed by tazjin
parent cc526a2c87
commit 2246a31e72
3 changed files with 38 additions and 14 deletions

View file

@ -84,9 +84,9 @@ impl Thunk {
if let ThunkRepr::Suspended { lambda, upvalues } =
std::mem::replace(&mut *thunk_mut, ThunkRepr::Blackhole)
{
vm.call(lambda, upvalues, 0);
*thunk_mut = ThunkRepr::Evaluated(
vm.run().map_err(|e| ErrorKind::ThunkForce(Box::new(e)))?,
vm.call(lambda, upvalues, 0)
.map_err(|e| ErrorKind::ThunkForce(Box::new(e)))?,
);
}
}