Skip to main content

linera_witty/runtime/wasmer/
memory.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! How to access the memory of a Wasmer guest instance.
5
6use std::borrow::Cow;
7
8use wasmer::{Extern, Memory};
9
10use super::{
11    super::traits::InstanceWithMemory, EntrypointInstance, ReentrantInstance, WithEnvironment,
12};
13use crate::{GuestPointer, RuntimeError, RuntimeMemory};
14
15macro_rules! impl_memory_traits {
16    ($instance:ty) => {
17        impl<UserData: 'static> InstanceWithMemory for $instance {
18            fn memory_from_export(&self, export: Extern) -> Result<Option<Memory>, RuntimeError> {
19                Ok(match export {
20                    Extern::Memory(memory) => Some(memory),
21                    _ => None,
22                })
23            }
24
25            fn load_memory(&mut self) -> Result<Memory, RuntimeError> {
26                WithEnvironment::environment(self).memory()
27            }
28        }
29
30        impl<UserData: 'static> RuntimeMemory<$instance> for Memory {
31            fn read<'instance>(
32                &self,
33                instance: &'instance $instance,
34                location: GuestPointer,
35                length: u32,
36            ) -> Result<Cow<'instance, [u8]>, RuntimeError> {
37                let mut buffer = vec![0u8; length as usize];
38                let start = location.0 as u64;
39
40                self.view(instance).read(start, &mut buffer)?;
41
42                Ok(Cow::Owned(buffer))
43            }
44
45            fn write(
46                &mut self,
47                instance: &mut $instance,
48                location: GuestPointer,
49                bytes: &[u8],
50            ) -> Result<(), RuntimeError> {
51                let start = location.0 as u64;
52
53                self.view(&*instance).write(start, bytes)?;
54
55                Ok(())
56            }
57        }
58    };
59}
60
61impl_memory_traits!(EntrypointInstance<UserData>);
62impl_memory_traits!(ReentrantInstance<'_, UserData>);