From 6deaa0d6cef081ea9399918611ba57142f7255b5 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 4 Sep 2022 22:34:25 +0300 Subject: fix(tvix/eval): force value passed to builtins.toString 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 Tested-by: BuildkiteCI --- tvix/eval/src/builtins/mod.rs | 28 +++++++++++++++++++++++++--- tvix/eval/src/vm.rs | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'tvix') diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 947854e6f0..1fe5d4a83e 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 { vec![ Builtin::new("add", 2, |mut args, _| { @@ -96,9 +117,10 @@ fn pure_builtins() -> Vec { 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 73a03263c8..b65a37582f 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)), -- cgit 1.4.1