Skip to main content

edlcodegen_core/
heap_pointer.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4extern crate alloc;
5
6use crate::{
7    edl_core_types::AbiError,
8    helpers::{allocate_memory, copy_slice_to_buffer, deallocate_memory},
9};
10use core::ffi::c_void;
11
12/// light weight smart pointer that owns memory using HeapAlloc and HeapFree
13/// as it's allocation and deallocation mechanisms.
14pub struct HeapPtr<T> {
15    ptr: *mut T,
16}
17
18impl<T> HeapPtr<T> {
19    pub fn new(size: usize) -> Self {
20        Self {
21            ptr: allocate_memory(size) as *mut T,
22        }
23    }
24
25    pub const fn from_raw(ptr: *mut T) -> Self {
26        Self { ptr }
27    }
28
29    pub fn from_slice(slice: &[T]) -> Result<Self, AbiError> {
30        let heap_ptr = Self::new(slice.len());
31        copy_slice_to_buffer(heap_ptr.as_mut_ptr() as *mut c_void, slice)?;
32        Ok(heap_ptr)
33    }
34
35    pub const fn as_ptr(&self) -> *const T {
36        self.ptr
37    }
38
39    pub const fn as_mut_ptr(&self) -> *mut T {
40        self.ptr
41    }
42
43    /// Consumes the wrapper and returns the raw pointer, skipping deallocation.
44    pub fn into_raw(self) -> *mut T {
45        let raw = self.ptr;
46        core::mem::forget(self);
47        raw
48    }
49
50    /// Returns `true` if the internal pointer is null.
51    pub const fn is_null(&self) -> bool {
52        self.ptr.is_null()
53    }
54}
55
56impl<T> Drop for HeapPtr<T> {
57    fn drop(&mut self) {
58        if self.is_null() {
59            return;
60        }
61
62        // TODO: Should figure out how we can Log somehow.
63        let _ = deallocate_memory(self.ptr as *mut c_void);
64    }
65}