Fix argument type allocation

This commit is contained in:
Daniil Gentili 2023-11-24 21:48:26 +01:00
parent 465c905a9b
commit 86c9074470
4 changed files with 30 additions and 10 deletions

View File

@ -87,7 +87,7 @@ impl<'a> Arg<'a> {
{ {
self.zval self.zval
.as_mut() .as_mut()
.and_then(|zv| T::from_zval_mut(zv)) .and_then(|zv| T::from_zval_mut(zv.dereference_mut()))
.ok_or(self) .ok_or(self)
} }
@ -98,7 +98,9 @@ impl<'a> Arg<'a> {
where where
T: FromZvalMut<'a>, T: FromZvalMut<'a>,
{ {
self.zval.as_mut().and_then(|zv| T::from_zval_mut(zv)) self.zval
.as_mut()
.and_then(|zv| T::from_zval_mut(zv.dereference_mut()))
} }
/// Attempts to return a reference to the arguments internal Zval. /// Attempts to return a reference to the arguments internal Zval.

View File

@ -51,6 +51,25 @@ impl Zval {
} }
} }
/// Dereference the zval, if it is a reference.
pub fn dereference(&self) -> &Self {
return self.reference().or_else(|| self.indirect()).unwrap_or(self);
}
/// Dereference the zval mutable, if it is a reference.
pub fn dereference_mut(&mut self) -> &mut Self {
// TODO: probably more ZTS work is needed here
if self.is_reference() {
#[allow(clippy::unwrap_used)]
return self.reference_mut().unwrap();
}
if self.is_indirect() {
#[allow(clippy::unwrap_used)]
return self.indirect_mut().unwrap();
}
self
}
/// Returns the value of the zval if it is a long. /// Returns the value of the zval if it is a long.
pub fn long(&self) -> Option<ZendLong> { pub fn long(&self) -> Option<ZendLong> {
if self.is_long() { if self.is_long() {

View File

@ -1,7 +1,4 @@
use std::{ use std::{ffi::c_void, ptr};
ffi::{c_void, CString},
ptr,
};
use crate::{ use crate::{
ffi::{ ffi::{
@ -9,6 +6,7 @@ use crate::{
_ZEND_SEND_MODE_SHIFT, _ZEND_TYPE_NAME_BIT, _ZEND_TYPE_NULLABLE_BIT, _ZEND_SEND_MODE_SHIFT, _ZEND_TYPE_NAME_BIT, _ZEND_TYPE_NULLABLE_BIT,
}, },
flags::DataType, flags::DataType,
types::ZendStr,
}; };
/// Internal Zend type. /// Internal Zend type.
@ -82,7 +80,7 @@ impl ZendType {
allow_null: bool, allow_null: bool,
) -> Option<Self> { ) -> Option<Self> {
Some(Self { Some(Self {
ptr: CString::new(class_name).ok()?.into_raw() as *mut c_void, ptr: ZendStr::new(class_name, true).into_raw().as_ptr() as *mut c_void,
type_mask: _ZEND_TYPE_NAME_BIT type_mask: _ZEND_TYPE_NAME_BIT
| (if allow_null { | (if allow_null {
_ZEND_TYPE_NULLABLE_BIT _ZEND_TYPE_NULLABLE_BIT

View File

@ -35,12 +35,13 @@ pub fn try_catch<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> Result<R, Catch
/// PHP propose a try catch mechanism in C using setjmp and longjmp (bailout) /// PHP propose a try catch mechanism in C using setjmp and longjmp (bailout)
/// It store the arg of setjmp into the bailout field of the global executor /// It store the arg of setjmp into the bailout field of the global executor
/// If a bailout is triggered, the executor will jump to the setjmp and restore the previous setjmp /// If a bailout is triggered, the executor will jump to the setjmp and restore
/// the previous setjmp
/// ///
/// try_catch_first allow to use this mechanism /// try_catch_first allow to use this mechanism
/// ///
/// This functions differs from ['try_catch'] as it also initialize the bailout mechanism /// This functions differs from ['try_catch'] as it also initialize the bailout
/// for the first time /// mechanism for the first time
/// ///
/// # Returns /// # Returns
/// ///