runestick/
vm_call.rs

1use crate::{Call, Future, Generator, Stream, Value, Vm, VmError, VmExecution};
2
3/// An instruction to push a virtual machine to the execution.
4#[derive(Debug)]
5pub struct VmCall {
6    pub(crate) call: Call,
7    pub(crate) vm: Vm,
8}
9
10impl VmCall {
11    /// Construct a new nested vm call.
12    pub(crate) fn new(call: Call, vm: Vm) -> Self {
13        Self { call, vm }
14    }
15
16    /// Encode the push itno an execution.
17    pub(crate) fn into_execution(self, execution: &mut VmExecution) -> Result<(), VmError> {
18        let value = match self.call {
19            Call::Async => Value::from(Future::new(self.vm.async_complete())),
20            Call::Stream => Value::from(Stream::new(self.vm)),
21            Call::Generator => Value::from(Generator::new(self.vm)),
22            Call::Immediate => {
23                execution.push_vm(self.vm);
24                return Ok(());
25            }
26        };
27
28        let vm = execution.vm_mut()?;
29        vm.stack_mut().push(value);
30        vm.advance();
31        Ok(())
32    }
33}