Skip to content

Commit

Permalink
workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Jun 25, 2024
1 parent b340773 commit 14bc9f3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
40 changes: 40 additions & 0 deletions crates/libs/strings/src/heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use super::*;
use core::ffi::c_void;

/// Allocate memory of size `bytes` using `HeapAlloc`.
pub fn heap_alloc(bytes: usize) -> crate::Result<*mut c_void> {
#[cfg(windows)]
let ptr: *mut c_void = unsafe { bindings::HeapAlloc(bindings::GetProcessHeap(), 0, bytes) };

#[cfg(not(windows))]
let ptr: *mut c_void = unsafe {
extern "C" {
fn malloc(bytes: usize) -> *mut c_void;
}

malloc(bytes)
};

if ptr.is_null() {
Err(Error::from_hresult(HRESULT(bindings::E_OUTOFMEMORY)))
} else {
Ok(ptr)
}
}

/// Free memory allocated by `heap_alloc`.
pub unsafe fn heap_free(ptr: *mut c_void) {
#[cfg(windows)]
{
bindings::HeapFree(bindings::GetProcessHeap(), 0, ptr);
}

#[cfg(not(windows))]
{
extern "C" {
fn free(ptr: *mut c_void);
}

free(ptr);
}
}
16 changes: 5 additions & 11 deletions crates/libs/strings/src/hstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ impl Clone for HSTRING {
}

impl Drop for HSTRING {
#[inline]
fn drop(&mut self) {
if self.is_empty() {
return;
Expand All @@ -116,7 +115,7 @@ impl Drop for HSTRING {
unsafe {
let header = header.as_ref();
if header.flags & REFERENCE_FLAG == 0 && header.count.release() == 0 {
bindings::HeapFree(bindings::GetProcessHeap(), 0, header as *const _ as *mut _);
heap_free(header as *const _ as *mut _);
}
}
}
Expand Down Expand Up @@ -423,28 +422,23 @@ struct Header {
}

impl Header {
#[inline]
fn alloc(len: u32) -> Result<*mut Header> {
debug_assert!(len != 0);
// Allocate enough space for header and two bytes per character.
// The space for the terminating null character is already accounted for inside of `Header`.
let alloc_size = core::mem::size_of::<Header>() + 2 * len as usize;

unsafe {
let header =
bindings::HeapAlloc(bindings::GetProcessHeap(), 0, alloc_size) as *mut Header;

if header.is_null() {
return Err(Error::from_hresult(HRESULT(bindings::E_OUTOFMEMORY)));
}
let header = heap_alloc(alloc_size)? as *mut Header;

unsafe {
// Use `ptr::write` (since `header` is unintialized). `Header` is safe to be all zeros.
header.write(core::mem::MaybeUninit::<Header>::zeroed().assume_init());
(*header).len = len;
(*header).count = RefCount::new(1);
(*header).data = &mut (*header).buffer_start;
Ok(header)
}

Ok(header)
}

fn duplicate(&self) -> Result<*mut Header> {
Expand Down
3 changes: 3 additions & 0 deletions crates/libs/strings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ use decode::*;
mod ref_count;
use ref_count::*;

mod heap;
use heap::*;

mod literals;
pub use literals::*;

Expand Down

0 comments on commit 14bc9f3

Please sign in to comment.