From 5e7a4907ec8f8a4fc6c08fc4f5432ff132338399 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Thu, 25 Jun 2026 12:56:41 +0200 Subject: [PATCH] Add allocator functions to c-api --- .cspell.dict/cpython.txt | 1 + Cargo.lock | 1 + crates/capi/Cargo.toml | 1 + crates/capi/src/lib.rs | 1 + crates/capi/src/pymem.rs | 46 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 crates/capi/src/pymem.rs diff --git a/.cspell.dict/cpython.txt b/.cspell.dict/cpython.txt index 84265bda609..e5b31b57f15 100644 --- a/.cspell.dict/cpython.txt +++ b/.cspell.dict/cpython.txt @@ -192,6 +192,7 @@ pyerrors Pyfunc pylifecycle pymain +pymem pyrepl pystate PYTHONTRACEMALLOC diff --git a/Cargo.lock b/Cargo.lock index 743e293f161..bd10622e601 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3447,6 +3447,7 @@ version = "0.5.0" dependencies = [ "bitflags 2.13.0", "itertools 0.14.0", + "libc", "num-complex", "pyo3", "rustpython-pylib", diff --git a/crates/capi/Cargo.toml b/crates/capi/Cargo.toml index 601989faa1d..878620ebe23 100644 --- a/crates/capi/Cargo.toml +++ b/crates/capi/Cargo.toml @@ -14,6 +14,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] bitflags = { workspace = true } itertools = { workspace = true } +libc = { workspace = true } num-complex = { workspace = true } rustpython-vm = { workspace = true, features = ["threading", "compiler", "importlib", "host_env"] } rustpython-stdlib = {workspace = true, features = ["threading"] } diff --git a/crates/capi/src/lib.rs b/crates/capi/src/lib.rs index fb3bc687f4d..638a78d6327 100644 --- a/crates/capi/src/lib.rs +++ b/crates/capi/src/lib.rs @@ -26,6 +26,7 @@ pub mod object; pub mod pycapsule; pub mod pyerrors; pub mod pylifecycle; +pub mod pymem; pub mod pystate; pub mod refcount; pub mod setobject; diff --git a/crates/capi/src/pymem.rs b/crates/capi/src/pymem.rs new file mode 100644 index 00000000000..6c8b66f5d3e --- /dev/null +++ b/crates/capi/src/pymem.rs @@ -0,0 +1,46 @@ +use core::ffi::c_void; + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_Malloc(n: usize) -> *mut c_void { + unsafe { libc::malloc(if n == 0 { 1 } else { n }) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_Calloc(nelem: usize, elsize: usize) -> *mut c_void { + unsafe { + libc::calloc( + if nelem == 0 || elsize == 0 { 1 } else { nelem }, + if nelem == 0 || elsize == 0 { 1 } else { elsize }, + ) + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_Realloc(ptr: *mut c_void, new_size: usize) -> *mut c_void { + unsafe { libc::realloc(ptr, if new_size == 0 { 1 } else { new_size }) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_Free(ptr: *mut c_void) { + unsafe { libc::free(ptr) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_RawMalloc(n: usize) -> *mut c_void { + unsafe { libc::malloc(n) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_RawCalloc(nelem: usize, elsize: usize) -> *mut c_void { + unsafe { libc::calloc(nelem, elsize) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_RawRealloc(ptr: *mut c_void, new_size: usize) -> *mut c_void { + unsafe { libc::realloc(ptr, new_size) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyMem_RawFree(ptr: *mut c_void) { + unsafe { libc::free(ptr) } +}