diff options
author | edef <edef@edef.eu> | 2023-12-30T00·52+0000 |
---|---|---|
committer | edef <edef@edef.eu> | 2024-01-16T19·20+0000 |
commit | b624edb2ae0df67f9d70a031563b83a33bb282ef (patch) | |
tree | bbf4a6e05f56ee593f6fa70565a3eecdc3b76942 /tvix/eval/src/vm/macros.rs | |
parent | 5ac9450395bf88c0716914dd407a5d13e23b49ed (diff) |
fix(tvix/eval): lift VM ops over Catchable r/7395
We want to handle bottoms in a consistent fashion. Previously this was handled by repetitive is_catchable checks, which were not consistently present. Change-Id: I9614c479cc6297d1f64efba22b620a26e2a96802 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10485 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/vm/macros.rs')
-rw-r--r-- | tvix/eval/src/vm/macros.rs | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/tvix/eval/src/vm/macros.rs b/tvix/eval/src/vm/macros.rs index eb386df92fa3..fdb812961172 100644 --- a/tvix/eval/src/vm/macros.rs +++ b/tvix/eval/src/vm/macros.rs @@ -36,24 +36,25 @@ macro_rules! arithmetic_op { #[macro_export] macro_rules! cmp_op { ( $vm:ident, $frame:ident, $span:ident, $op:tt ) => {{ - let b = $vm.stack_pop(); - let a = $vm.stack_pop(); + lifted_pop! { + $vm(b, a) => { + async fn compare(a: Value, b: Value, co: GenCo) -> Result<Value, ErrorKind> { + let a = generators::request_force(&co, a).await; + let b = generators::request_force(&co, b).await; + let span = generators::request_span(&co).await; + let ordering = a.nix_cmp_ordering(b, co, span).await?; + match ordering { + Err(cek) => Ok(Value::Catchable(cek)), + Ok(ordering) => Ok(Value::Bool(cmp_op!(@order $op ordering))), + } + } - async fn compare(a: Value, b: Value, co: GenCo) -> Result<Value, ErrorKind> { - let a = generators::request_force(&co, a).await; - let b = generators::request_force(&co, b).await; - let span = generators::request_span(&co).await; - let ordering = a.nix_cmp_ordering(b, co, span).await?; - match ordering { - Err(cek) => Ok(Value::Catchable(cek)), - Ok(ordering) => Ok(Value::Bool(cmp_op!(@order $op ordering))), + let gen_span = $frame.current_light_span(); + $vm.push_call_frame($span, $frame); + $vm.enqueue_generator("compare", gen_span, |co| compare(a, b, co)); + return Ok(false); } } - - let gen_span = $frame.current_light_span(); - $vm.push_call_frame($span, $frame); - $vm.enqueue_generator("compare", gen_span, |co| compare(a, b, co)); - return Ok(false); }}; (@order < $ordering:expr) => { @@ -72,3 +73,21 @@ macro_rules! cmp_op { matches!($ordering, Ordering::Equal | Ordering::Greater) }; } + +#[macro_export] +macro_rules! lifted_pop { + ($vm:ident ($($bind:ident),+) => $body:expr) => { + { + $( + let $bind = $vm.stack_pop(); + )+ + $( + if $bind.is_catchable() { + $vm.stack.push($bind); + continue; + } + )+ + $body + } + } +} |