Skip to main content

telltale_vm/driver/
single_thread.rs

1//! Native single-thread runtime driver.
2
3use crate::effect::EffectHandler;
4use crate::kernel::VMKernel;
5use crate::loader::CodeImage;
6use crate::owned::OwnedSession;
7use crate::vm::{ObsEvent, RunStatus, StepResult, VMConfig, VMError, VM};
8
9/// Native cooperative runtime driver backed by the canonical VM kernel.
10#[derive(Debug)]
11pub struct NativeSingleThreadDriver {
12    vm: VM,
13}
14
15impl NativeSingleThreadDriver {
16    /// Create a new driver from VM config.
17    #[must_use]
18    pub fn new(config: VMConfig) -> Self {
19        Self {
20            vm: VM::new(config),
21        }
22    }
23
24    /// Wrap an existing VM instance.
25    #[must_use]
26    pub fn with_vm(vm: VM) -> Self {
27        Self { vm }
28    }
29
30    /// Access the inner VM.
31    #[must_use]
32    pub fn vm(&self) -> &VM {
33        &self.vm
34    }
35
36    /// Preferred choreography open path that returns an ownership-bearing handle.
37    ///
38    /// # Errors
39    ///
40    /// Returns a `VMError` if the choreography cannot be loaded or claimed.
41    pub fn load_choreography_owned(
42        &mut self,
43        image: &CodeImage,
44        owner_id: impl Into<String>,
45    ) -> Result<OwnedSession, VMError> {
46        self.vm.load_choreography_owned(image, owner_id)
47    }
48
49    /// Execute one scheduler round via the kernel.
50    ///
51    /// # Errors
52    ///
53    /// Returns a `VMError` if a coroutine faults.
54    pub fn step_round(
55        &mut self,
56        handler: &dyn EffectHandler,
57        n: usize,
58    ) -> Result<StepResult, VMError> {
59        VMKernel::step_round(&mut self.vm, handler, n)
60    }
61
62    /// Run up to `max_rounds` with concurrency `n` via the kernel.
63    ///
64    /// # Errors
65    ///
66    /// Returns a `VMError` if a coroutine faults.
67    pub fn run(
68        &mut self,
69        handler: &dyn EffectHandler,
70        max_rounds: usize,
71        n: usize,
72    ) -> Result<RunStatus, VMError> {
73        VMKernel::run_concurrent(&mut self.vm, handler, max_rounds, n)
74    }
75
76    /// Borrow the observable trace.
77    #[must_use]
78    pub fn trace(&self) -> &[ObsEvent] {
79        self.vm.trace()
80    }
81}