diff options
author | Florian Klink <flokli@flokli.de> | 2024-01-16T12·19+0200 |
---|---|---|
committer | flokli <flokli@flokli.de> | 2024-01-18T09·09+0000 |
commit | e0a867cabff021348cc283b25467cfd40b8eb15a (patch) | |
tree | 9b4f1fd63460ba8385b38259481a7bb32363801b /tvix/eval/src/vm | |
parent | 44d24852c3c62320cb2a4c9b9627e744c518f207 (diff) |
refactor(tvix/eval): generalize EvalIO container r/7407
Don't restrict to a Box<dyn EvalIO>. There's still one or two places where we do restrict, this will be solved by b/262. Change-Id: Ic8d927d6ea81fa12d90b1e4352f35ffaafbd1adf Reviewed-on: https://cl.tvl.fyi/c/depot/+/10639 Tested-by: BuildkiteCI Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Diffstat (limited to 'tvix/eval/src/vm')
-rw-r--r-- | tvix/eval/src/vm/generators.rs | 9 | ||||
-rw-r--r-- | tvix/eval/src/vm/mod.rs | 39 |
2 files changed, 32 insertions, 16 deletions
diff --git a/tvix/eval/src/vm/generators.rs b/tvix/eval/src/vm/generators.rs index f2ce73a0c742..3d2fd9d266c7 100644 --- a/tvix/eval/src/vm/generators.rs +++ b/tvix/eval/src/vm/generators.rs @@ -224,7 +224,10 @@ pub fn pin_generator( Box::pin(f) } -impl<'o> VM<'o> { +impl<'o, IO> VM<'o, IO> +where + IO: AsRef<dyn EvalIO> + 'static, +{ /// Helper function to re-enqueue the current generator while it /// is awaiting a value. fn reenqueue_generator(&mut self, name: &'static str, span: LightSpan, generator: Generator) { @@ -411,6 +414,7 @@ impl<'o> VM<'o> { VMRequest::PathImport(path) => { let imported = self .io_handle + .as_ref() .import_path(&path) .map_err(|e| ErrorKind::IO { path: Some(path), @@ -424,6 +428,7 @@ impl<'o> VM<'o> { VMRequest::ReadToString(path) => { let content = self .io_handle + .as_ref() .read_to_string(&path) .map_err(|e| ErrorKind::IO { path: Some(path), @@ -437,6 +442,7 @@ impl<'o> VM<'o> { VMRequest::PathExists(path) => { let exists = self .io_handle + .as_ref() .path_exists(&path) .map_err(|e| ErrorKind::IO { path: Some(path), @@ -451,6 +457,7 @@ impl<'o> VM<'o> { VMRequest::ReadDir(path) => { let dir = self .io_handle + .as_ref() .read_dir(&path) .map_err(|e| ErrorKind::IO { path: Some(path), diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs index 398a02cc78c8..5238fdc0662f 100644 --- a/tvix/eval/src/vm/mod.rs +++ b/tvix/eval/src/vm/mod.rs @@ -48,7 +48,7 @@ trait GetSpan { fn get_span(self) -> Span; } -impl<'o> GetSpan for &VM<'o> { +impl<'o, IO> GetSpan for &VM<'o, IO> { fn get_span(self) -> Span { self.reasonable_span.span() } @@ -75,12 +75,12 @@ impl GetSpan for Span { /// Internal helper trait for ergonomically converting from a `Result<T, /// ErrorKind>` to a `Result<T, Error>` using the current span of a call frame, /// and chaining the VM's frame stack around it for printing a cause chain. -trait WithSpan<T, S: GetSpan> { - fn with_span(self, top_span: S, vm: &VM) -> Result<T, Error>; +trait WithSpan<T, S: GetSpan, IO> { + fn with_span(self, top_span: S, vm: &VM<IO>) -> Result<T, Error>; } -impl<T, S: GetSpan> WithSpan<T, S> for Result<T, ErrorKind> { - fn with_span(self, top_span: S, vm: &VM) -> Result<T, Error> { +impl<T, S: GetSpan, IO> WithSpan<T, S, IO> for Result<T, ErrorKind> { + fn with_span(self, top_span: S, vm: &VM<IO>) -> Result<T, Error> { match self { Ok(something) => Ok(something), Err(kind) => { @@ -149,7 +149,7 @@ impl CallFrame { /// Construct an error result from the given ErrorKind and the source span /// of the current instruction. - pub fn error<T>(&self, vm: &VM, kind: ErrorKind) -> Result<T, Error> { + pub fn error<T, IO>(&self, vm: &VM<IO>, kind: ErrorKind) -> Result<T, Error> { Err(kind).with_span(self, vm) } @@ -249,7 +249,7 @@ impl ImportCache { } } -struct VM<'o> { +struct VM<'o, IO> { /// VM's frame stack, representing the execution contexts the VM is working /// through. Elements are usually pushed when functions are called, or /// thunks are being forced. @@ -280,7 +280,7 @@ struct VM<'o> { /// Implementation of I/O operations used for impure builtins and /// features like `import`. - io_handle: Box<dyn EvalIO>, + io_handle: IO, /// Runtime observer which can print traces of runtime operations. observer: &'o mut dyn RuntimeObserver, @@ -324,10 +324,13 @@ struct VM<'o> { try_eval_frames: Vec<usize>, } -impl<'o> VM<'o> { +impl<'o, IO> VM<'o, IO> +where + IO: AsRef<dyn EvalIO> + 'static, +{ pub fn new( nix_search_path: NixSearchPath, - io_handle: Box<dyn EvalIO>, + io_handle: IO, observer: &'o mut dyn RuntimeObserver, globals: Rc<GlobalsMap>, reasonable_span: LightSpan, @@ -858,7 +861,7 @@ impl<'o> VM<'o> { Value::UnresolvedPath(path) => { let resolved = self .nix_search_path - .resolve(&mut *self.io_handle, *path) + .resolve(&self.io_handle, *path) .with_span(&frame, self)?; self.stack.push(resolved.into()); } @@ -914,7 +917,10 @@ impl<'o> VM<'o> { } /// Implementation of helper functions for the runtime logic above. -impl<'o> VM<'o> { +impl<'o, IO> VM<'o, IO> +where + IO: AsRef<dyn EvalIO> + 'static, +{ pub(crate) fn stack_pop(&mut self) -> Value { self.stack.pop().expect("runtime stack empty") } @@ -1301,14 +1307,17 @@ async fn final_deep_force(co: GenCo) -> Result<Value, ErrorKind> { Ok(generators::request_deep_force(&co, value).await) } -pub fn run_lambda( +pub fn run_lambda<IO>( nix_search_path: NixSearchPath, - io_handle: Box<dyn EvalIO>, + io_handle: IO, observer: &mut dyn RuntimeObserver, globals: Rc<GlobalsMap>, lambda: Rc<Lambda>, strict: bool, -) -> EvalResult<RuntimeResult> { +) -> EvalResult<RuntimeResult> +where + IO: AsRef<dyn EvalIO> + 'static, +{ // Retain the top-level span of the expression in this lambda, as // synthetic "calls" in deep_force will otherwise not have a span // to fall back to. |