linera_wasmer/
function_env.rs1use std::{any::Any, fmt::Debug, marker::PhantomData};
2
3use crate::vm::VMFunctionEnvironment;
4
5use crate::store::{AsStoreMut, AsStoreRef, StoreHandle, StoreMut, StoreObjects, StoreRef};
6
7#[derive(Debug)]
8#[repr(transparent)]
9pub struct FunctionEnv<T> {
12 pub(crate) handle: StoreHandle<VMFunctionEnvironment>,
13 marker: PhantomData<T>,
14}
15
16impl<T: Any> FunctionEnv<T> {
17 pub fn new(store: &mut impl AsStoreMut, value: T) -> Self {
19 Self {
20 handle: StoreHandle::new(
21 store.as_store_mut().objects_mut(),
22 VMFunctionEnvironment::new(value),
23 ),
24 marker: PhantomData,
25 }
26 }
27
28 pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T {
30 self.handle
31 .get(store.as_store_ref().objects())
32 .as_ref()
33 .downcast_ref::<T>()
34 .unwrap()
35 }
36
37 #[allow(dead_code)] pub(crate) fn from_handle(handle: StoreHandle<VMFunctionEnvironment>) -> Self {
39 Self {
40 handle,
41 marker: PhantomData,
42 }
43 }
44
45 pub fn as_mut<'a>(&self, store: &'a mut impl AsStoreMut) -> &'a mut T {
47 self.handle
48 .get_mut(store.objects_mut())
49 .as_mut()
50 .downcast_mut::<T>()
51 .unwrap()
52 }
53
54 pub fn into_mut(self, store: &mut impl AsStoreMut) -> FunctionEnvMut<T> {
56 FunctionEnvMut {
57 store_mut: store.as_store_mut(),
58 func_env: self,
59 }
60 }
61}
62
63impl<T> PartialEq for FunctionEnv<T> {
64 fn eq(&self, other: &Self) -> bool {
65 self.handle == other.handle
66 }
67}
68
69impl<T> Eq for FunctionEnv<T> {}
70
71impl<T> std::hash::Hash for FunctionEnv<T> {
72 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
73 self.handle.hash(state);
74 self.marker.hash(state);
75 }
76}
77
78impl<T> Clone for FunctionEnv<T> {
79 fn clone(&self) -> Self {
80 Self {
81 handle: self.handle.clone(),
82 marker: self.marker,
83 }
84 }
85}
86
87pub struct FunctionEnvMut<'a, T: 'a> {
89 pub(crate) store_mut: StoreMut<'a>,
90 pub(crate) func_env: FunctionEnv<T>,
91}
92
93impl<'a, T: Debug + 'static> Debug for FunctionEnvMut<'a, T> {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 self.func_env.as_ref(&self.store_mut).fmt(f)
96 }
97}
98
99impl<T: 'static> FunctionEnvMut<'_, T> {
100 pub fn data(&self) -> &T {
102 self.func_env.as_ref(&self.store_mut)
103 }
104
105 pub fn data_mut(&mut self) -> &mut T {
107 self.func_env.as_mut(&mut self.store_mut)
108 }
109
110 pub fn as_ref(&self) -> FunctionEnv<T> {
112 self.func_env.clone()
113 }
114
115 pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
117 FunctionEnvMut {
118 store_mut: self.store_mut.as_store_mut(),
119 func_env: self.func_env.clone(),
120 }
121 }
122
123 pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut) {
125 let data = self.func_env.as_mut(&mut self.store_mut) as *mut T;
126 let data = unsafe { &mut *data };
131 (data, self.store_mut.as_store_mut())
132 }
133}
134
135impl<T> AsStoreRef for FunctionEnvMut<'_, T> {
136 fn as_store_ref(&self) -> StoreRef<'_> {
137 StoreRef {
138 inner: self.store_mut.inner,
139 }
140 }
141}
142
143impl<T> AsStoreMut for FunctionEnvMut<'_, T> {
144 fn as_store_mut(&mut self) -> StoreMut<'_> {
145 StoreMut {
146 inner: self.store_mut.inner,
147 }
148 }
149 #[inline]
150 fn objects_mut(&mut self) -> &mut StoreObjects {
151 &mut self.store_mut.inner.objects
152 }
153}