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}