Skip to content

Commit b4b8acc

Browse files
authored
Merge pull request #292 from danog/fix-argument-type-allocation
Fix argument type allocation
2 parents 465c905 + 86c9074 commit b4b8acc

File tree

4 files changed

+30
-10
lines changed

4 files changed

+30
-10
lines changed

src/args.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<'a> Arg<'a> {
8787
{
8888
self.zval
8989
.as_mut()
90-
.and_then(|zv| T::from_zval_mut(zv))
90+
.and_then(|zv| T::from_zval_mut(zv.dereference_mut()))
9191
.ok_or(self)
9292
}
9393

@@ -98,7 +98,9 @@ impl<'a> Arg<'a> {
9898
where
9999
T: FromZvalMut<'a>,
100100
{
101-
self.zval.as_mut().and_then(|zv| T::from_zval_mut(zv))
101+
self.zval
102+
.as_mut()
103+
.and_then(|zv| T::from_zval_mut(zv.dereference_mut()))
102104
}
103105

104106
/// Attempts to return a reference to the arguments internal Zval.

src/types/zval.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ impl Zval {
5151
}
5252
}
5353

54+
/// Dereference the zval, if it is a reference.
55+
pub fn dereference(&self) -> &Self {
56+
return self.reference().or_else(|| self.indirect()).unwrap_or(self);
57+
}
58+
59+
/// Dereference the zval mutable, if it is a reference.
60+
pub fn dereference_mut(&mut self) -> &mut Self {
61+
// TODO: probably more ZTS work is needed here
62+
if self.is_reference() {
63+
#[allow(clippy::unwrap_used)]
64+
return self.reference_mut().unwrap();
65+
}
66+
if self.is_indirect() {
67+
#[allow(clippy::unwrap_used)]
68+
return self.indirect_mut().unwrap();
69+
}
70+
self
71+
}
72+
5473
/// Returns the value of the zval if it is a long.
5574
pub fn long(&self) -> Option<ZendLong> {
5675
if self.is_long() {

src/zend/_type.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
use std::{
2-
ffi::{c_void, CString},
3-
ptr,
4-
};
1+
use std::{ffi::c_void, ptr};
52

63
use crate::{
74
ffi::{
85
zend_type, IS_MIXED, MAY_BE_ANY, MAY_BE_BOOL, _IS_BOOL, _ZEND_IS_VARIADIC_BIT,
96
_ZEND_SEND_MODE_SHIFT, _ZEND_TYPE_NAME_BIT, _ZEND_TYPE_NULLABLE_BIT,
107
},
118
flags::DataType,
9+
types::ZendStr,
1210
};
1311

1412
/// Internal Zend type.
@@ -82,7 +80,7 @@ impl ZendType {
8280
allow_null: bool,
8381
) -> Option<Self> {
8482
Some(Self {
85-
ptr: CString::new(class_name).ok()?.into_raw() as *mut c_void,
83+
ptr: ZendStr::new(class_name, true).into_raw().as_ptr() as *mut c_void,
8684
type_mask: _ZEND_TYPE_NAME_BIT
8785
| (if allow_null {
8886
_ZEND_TYPE_NULLABLE_BIT

src/zend/try_catch.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ pub fn try_catch<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> Result<R, Catch
3535

3636
/// PHP propose a try catch mechanism in C using setjmp and longjmp (bailout)
3737
/// It store the arg of setjmp into the bailout field of the global executor
38-
/// If a bailout is triggered, the executor will jump to the setjmp and restore the previous setjmp
38+
/// If a bailout is triggered, the executor will jump to the setjmp and restore
39+
/// the previous setjmp
3940
///
4041
/// try_catch_first allow to use this mechanism
4142
///
42-
/// This functions differs from ['try_catch'] as it also initialize the bailout mechanism
43-
/// for the first time
43+
/// This functions differs from ['try_catch'] as it also initialize the bailout
44+
/// mechanism for the first time
4445
///
4546
/// # Returns
4647
///

0 commit comments

Comments
 (0)