linera_witty/runtime/
traits.rs1use std::ops::{Deref, DerefMut};
7
8use frunk::HList;
9
10use super::{memory::Memory, RuntimeError};
11use crate::memory_layout::FlatLayout;
12
13pub trait Runtime: Sized {
17    type Export;
19
20    type Memory;
22}
23
24pub trait Instance: Sized {
26    type Runtime: Runtime;
28
29    type UserData;
31
32    type UserDataReference<'a>: Deref<Target = Self::UserData>
34    where
35        Self::UserData: 'a,
36        Self: 'a;
37
38    type UserDataMutReference<'a>: DerefMut<Target = Self::UserData>
40    where
41        Self::UserData: 'a,
42        Self: 'a;
43
44    fn load_export(&mut self, name: &str) -> Option<<Self::Runtime as Runtime>::Export>;
46
47    fn user_data(&self) -> Self::UserDataReference<'_>;
49
50    fn user_data_mut(&mut self) -> Self::UserDataMutReference<'_>;
52}
53
54pub trait InstanceWithFunction<Parameters, Results>: Instance
56where
57    Parameters: FlatLayout,
58    Results: FlatLayout,
59{
60    type Function;
62
63    fn function_from_export(
65        &mut self,
66        export: <Self::Runtime as Runtime>::Export,
67    ) -> Result<Option<Self::Function>, RuntimeError>;
68
69    fn call(
71        &mut self,
72        function: &Self::Function,
73        parameters: Parameters,
74    ) -> Result<Results, RuntimeError>;
75
76    fn load_function(&mut self, name: &str) -> Result<Self::Function, RuntimeError> {
78        let export = self
79            .load_export(name)
80            .ok_or_else(|| RuntimeError::FunctionNotFound(name.to_string()))?;
81
82        self.function_from_export(export)?
83            .ok_or_else(|| RuntimeError::NotAFunction(name.to_string()))
84    }
85}
86
87pub trait CabiReallocAlias: InstanceWithFunction<HList![i32, i32, i32, i32], HList![i32]> {}
89
90impl<AnyInstance> CabiReallocAlias for AnyInstance where
91    AnyInstance: InstanceWithFunction<HList![i32, i32, i32, i32], HList![i32]>
92{
93}
94
95pub trait CabiFreeAlias: InstanceWithFunction<HList![i32], HList![]> {}
97
98impl<AnyInstance> CabiFreeAlias for AnyInstance where
99    AnyInstance: InstanceWithFunction<HList![i32], HList![]>
100{
101}
102
103pub trait InstanceWithMemory: CabiReallocAlias + CabiFreeAlias {
105    fn memory_from_export(
107        &self,
108        export: <Self::Runtime as Runtime>::Export,
109    ) -> Result<Option<<Self::Runtime as Runtime>::Memory>, RuntimeError>;
110
111    fn memory(&mut self) -> Result<Memory<'_, Self>, RuntimeError> {
113        let export = self
114            .load_export("memory")
115            .ok_or(RuntimeError::MissingMemory)?;
116
117        let memory = self
118            .memory_from_export(export)?
119            .ok_or(RuntimeError::NotMemory)?;
120
121        Ok(Memory::new(self, memory))
122    }
123}