Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Palloc and PStr? #1855

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pgrx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub mod misc;
pub mod namespace;
pub mod nodes;
pub mod nullable;
pub mod palloc;
pub mod pg_catalog;
pub mod pgbox;
pub mod rel;
Expand Down
5 changes: 5 additions & 0 deletions pgrx/src/memcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,8 @@ mod nightly {
}
}
}
/// A type pallocated in a context.
pub struct InCx<'mcx, T>(T, PhantomData<MemCx<'mcx>>);

/// An "owning" palloc.
pub struct Palloc<'mcx, T>(T, &'mcx MemCx<'mcx>);
46 changes: 46 additions & 0 deletions pgrx/src/palloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::memcx::MemCx;
use core::ffi::{self, CStr};
use core::marker::PhantomData;
use core::mem;
use core::ptr::NonNull;

/// A CStr in a palloc
///
/// ABI-compatible with `*const ffi::c_char`
#[repr(transparent)]
pub struct PStr<'mcx>(NonNull<ffi::c_char>, PhantomData<&'mcx MemCx<'mcx>>);

impl<'mcx> PStr<'mcx> {
/// AKA [`mem::transmute`].
///
/// # Safety
///
/// By invoking this, you assert
/// - The pointee is data allocated via a Postgres memory context.
/// - `'this` does not outlive that memory context.
/// - The constraints of [`CStr::from_ptr`] apply, with a `\0`-terminated pointee
///
/// You are giving this a lifetime bounded by the called-with lifetime. There is no check to
/// validate your assertion, nor is there a check to validate the pointee is `\0`-terminated.
#[inline]
pub(crate) unsafe fn assume_ptr_lives_for<'this>(ptr: NonNull<ffi::c_char>) -> PStr<'this> {
// SAFETY: The caller is allowed to assign a lifetime to this fn, making it a kind of
// "lifetime transmutation", regardless of whether we transmute or use struct init.
unsafe { mem::transmute(ptr) }
}

/// Safely introduces a lifetime
///
/// # Safety
///
/// By calling this function, you assert:
/// - The pointee is data allocated via the referenced `MemCx<'mcx>`.
/// - The constraints of [`CStr::from_ptr`] apply, with a `\0`-terminated pointee
#[inline]
pub unsafe fn assume_ptr_in(ptr: NonNull<ffi::c_char>, _memcx: &MemCx<'mcx>) -> PStr<'mcx> {
PStr::assume_ptr_lives_for::<'mcx>(ptr)
}
}

/// A type allocated in a memory context.
pub struct Palloc<'mcx, T>(T, PhantomData<&'mcx MemCx<'mcx>>);
57 changes: 57 additions & 0 deletions spare_pstring_stuff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
enum Encoding {
Bytes,
Utf8,
}
/// Pallocated, extensible string, that does not assume an encoding.
///
/// Like StringInfo, but with less FFI.
/// Note that the 0-len str.
pub struct PString<'mcx> {
ptr: NonNull<ffi::c_char>,
mcx: &'mcx MemCx<'mcx>,
len: u32,
cap: u32,
}

impl<'mcx> PString<'mcx> {
pub fn new_in(mcx: &MemCx<'mcx>) -> PString<'mcx> {
todo!()
}

/// Into a pallocated string.
pub fn into_pstr(self) -> PStr<'mcx> {
PStr(self.ptr, PhantomData)
}
}


struct CloneIn();
struct IsRef();
struct IsPalloc();

trait AllocAs {}
impl AllocAs for CloneIn {
}
impl AllocAs for IsRef {
}
impl AllocAs for IsPalloc {
}

pub struct PStrBuilder<M, Alloc> {
memcx: M,
raw_ptr: Option<*mut ffi::c_char>,
alloc: Alloc,
}

/// Instead of a proliferation of "create this from so-and-so"
pub fn build_from(builder: PStrBuilder<MemCx<'mcx>>) -> PString<'mcx> {
todo!()
}

impl<M> PStrBuilder<M> {

}

impl<'mcx> PStrBuilder<MemCx<'mcx>> {

}
Loading