mirror of
https://git.proxmox.com/git/perlmod
synced 2025-10-05 16:40:23 +00:00
"fix" the destructor macro
long story short: compiler restrictions Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
6dd6718b6e
commit
aabc6479bb
@ -29,5 +29,8 @@ mod export {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
perlmod::destructor! { Bless : CLASSNAME }
|
#[export(name = "DESTROY")]
|
||||||
|
fn destroy(#[raw] this: Value) {
|
||||||
|
perlmod::destructor!(this, Bless : CLASSNAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
/// Create a standard destructor for a boxed type.
|
/// Create a standard destructor for a boxed type.
|
||||||
///
|
///
|
||||||
|
/// Due to compiler restrictions, the function itself needs to be written manually, only the
|
||||||
|
/// contents can be generated using this macro. This also means that the `this` parameter needs to
|
||||||
|
/// be passed to the macro.
|
||||||
|
///
|
||||||
/// For safety it is recommended to pass the package name to the macro in order for the generated
|
/// For safety it is recommended to pass the package name to the macro in order for the generated
|
||||||
/// code to also guard against values not blessed into the package.
|
/// code to also guard against values not blessed into the package.
|
||||||
///
|
///
|
||||||
@ -9,22 +13,34 @@
|
|||||||
///
|
///
|
||||||
/// Usage:
|
/// Usage:
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
|
/// #[export(name = "DESTROY")]
|
||||||
|
/// fn destroy(#[raw] this: Value) {
|
||||||
/// // complete:
|
/// // complete:
|
||||||
/// destructor!(MyType : "My::RS::Package" => {
|
/// destructor!(this, MyType : "My::RS::Package" => {
|
||||||
/// Err(err) => { eprintln!("DESTROY called with invalid pointer: {}", err); }
|
/// Err(err) => { eprintln!("DESTROY called with invalid pointer: {}", err); }
|
||||||
/// });
|
/// });
|
||||||
|
/// }
|
||||||
///
|
///
|
||||||
|
/// #[export(name = "DESTROY")]
|
||||||
|
/// fn destroy(#[raw] this: Value) {
|
||||||
/// // error case only
|
/// // error case only
|
||||||
/// destructor!(MyType {
|
/// destructor!(this, MyType {
|
||||||
/// Err(err) => { eprintln!("DESTROY called with invalid pointer: {}", err); }
|
/// Err(err) => { eprintln!("DESTROY called with invalid pointer: {}", err); }
|
||||||
/// });
|
/// });
|
||||||
|
/// }
|
||||||
///
|
///
|
||||||
|
/// #[export(name = "DESTROY")]
|
||||||
|
/// fn destroy(#[raw] this: Value) {
|
||||||
/// // simple case with default error case (which is the above example case)
|
/// // simple case with default error case (which is the above example case)
|
||||||
/// // the class name can also reference a constant.
|
/// // the class name can also reference a constant.
|
||||||
/// destructor!(MyType : CLASSNAME);
|
/// destructor!(this, MyType : CLASSNAME);
|
||||||
|
/// }
|
||||||
///
|
///
|
||||||
|
/// #[export(name = "DESTROY")]
|
||||||
|
/// fn destroy(#[raw] this: Value) {
|
||||||
/// // simple less-safe case without checking the reference type.
|
/// // simple less-safe case without checking the reference type.
|
||||||
/// destructor!(MyType);
|
/// destructor!(this, MyType);
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The generated code looks like this:
|
/// The generated code looks like this:
|
||||||
@ -45,9 +61,9 @@
|
|||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! destructor {
|
macro_rules! destructor {
|
||||||
($ty:ty : $package:expr) => {
|
($this:expr, $ty:ty : $package:expr) => {
|
||||||
$crate::destructor! {
|
$crate::destructor! {
|
||||||
$ty : $package => {
|
$this, $ty : $package => {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("DESTROY called with invalid pointer: {}", err);
|
eprintln!("DESTROY called with invalid pointer: {}", err);
|
||||||
}
|
}
|
||||||
@ -55,22 +71,20 @@ macro_rules! destructor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($ty:ty : $package:expr => {
|
($this:expr, $ty:ty : $package:expr => {
|
||||||
Err($errname:ident) => $on_err:expr
|
Err($errname:ident) => $on_err:expr
|
||||||
}) => {
|
}) => {
|
||||||
#[perlmod::export(name = "DESTROY")]
|
match unsafe { $this.from_blessed_box::<$ty>($package) } {
|
||||||
fn destroy(#[raw] this: Value) {
|
|
||||||
match unsafe { this.from_blessed_box::<$ty>($package) } {
|
|
||||||
Ok(ptr) => {
|
Ok(ptr) => {
|
||||||
let _ = unsafe { Box::<$ty>::from_raw(ptr as *const $ty as *mut $ty) };
|
let _ = unsafe { Box::<$ty>::from_raw(ptr as *const $ty as *mut $ty) };
|
||||||
}
|
}
|
||||||
Err($errname) => $on_err,
|
Err($errname) => $on_err,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
($ty:ty) => {
|
($this:expr, $ty:ty) => {
|
||||||
$crate::destructor! {
|
$crate::destructor! {
|
||||||
|
$this,
|
||||||
$ty {
|
$ty {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("DESTROY called with invalid pointer: {}", err);
|
eprintln!("DESTROY called with invalid pointer: {}", err);
|
||||||
@ -79,17 +93,14 @@ macro_rules! destructor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($ty:ty {
|
($this:expr, $ty:ty {
|
||||||
Err($name:ident) => $on_err:expr
|
Err($name:ident) => $on_err:expr
|
||||||
}) => {
|
}) => {
|
||||||
#[perlmod::export(name = "DESTROY")]
|
match unsafe { $this.from_ref_box::<$ty>() } {
|
||||||
fn destroy(#[raw] this: Value) {
|
|
||||||
match unsafe { this.from_ref_box::<$ty>() } {
|
|
||||||
Ok(ptr) => {
|
Ok(ptr) => {
|
||||||
let _ = unsafe { Box::<Bless>::from_raw(ptr) };
|
let _ = unsafe { Box::<Bless>::from_raw(ptr) };
|
||||||
}
|
}
|
||||||
Err($name) => $on_err,
|
Err($name) => $on_err,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user