diff options
author | Vincent Ambo <mail@tazj.in> | 2022-09-04T19·34+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-09T21·14+0000 |
commit | 6deaa0d6cef081ea9399918611ba57142f7255b5 (patch) | |
tree | ee8e90a0d47df636e54ccd135803e787058f8e0d /tvix/eval/src | |
parent | 0aeca647777d2f17e40290e76c37e993e23c64ce (diff) |
fix(tvix/eval): force value passed to builtins.toString r/4782
This introduces a macro to do the forcing, but this solution isn't very nice and also does not work in all cases yet. Change-Id: Icd18862ec47edb82c0efc3af5835a6cb6126f629 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6456 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src')
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 28 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 2 |
2 files changed, 26 insertions, 4 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 947854e6f00a..1fe5d4a83eb1 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -15,6 +15,27 @@ use crate::{ use crate::arithmetic_op; +/// Helper macro to ensure that a value has been forced. The structure +/// of this is a little cumbersome as there are different reference +/// types depending on whether the value is inside a thunk or not. +macro_rules! force { + ( $vm:ident, $src:expr, $value:ident, $body:block ) => { + if let Value::Thunk(thunk) = $src { + thunk.force($vm)?; + let guard = thunk.value(); + let $value: &Value = &guard; + $body + } else { + let $value: &Value = $src; + $body + } + }; + + ( $vm:ident, $value:ident, $body:block ) => { + force!($vm, &$value, $value, $body) + }; +} + fn pure_builtins() -> Vec<Builtin> { vec![ Builtin::new("add", 2, |mut args, _| { @@ -96,9 +117,10 @@ fn pure_builtins() -> Vec<Builtin> { args.pop().unwrap().to_str()?.as_str().to_owned(), )); }), - Builtin::new("toString", 1, |args, _| { - // TODO: toString is actually not the same as Display - Ok(Value::String(format!("{}", args[0]).into())) + Builtin::new("toString", 1, |args, vm| { + force!(vm, &args[0], value, { + Ok(Value::String(format!("{}", value).into())) + }) }), Builtin::new("typeOf", 1, |args, _| { Ok(Value::String(args[0].type_of().into())) diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 73a03263c864..b65a37582f43 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -66,7 +66,7 @@ macro_rules! arithmetic_op { $self.push(result); }}; - ( $a:ident, $b:ident, $op:tt ) => {{ + ( $a:expr, $b:expr, $op:tt ) => {{ match ($a, $b) { (Value::Integer(i1), Value::Integer(i2)) => Ok(Value::Integer(i1 $op i2)), (Value::Float(f1), Value::Float(f2)) => Ok(Value::Float(f1 $op f2)), |