mirror of
https://git.proxmox.com/git/perlmod
synced 2025-10-19 18:55:02 +00:00
perlmod: add magic ffi and glue
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
62f3c1eb74
commit
6f26c2da30
@ -33,6 +33,46 @@ pub struct HE {
|
|||||||
_ffi: usize,
|
_ffi: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Raw perl MAGIC struct, we don't actually make its contents available.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct MAGIC {
|
||||||
|
_ffi: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MAGIC {
|
||||||
|
pub fn vtbl(&self) -> Option<&MGVTBL> {
|
||||||
|
unsafe { RSPL_MAGIC_virtual(self as *const MAGIC).as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ptr(&self) -> *const libc::c_char {
|
||||||
|
unsafe { RSPL_MAGIC_ptr(self as *const MAGIC) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> isize {
|
||||||
|
unsafe { RSPL_MAGIC_len(self as *const MAGIC) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct big enough to fit perl's MGVTBL struct. We don't make the contents available for now.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct MGVTBL {
|
||||||
|
_funptrs: [usize; 8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MGVTBL {
|
||||||
|
/// Create a new all-zeroes vtbl as perl docs suggest this is the safest way to
|
||||||
|
/// make sure what a `PERL_MAGIC_ext` magic actually means, as the ptr value
|
||||||
|
/// may be arbitrary.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This must not be deallocated as long as it is attached to a perl value, so best use this as
|
||||||
|
/// `const` variables, rather than dynamically allocating it.
|
||||||
|
pub const fn zero() -> Self {
|
||||||
|
Self { _funptrs: [0; 8] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// in our glue:
|
// in our glue:
|
||||||
#[link(name = "glue", kind = "static")]
|
#[link(name = "glue", kind = "static")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -129,6 +169,21 @@ extern "C" {
|
|||||||
|
|
||||||
//pub fn RSPL_SvFLAGS(sv: *mut SV) -> u32;
|
//pub fn RSPL_SvFLAGS(sv: *mut SV) -> u32;
|
||||||
pub fn RSPL_SvGETMAGIC(sv: *mut SV) -> bool;
|
pub fn RSPL_SvGETMAGIC(sv: *mut SV) -> bool;
|
||||||
|
|
||||||
|
pub fn RSPL_sv_magicext(
|
||||||
|
sv: *mut SV,
|
||||||
|
obj: *mut SV,
|
||||||
|
how: libc::c_int,
|
||||||
|
vtbl: Option<&MGVTBL>,
|
||||||
|
name: *const libc::c_char,
|
||||||
|
namelen: i32,
|
||||||
|
) -> *mut MAGIC;
|
||||||
|
pub fn RSPL_sv_unmagicext(sv: *mut SV, ty: libc::c_int, vtbl: Option<&MGVTBL>);
|
||||||
|
pub fn RSPL_mg_findext(sv: *const SV, ty: libc::c_int, vtbl: Option<&MGVTBL>) -> *const MAGIC;
|
||||||
|
pub fn RSPL_MAGIC_virtual(mg: *const MAGIC) -> *const MGVTBL;
|
||||||
|
pub fn RSPL_MAGIC_ptr(mg: *const MAGIC) -> *const libc::c_char;
|
||||||
|
pub fn RSPL_MAGIC_len(mg: *const MAGIC) -> isize;
|
||||||
|
pub fn RSPL_PERL_MAGIC_ext() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Argument marker for the stack.
|
/// Argument marker for the stack.
|
||||||
|
@ -377,6 +377,55 @@ extern void RSPL_SvGETMAGIC(SV *sv) {
|
|||||||
return SvGETMAGIC(sv);
|
return SvGETMAGIC(sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new all-zeroes vtbl as perl docs suggest this is the safest way to
|
||||||
|
/// make sure what a `PERL_MAGIC_ext` magic actually means, as the ptr value
|
||||||
|
/// may be arbitrary. So this function is actually used to allocate "tags".
|
||||||
|
extern MGVTBL* RSPL_mgvtbl_new() {
|
||||||
|
return calloc(1, sizeof(MGVTBL));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern MAGIC* RSPL_sv_magicext(
|
||||||
|
SV *sv,
|
||||||
|
SV *obj,
|
||||||
|
int how,
|
||||||
|
const MGVTBL *vtbl,
|
||||||
|
const char *name,
|
||||||
|
int32_t namelen)
|
||||||
|
{
|
||||||
|
return sv_magicext(sv, obj, how, vtbl, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern MAGIC* RSPL_mg_findext(const SV *sv, int ty, const MGVTBL *vtbl) {
|
||||||
|
return mg_findext(sv, ty, vtbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it's not completely clear to me whether we want to use mg_freeext or sv_unmagicext
|
||||||
|
extern void RSPL_mg_freeext(SV *sv, int ty, const MGVTBL *vtbl) {
|
||||||
|
return mg_freeext(sv, ty, vtbl);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
extern void RSPL_sv_unmagicext(SV *sv, int ty, MGVTBL *vtbl) {
|
||||||
|
// always returns 0 currently
|
||||||
|
sv_unmagicext(sv, ty, vtbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seems safer than depending on a `struct magic` declaration within rust code:
|
||||||
|
extern const MGVTBL* RSPL_MAGIC_virtual(const MAGIC* mg) {
|
||||||
|
return mg->mg_virtual;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const char* RSPL_MAGIC_ptr(const MAGIC* mg) {
|
||||||
|
return mg->mg_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern isize RSPL_MAGIC_len(const MAGIC* mg) {
|
||||||
|
return mg->mg_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int RSPL_PERL_MAGIC_ext() {
|
||||||
|
return PERL_MAGIC_ext;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These make are convoluted brainfarts:
|
These make are convoluted brainfarts:
|
||||||
SVt_NULL undef
|
SVt_NULL undef
|
||||||
|
Loading…
Reference in New Issue
Block a user