From 8e122574c238ec18644fbe49d18a8d204fff66e0 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 11 Oct 2022 02:18:14 +0300 Subject: fix(tvix/eval): implement functor calling for non-tail-calls Change-Id: I1113921c46010021b61c412d74d60193c156e0f1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6937 Reviewed-by: grfn Autosubmit: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/vm.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tvix') diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index c805b70218c0..9a8d07ea63eb 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -227,6 +227,21 @@ impl<'o> VM<'o> { Value::Thunk(t) => self.call_value(&t.value()), + // Attribute sets with a __functor attribute are callable. + Value::Attrs(ref attrs) => match attrs.select("__functor") { + None => Err(self.error(ErrorKind::NotCallable(callable.type_of()))), + Some(functor) => { + // The functor receives the set itself as its first argument + // and needs to be called with it. However, this call is + // synthetic (i.e. there is no corresponding OpCall for the + // first call in the bytecode.) + self.push(callable.clone()); + self.call_value(functor)?; + let primed = self.pop(); + self.call_value(&primed) + } + }, + // TODO: this isn't guaranteed to be a useful span, actually other => Err(self.error(ErrorKind::NotCallable(other.type_of()))), } -- cgit 1.4.1