Skip to content

Commit caa46c3

Browse files
committed
Fix base type getter.
1 parent 50338e3 commit caa46c3

File tree

10 files changed

+25
-20
lines changed

10 files changed

+25
-20
lines changed

phper-alloc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub trait EAllocatable {
2727

2828
/// The Box which use php `emalloc` and `efree` to manage memory.
2929
///
30-
/// TODO now feature `allocator_api` is still unstable, implement myself.
30+
/// TODO now feature `allocator_api` is still unstable, implement myself, use Box<T, Alloc> later.
3131
pub struct EBox<T: EAllocatable> {
3232
ptr: *mut T,
3333
}

phper/src/arrays.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ impl EAllocatable for Array {
130130
if (*ptr).inner.gc.refcount == 0 {
131131
zend_hash_destroy(ptr.cast());
132132
_efree(ptr.cast());
133+
} else {
134+
(*ptr).inner.gc.refcount -= 1;
133135
}
134136
}
135137
}

phper/src/classes.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ impl<T: Send> Classifiable for DynamicClass<T> {
171171
pub type StatelessClassEntry = ClassEntry<()>;
172172

173173
/// Wrapper of [crate::sys::zend_class_entry].
174+
///
175+
/// # Generic
176+
///
177+
/// 1. Any `zend_class_entry` can be make into `ClassEntry<()>`, alias as [StatelessClassEntry].
178+
///
179+
/// 2. Only the `zend_class_entry` created by [crate::modules::Module::add_class] can be make into
180+
/// `ClassEntry<T>`, where `T` is the type defined by [Classifiable::state_type_id], as the inner
181+
/// state of `ClassEntry<T>` and `Object<T>`.
174182
#[repr(transparent)]
175183
pub struct ClassEntry<T: 'static> {
176184
inner: zend_class_entry,

phper/src/errors.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ use anyhow::anyhow;
99
use std::{convert::Infallible, error, ffi::FromBytesWithNulError, io, str::Utf8Error};
1010

1111
/// PHP Throwable, can cause throwing an exception when setting to [crate::values::Val].
12-
///
13-
/// TODO Write a derive macro for auto extends the item implements for enum.
1412
pub trait Throwable: error::Error {
1513
fn class_entry(&self) -> &StatelessClassEntry;
1614

phper/src/modules.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ impl Module {
150150
self.class_entities.push(unsafe { ClassEntity::new(class) });
151151
}
152152

153+
/// Leak memory to generate `zend_module_entry` pointer.
154+
#[doc(hidden)]
153155
pub unsafe fn module_entry(self) -> *const zend_module_entry {
154156
assert!(!self.name.is_empty(), "module name must be set");
155157
assert!(!self.version.is_empty(), "module version must be set");

phper/src/objects.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ impl<T> EAllocatable for Object<T> {
158158

159159
// zend_objects_store_call_destructors(ptr.cast());
160160
// zend_objects_store_free_object_storage(ptr.cast(), true.into());
161+
} else {
162+
(*ptr).inner.gc.refcount -= 1;
161163
}
162164
}
163165
}

phper/src/strings.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ impl ZendString {
5454
impl EAllocatable for ZendString {
5555
fn free(ptr: *mut Self) {
5656
unsafe {
57-
phper_zend_string_release(ptr.cast());
57+
if (*ptr).inner.gc.refcount == 0 {
58+
phper_zend_string_release(ptr.cast());
59+
} else {
60+
(*ptr).inner.gc.refcount -= 1;
61+
}
5862
}
5963
}
6064
}

phper/src/types.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl From<u32> for Type {
129129
}
130130
}
131131

132-
pub(crate) fn get_type_by_const(mut t: u32) -> crate::Result<String> {
132+
fn get_type_by_const(mut t: u32) -> crate::Result<String> {
133133
unsafe {
134134
t = get_base_type_by_raw(t);
135135
let s = zend_get_type_by_const(t as c_int);
@@ -147,18 +147,8 @@ pub(crate) fn get_type_by_const(mut t: u32) -> crate::Result<String> {
147147
}
148148

149149
#[inline]
150-
pub fn get_base_type_by_raw(mut t: u32) -> u32 {
151-
t &= !(IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT);
152-
153-
#[cfg(any(
154-
phper_major_version = "8",
155-
all(phper_major_version = "7", phper_minor_version = "4")
156-
))]
157-
{
158-
t &= !(IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT);
159-
}
160-
161-
t
150+
fn get_base_type_by_raw(t: u32) -> u32 {
151+
t & !(!0 << Z_TYPE_FLAGS_SHIFT)
162152
}
163153

164154
#[derive(From)]

phper/src/values.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,7 @@ impl SetVal for EBox<Array> {
391391
}
392392
}
393393

394-
// TODO Because the type of method argument `this` is mut ref, can't become a return value,
395-
// TODO Support chain call for PHP object later.
394+
// TODO Support chain call for PHP object later, now only support return owned object.
396395
impl<T> SetVal for EBox<Object<T>> {
397396
unsafe fn set_val(self, val: &mut Val) {
398397
let object = EBox::into_raw(self);

tests/integration/tests/php/arrays.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
assert_eq(integrate_arrays_new_drop(), "FOO BAR");
66
integrate_arrays_types();
7-
integrate_arrays_iter();
7+
integrate_arrays_iter();

0 commit comments

Comments
 (0)