oasis_contract_sdk/
memory.rs

1//! Memory management.
2use std::marker::PhantomData;
3
4/// A region of memory managed on behalf of the host.
5///
6/// The host is responsible for deallocating the region by calling `deallocate`.
7#[repr(C)]
8pub struct HostRegion {
9    pub offset: u32,
10    pub length: u32,
11}
12
13impl HostRegion {
14    /// Creates a new host region from arguments.
15    ///
16    /// This does not yet transfer memory ownership from the host.
17    pub fn from_arg((offset, length): (u32, u32)) -> Self {
18        Self::from_args(offset, length)
19    }
20
21    /// Creates a new host region from arguments.
22    ///
23    /// This does not yet transfer memory ownership from the host.
24    pub fn from_args(offset: u32, length: u32) -> Self {
25        Self { offset, length }
26    }
27
28    /// Transfers ownership of memory to the host by constructing a host region.
29    pub fn from_vec(data: Vec<u8>) -> Self {
30        let data_ptr = data.as_ptr() as usize;
31        let data_len = data.len();
32        std::mem::forget(data);
33
34        HostRegion {
35            offset: data_ptr as u32,
36            length: data_len as u32,
37        }
38    }
39
40    /// Transfers ownership of memory from the host and returns the vector.
41    ///
42    /// # Safety
43    ///
44    /// This is safe as long as the region was constructed from valid arguments.
45    pub fn into_vec(self) -> Vec<u8> {
46        let ptr = self.offset as *mut u8;
47        assert!(!ptr.is_null());
48
49        unsafe { Vec::from_raw_parts(ptr, self.length as usize, self.length as usize) }
50    }
51
52    /// Returns a new region by dereferencing a pointer to the region.
53    ///
54    /// This does not yet transfer memory ownership from the host.
55    ///
56    /// # Safety
57    ///
58    /// This is safe as long as the pointer is a valid pointer to the region struct.
59    pub unsafe fn deref(arg: *const HostRegion) -> Self {
60        let hr = &*arg;
61        HostRegion {
62            offset: hr.offset,
63            length: hr.length,
64        }
65    }
66}
67
68/// Reference to a host region.
69pub struct HostRegionRef<'a> {
70    pub offset: u32,
71    pub length: u32,
72
73    _lifetime: PhantomData<&'a [u8]>,
74}
75
76impl<'a> HostRegionRef<'a> {
77    /// Creates a new host region from the given byte slice.
78    pub fn from_slice(data: &'a [u8]) -> Self {
79        Self {
80            offset: data.as_ptr() as u32,
81            length: data.len() as u32,
82            _lifetime: PhantomData,
83        }
84    }
85}
86
87/// Allocate memory on host's behalf.
88pub fn allocate_host(length: u32) -> u32 {
89    let data: Vec<u8> = Vec::with_capacity(length as usize);
90    let data_ptr = data.as_ptr() as usize;
91    std::mem::forget(data);
92    data_ptr as u32
93}
94
95/// Deallocate memory on host's behalf.
96pub fn deallocate_host(offset: u32, length: u32) {
97    HostRegion::from_args(offset, length).into_vec();
98}