From 59e695a9d907aba0db23fb6ac71acd80f7713cd0 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Fri, 9 Dec 2022 12:58:58 +0300 Subject: feat(tvix/eval): add observer configuration to public API With this change, it should be possible to have both existing use-cases (CLI & Tvixbolt) use the same API. Change-Id: I2195264f08cc892177b559a28660dc5f98e48e41 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7545 Autosubmit: tazjin Tested-by: BuildkiteCI Reviewed-by: grfn --- tvix/eval/src/lib.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'tvix') diff --git a/tvix/eval/src/lib.rs b/tvix/eval/src/lib.rs index c4c3e06901f4..aef6f5f06b2e 100644 --- a/tvix/eval/src/lib.rs +++ b/tvix/eval/src/lib.rs @@ -44,6 +44,7 @@ use std::sync::Arc; pub use crate::builtins::global_builtins; pub use crate::compiler::{compile, prepare_globals}; pub use crate::errors::{Error, ErrorKind, EvalResult}; +use crate::observer::{CompilerObserver, RuntimeObserver}; pub use crate::pretty_ast::pretty_print_expr; pub use crate::source::SourceCode; pub use crate::value::Value; @@ -69,10 +70,9 @@ pub(crate) fn unwrap_or_clone_rc(rc: Rc) -> T { /// /// Public fields are intended to be set by the caller. Setting all /// fields is optional. -#[derive(Clone)] -pub struct Evaluation<'a> { +pub struct Evaluation<'code, 'co, 'ro> { /// The Nix source code to be evaluated. - code: &'a str, + code: &'code str, /// Optional location of the source code (i.e. path to the file it was read /// from). Used for error reporting, and for resolving relative paths in @@ -91,6 +91,14 @@ pub struct Evaluation<'a> { /// (optional) Nix search path, e.g. the value of `NIX_PATH` used /// for resolving items on the search path (such as ``). pub nix_path: Option, + + /// (optional) compiler observer for reporting on compilation + /// details, like the emitted bytecode. + pub compiler_observer: Option<&'co mut dyn CompilerObserver>, + + /// (optional) runtime observer, for reporting on execution steps + /// of Nix code. + pub runtime_observer: Option<&'ro mut dyn RuntimeObserver>, } /// Result of evaluating a piece of Nix code. If evaluation succeeded, a value @@ -109,11 +117,11 @@ pub struct EvaluationResult { pub warnings: Vec, } -impl<'a> Evaluation<'a> { +impl<'code, 'co, 'ro> Evaluation<'code, 'co, 'ro> { /// Initialise an `Evaluation` for the given Nix source code snippet, and /// an optional code location. /// reporting the location of errors in the code. - pub fn new(code: &'a str, location: Option) -> Self { + pub fn new(code: &'code str, location: Option) -> Self { let source_map = SourceCode::new(); let location_str = location @@ -130,6 +138,8 @@ impl<'a> Evaluation<'a> { file, expr: None, nix_path: None, + compiler_observer: None, + runtime_observer: None, } } @@ -163,12 +173,15 @@ impl<'a> Evaluation<'a> { let builtins = crate::compiler::prepare_globals(Box::new(global_builtins(self.source_map()))); + let mut noop_observer = observer::NoOpObserver::default(); + let compiler_observer = self.compiler_observer.take().unwrap_or(&mut noop_observer); + let compiler_result = match compiler::compile( self.expr.as_ref().unwrap(), self.location.take(), self.file.clone(), builtins, - &mut observer::NoOpObserver::default(), // TODO: compilation observer + compiler_observer, ) { Ok(result) => result, Err(err) => { @@ -202,11 +215,8 @@ impl<'a> Evaluation<'a> { }) .unwrap_or_else(|| Default::default()); - let vm_result = run_lambda( - nix_path, - &mut observer::NoOpObserver::default(), // TODO: runtime observer - compiler_result.lambda, - ); + let runtime_observer = self.runtime_observer.take().unwrap_or(&mut noop_observer); + let vm_result = run_lambda(nix_path, runtime_observer, compiler_result.lambda); match vm_result { Ok(mut runtime_result) => { -- cgit 1.4.1