about summary refs log tree commit diff
path: root/tvix/eval/src/vm
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/vm')
-rw-r--r--tvix/eval/src/vm/generators.rs64
-rw-r--r--tvix/eval/src/vm/macros.rs2
-rw-r--r--tvix/eval/src/vm/mod.rs74
3 files changed, 63 insertions, 77 deletions
diff --git a/tvix/eval/src/vm/generators.rs b/tvix/eval/src/vm/generators.rs
index dbf7703bf002..36b837dbee6e 100644
--- a/tvix/eval/src/vm/generators.rs
+++ b/tvix/eval/src/vm/generators.rs
@@ -81,7 +81,7 @@ pub enum VMRequest {
     EnterLambda {
         lambda: Rc<Lambda>,
         upvalues: Rc<Upvalues>,
-        light_span: LightSpan,
+        span: Span,
     },
 
     /// Emit a runtime warning (already containing a span) through the VM.
@@ -198,7 +198,7 @@ pub enum VMResponse {
     Directory(Vec<(bytes::Bytes, FileType)>),
 
     /// VM response with a span to use at the current point.
-    Span(LightSpan),
+    Span(Span),
 
     /// [std::io::Reader] produced by the VM in response to some IO operation.
     Reader(Box<dyn std::io::Read>),
@@ -234,7 +234,7 @@ where
 {
     /// 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) {
+    fn reenqueue_generator(&mut self, name: &'static str, span: Span, generator: Generator) {
         self.frames.push(Frame::Generator {
             name,
             generator,
@@ -244,7 +244,7 @@ where
     }
 
     /// Helper function to enqueue a new generator.
-    pub(super) fn enqueue_generator<F, G>(&mut self, name: &'static str, span: LightSpan, gen: G)
+    pub(super) fn enqueue_generator<F, G>(&mut self, name: &'static str, span: Span, gen: G)
     where
         F: Future<Output = Result<Value, ErrorKind>> + 'static,
         G: FnOnce(GenCo) -> F,
@@ -265,7 +265,7 @@ where
     pub(crate) fn run_generator(
         &mut self,
         name: &'static str,
-        span: LightSpan,
+        span: Span,
         frame_id: usize,
         state: GeneratorState,
         mut generator: Generator,
@@ -302,8 +302,8 @@ where
                         // this function prepares the frame stack and yields
                         // back to the outer VM loop.
                         VMRequest::ForceValue(value) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
-                            self.enqueue_generator("force", span.clone(), |co| {
+                            self.reenqueue_generator(name, span, generator);
+                            self.enqueue_generator("force", span, |co| {
                                 value.force_owned_genco(co, span)
                             });
                             return Ok(false);
@@ -311,8 +311,8 @@ where
 
                         // Generator has requested a deep-force.
                         VMRequest::DeepForceValue(value) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
-                            self.enqueue_generator("deep_force", span.clone(), |co| {
+                            self.reenqueue_generator(name, span, generator);
+                            self.enqueue_generator("deep_force", span, |co| {
                                 value.deep_force(co, span)
                             });
                             return Ok(false);
@@ -322,10 +322,10 @@ where
                         // Logic is similar to `ForceValue`, except with the
                         // value being taken from that stack.
                         VMRequest::WithValue(idx) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
+                            self.reenqueue_generator(name, span, generator);
 
                             let value = self.stack[self.with_stack[idx]].clone();
-                            self.enqueue_generator("force", span.clone(), |co| {
+                            self.enqueue_generator("force", span, |co| {
                                 value.force_owned_genco(co, span)
                             });
 
@@ -336,13 +336,13 @@ where
                         // with-stack. Logic is same as above, except for the
                         // value being from that stack.
                         VMRequest::CapturedWithValue(idx) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
+                            self.reenqueue_generator(name, span, generator);
 
                             let call_frame = self.last_call_frame()
                                 .expect("Tvix bug: generator requested captured with-value, but there is no call frame");
 
                             let value = call_frame.upvalues.with_stack().unwrap()[idx].clone();
-                            self.enqueue_generator("force", span.clone(), |co| {
+                            self.enqueue_generator("force", span, |co| {
                                 value.force_owned_genco(co, span)
                             });
 
@@ -351,23 +351,23 @@ where
 
                         VMRequest::NixEquality(values, ptr_eq) => {
                             let values = *values;
-                            self.reenqueue_generator(name, span.clone(), generator);
-                            self.enqueue_generator("nix_eq", span.clone(), |co| {
+                            self.reenqueue_generator(name, span, generator);
+                            self.enqueue_generator("nix_eq", span, |co| {
                                 values.0.nix_eq_owned_genco(values.1, co, ptr_eq, span)
                             });
                             return Ok(false);
                         }
 
                         VMRequest::StringCoerce(val, kind) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
-                            self.enqueue_generator("coerce_to_string", span.clone(), |co| {
+                            self.reenqueue_generator(name, span, generator);
+                            self.enqueue_generator("coerce_to_string", span, |co| {
                                 val.coerce_to_string(co, kind, span)
                             });
                             return Ok(false);
                         }
 
                         VMRequest::Call(callable) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
+                            self.reenqueue_generator(name, span, generator);
                             self.call_value(span, None, callable)?;
                             return Ok(false);
                         }
@@ -375,12 +375,12 @@ where
                         VMRequest::EnterLambda {
                             lambda,
                             upvalues,
-                            light_span,
+                            span,
                         } => {
                             self.reenqueue_generator(name, span, generator);
 
                             self.frames.push(Frame::CallFrame {
-                                span: light_span,
+                                span,
                                 call_frame: CallFrame {
                                     lambda,
                                     upvalues,
@@ -424,7 +424,7 @@ where
                                     path: Some(path),
                                     error: e.into(),
                                 })
-                                .with_span(&span, self)?;
+                                .with_span(span, self)?;
 
                             message = VMResponse::Path(imported);
                         }
@@ -438,7 +438,7 @@ where
                                     path: Some(path),
                                     error: e.into(),
                                 })
-                                .with_span(&span, self)?;
+                                .with_span(span, self)?;
 
                             message = VMResponse::Reader(reader)
                         }
@@ -453,7 +453,7 @@ where
                                     error: e.into(),
                                 })
                                 .map(Value::Bool)
-                                .with_span(&span, self)?;
+                                .with_span(span, self)?;
 
                             message = VMResponse::Value(exists);
                         }
@@ -467,31 +467,31 @@ where
                                     path: Some(path),
                                     error: e.into(),
                                 })
-                                .with_span(&span, self)?;
+                                .with_span(span, self)?;
                             message = VMResponse::Directory(dir);
                         }
 
                         VMRequest::Span => {
-                            message = VMResponse::Span(self.reasonable_light_span());
+                            message = VMResponse::Span(self.reasonable_span);
                         }
 
                         VMRequest::TryForce(value) => {
                             self.try_eval_frames.push(frame_id);
-                            self.reenqueue_generator(name, span.clone(), generator);
+                            self.reenqueue_generator(name, span, generator);
 
                             debug_assert!(
                                 self.frames.len() == frame_id + 1,
                                 "generator should be reenqueued with the same frame ID"
                             );
 
-                            self.enqueue_generator("force", span.clone(), |co| {
+                            self.enqueue_generator("force", span, |co| {
                                 value.force_owned_genco(co, span)
                             });
                             return Ok(false);
                         }
 
                         VMRequest::ToJson(value) => {
-                            self.reenqueue_generator(name, span.clone(), generator);
+                            self.reenqueue_generator(name, span, generator);
                             self.enqueue_generator("to_json", span, |co| {
                                 value.into_contextful_json_generator(co)
                             });
@@ -503,7 +503,7 @@ where
                 // Generator has completed, and its result value should
                 // be left on the stack.
                 genawaiter::GeneratorState::Complete(result) => {
-                    let value = result.with_span(&span, self)?;
+                    let value = result.with_span(span, self)?;
                     self.stack.push(value);
                     return Ok(true);
                 }
@@ -683,12 +683,12 @@ pub(crate) async fn request_enter_lambda(
     co: &GenCo,
     lambda: Rc<Lambda>,
     upvalues: Rc<Upvalues>,
-    light_span: LightSpan,
+    span: Span,
 ) -> Value {
     let msg = VMRequest::EnterLambda {
         lambda,
         upvalues,
-        light_span,
+        span,
     };
 
     match co.yield_(msg).await {
@@ -767,7 +767,7 @@ pub(crate) async fn request_read_dir(co: &GenCo, path: PathBuf) -> Vec<(bytes::B
     }
 }
 
-pub(crate) async fn request_span(co: &GenCo) -> LightSpan {
+pub(crate) async fn request_span(co: &GenCo) -> Span {
     match co.yield_(VMRequest::Span).await {
         VMResponse::Span(span) => span,
         msg => panic!(
diff --git a/tvix/eval/src/vm/macros.rs b/tvix/eval/src/vm/macros.rs
index d8a09706ab9c..f9c084d41f91 100644
--- a/tvix/eval/src/vm/macros.rs
+++ b/tvix/eval/src/vm/macros.rs
@@ -49,7 +49,7 @@ macro_rules! cmp_op {
                     }
                 }
 
-                let gen_span = $frame.current_light_span();
+                let gen_span = $frame.current_span();
                 $vm.push_call_frame($span, $frame);
                 $vm.enqueue_generator("compare", gen_span, |co| compare(a, b, co));
                 return Ok(false);
diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs
index 48dcdfc8df47..65117b79a0bc 100644
--- a/tvix/eval/src/vm/mod.rs
+++ b/tvix/eval/src/vm/mod.rs
@@ -28,7 +28,6 @@ use crate::{
     nix_search_path::NixSearchPath,
     observer::RuntimeObserver,
     opcode::{CodeIdx, Count, JumpOffset, OpCode, StackIdx, UpvalueIdx},
-    spans::LightSpan,
     upvalues::Upvalues,
     value::{
         Builtin, BuiltinResult, Closure, CoercionKind, Lambda, NixAttrs, NixContext, NixList,
@@ -51,7 +50,7 @@ trait GetSpan {
 
 impl<'o, IO> GetSpan for &VM<'o, IO> {
     fn get_span(self) -> Span {
-        self.reasonable_span.span()
+        self.reasonable_span
     }
 }
 
@@ -61,9 +60,9 @@ impl GetSpan for &CallFrame {
     }
 }
 
-impl GetSpan for &LightSpan {
+impl GetSpan for &Span {
     fn get_span(self) -> Span {
-        self.span()
+        *self
     }
 }
 
@@ -94,7 +93,7 @@ impl<T, S: GetSpan, IO> WithSpan<T, S, IO> for Result<T, ErrorKind> {
                         Frame::CallFrame { span, .. } => {
                             error = Error::new(
                                 ErrorKind::BytecodeError(Box::new(error)),
-                                span.span(),
+                                *span,
                                 vm.source.clone(),
                             );
                         }
@@ -104,7 +103,7 @@ impl<T, S: GetSpan, IO> WithSpan<T, S, IO> for Result<T, ErrorKind> {
                                     err: Box::new(error),
                                     gen_type: name,
                                 },
-                                span.span(),
+                                *span,
                                 vm.source.clone(),
                             );
                         }
@@ -163,13 +162,6 @@ impl CallFrame {
     pub fn current_span(&self) -> Span {
         self.chunk().get_span(self.ip - 1)
     }
-
-    /// Returns the information needed to calculate the current span,
-    /// but without performing that calculation.
-    // TODO: why pub?
-    pub(crate) fn current_light_span(&self) -> LightSpan {
-        LightSpan::new_actual(self.current_span())
-    }
 }
 
 /// A frame represents an execution state of the VM. The VM has a stack of
@@ -187,7 +179,7 @@ enum Frame {
         call_frame: CallFrame,
 
         /// Span from which the call frame was launched.
-        span: LightSpan,
+        span: Span,
     },
 
     /// Generator represents a frame that can yield further
@@ -201,7 +193,7 @@ enum Frame {
         name: &'static str,
 
         /// Span from which the generator was launched.
-        span: LightSpan,
+        span: Span,
 
         state: GeneratorState,
 
@@ -211,9 +203,9 @@ enum Frame {
 }
 
 impl Frame {
-    pub fn span(&self) -> LightSpan {
+    pub fn span(&self) -> Span {
         match self {
-            Frame::CallFrame { span, .. } | Frame::Generator { span, .. } => span.clone(),
+            Frame::CallFrame { span, .. } | Frame::Generator { span, .. } => *span,
         }
     }
 }
@@ -309,7 +301,7 @@ struct VM<'o, IO> {
     ///
     /// The VM should update this whenever control flow changes take place (i.e.
     /// entering or exiting a frame to yield control somewhere).
-    reasonable_span: LightSpan,
+    reasonable_span: Span,
 
     /// This field is responsible for handling `builtins.tryEval`. When that
     /// builtin is encountered, it sends a special message to the VM which
@@ -343,7 +335,7 @@ where
         observer: &'o mut dyn RuntimeObserver,
         source: SourceCode,
         globals: Rc<GlobalsMap>,
-        reasonable_span: LightSpan,
+        reasonable_span: Span,
     ) -> Self {
         Self {
             nix_search_path,
@@ -362,7 +354,7 @@ where
     }
 
     /// Push a call frame onto the frame stack.
-    fn push_call_frame(&mut self, span: LightSpan, call_frame: CallFrame) {
+    fn push_call_frame(&mut self, span: Span, call_frame: CallFrame) {
         self.frames.push(Frame::CallFrame { span, call_frame })
     }
 
@@ -444,7 +436,7 @@ where
     ///
     /// The return value indicates whether the bytecode has been executed to
     /// completion, or whether it has been suspended in favour of a generator.
-    fn execute_bytecode(&mut self, span: LightSpan, mut frame: CallFrame) -> EvalResult<bool> {
+    fn execute_bytecode(&mut self, span: Span, mut frame: CallFrame) -> EvalResult<bool> {
         loop {
             let op = frame.inc_ip();
             self.observer.observe_execute_op(frame.ip, &op, &self.stack);
@@ -464,7 +456,7 @@ where
                         );
                         Thunk::new_closure(blueprint)
                     } else {
-                        Thunk::new_suspended(blueprint, frame.current_light_span())
+                        Thunk::new_suspended(blueprint, frame.current_span())
                     };
                     let upvalues = thunk.upvalues_mut();
                     self.stack.push(Value::Thunk(thunk.clone()));
@@ -484,10 +476,10 @@ where
                             _ => unreachable!(),
                         };
 
-                        let gen_span = frame.current_light_span();
+                        let gen_span = frame.current_span();
 
                         self.push_call_frame(span, frame);
-                        self.enqueue_generator("force", gen_span.clone(), |co| {
+                        self.enqueue_generator("force", gen_span, |co| {
                             Thunk::force(thunk, co, gen_span)
                         });
 
@@ -515,7 +507,7 @@ where
 
                 OpCode::OpCall => {
                     let callable = self.stack_pop();
-                    self.call_value(frame.current_light_span(), Some((span, frame)), callable)?;
+                    self.call_value(frame.current_span(), Some((span, frame)), callable)?;
 
                     // exit this loop and let the outer loop enter the new call
                     return Ok(true);
@@ -640,9 +632,9 @@ where
 
                 OpCode::OpEqual => lifted_pop! {
                     self(b, a) => {
-                        let gen_span = frame.current_light_span();
+                        let gen_span = frame.current_span();
                         self.push_call_frame(span, frame);
-                        self.enqueue_generator("nix_eq", gen_span.clone(), |co| {
+                        self.enqueue_generator("nix_eq", gen_span, |co| {
                             a.nix_eq_owned_genco(b, co, PointerEquality::ForbidAll, gen_span)
                         });
                         return Ok(false);
@@ -739,7 +731,7 @@ where
                     let ident = self.stack_pop().to_str().with_span(&frame, self)?;
 
                     // Re-enqueue this frame.
-                    let op_span = frame.current_light_span();
+                    let op_span = frame.current_span();
                     self.push_call_frame(span, frame);
 
                     // Construct a generator frame doing the lookup in constant
@@ -770,10 +762,10 @@ where
 
                 OpCode::OpCoerceToString(kind) => {
                     let value = self.stack_pop();
-                    let gen_span = frame.current_light_span();
+                    let gen_span = frame.current_span();
                     self.push_call_frame(span, frame);
 
-                    self.enqueue_generator("coerce_to_string", gen_span.clone(), |co| {
+                    self.enqueue_generator("coerce_to_string", gen_span, |co| {
                         value.coerce_to_string(co, kind, gen_span)
                     });
 
@@ -808,7 +800,7 @@ where
 
                 OpCode::OpAdd => lifted_pop! {
                     self(b, a) => {
-                        let gen_span = frame.current_light_span();
+                        let gen_span = frame.current_span();
                         self.push_call_frame(span, frame);
 
                         // OpAdd can add not just numbers, but also string-like
@@ -1004,12 +996,6 @@ where
         Ok(())
     }
 
-    /// Returns a reasonable light span for the current situation that the VM is
-    /// in.
-    pub fn reasonable_light_span(&self) -> LightSpan {
-        self.reasonable_span.clone()
-    }
-
     /// Apply an argument from the stack to a builtin, and attempt to call it.
     ///
     /// All calls are tail-calls in Tvix, as every function application is a
@@ -1017,7 +1003,7 @@ where
     ///
     /// Due to this, once control flow exits this function, the generator will
     /// automatically be run by the VM.
-    fn call_builtin(&mut self, span: LightSpan, mut builtin: Builtin) -> EvalResult<()> {
+    fn call_builtin(&mut self, span: Span, mut builtin: Builtin) -> EvalResult<()> {
         let builtin_name = builtin.name();
         self.observer.observe_enter_builtin(builtin_name);
 
@@ -1041,8 +1027,8 @@ where
 
     fn call_value(
         &mut self,
-        span: LightSpan,
-        parent: Option<(LightSpan, CallFrame)>,
+        span: Span,
+        parent: Option<(Span, CallFrame)>,
         callable: Value,
     ) -> EvalResult<()> {
         match callable {
@@ -1098,7 +1084,7 @@ where
                 Ok(())
             }
 
-            v => Err(ErrorKind::NotCallable(v.type_of())).with_span(&span, self),
+            v => Err(ErrorKind::NotCallable(v.type_of())).with_span(span, self),
         }
     }
 
@@ -1345,17 +1331,17 @@ where
         observer,
         source,
         globals,
-        root_span.into(),
+        root_span,
     );
 
     // When evaluating strictly, synthesise a frame that will instruct
     // the VM to deep-force the final value before returning it.
     if strict {
-        vm.enqueue_generator("final_deep_force", root_span.into(), final_deep_force);
+        vm.enqueue_generator("final_deep_force", root_span, final_deep_force);
     }
 
     vm.frames.push(Frame::CallFrame {
-        span: root_span.into(),
+        span: root_span,
         call_frame: CallFrame {
             lambda,
             upvalues: Rc::new(Upvalues::with_capacity(0)),