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::session::SessionId;
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    /// Load a choreography image.
37    ///
38    /// # Errors
39    ///
40    /// Returns a `VMError` if limits are exceeded.
41    pub fn load_choreography(&mut self, image: &CodeImage) -> Result<SessionId, VMError> {
42        self.vm.load_choreography(image)
43    }
44
45    /// Execute one scheduler round via the kernel.
46    ///
47    /// # Errors
48    ///
49    /// Returns a `VMError` if a coroutine faults.
50    pub fn step_round(
51        &mut self,
52        handler: &dyn EffectHandler,
53        n: usize,
54    ) -> Result<StepResult, VMError> {
55        VMKernel::step_round(&mut self.vm, handler, n)
56    }
57
58    /// Run up to `max_rounds` with concurrency `n` via the kernel.
59    ///
60    /// # Errors
61    ///
62    /// Returns a `VMError` if a coroutine faults.
63    pub fn run(
64        &mut self,
65        handler: &dyn EffectHandler,
66        max_rounds: usize,
67        n: usize,
68    ) -> Result<RunStatus, VMError> {
69        VMKernel::run_concurrent(&mut self.vm, handler, max_rounds, n)
70    }
71
72    /// Borrow the observable trace.
73    #[must_use]
74    pub fn trace(&self) -> &[ObsEvent] {
75        self.vm.trace()
76    }
77}