Skip to content

Commit d36f785

Browse files
committed
Refactor owned object to EBox alias
1 parent cdf7ad7 commit d36f785

File tree

19 files changed

+225
-404
lines changed

19 files changed

+225
-404
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/.cargo
44
/vendor
55
core
6+
compile_commands.json

examples/complex/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
// See the Mulan PSL v2 for more details.
1010

1111
use phper::{
12-
arrays::ZArray,
12+
alloc::EBox,
13+
arrays::ZArr,
1314
classes::{ClassEntity, Visibility},
1415
functions::Argument,
1516
ini::{Policy, ini_get},
@@ -61,7 +62,7 @@ pub fn get_module() -> Module {
6162
.argument(Argument::new("name"));
6263
module.add_function("complex_throw_exception", throw_exception);
6364
module.add_function("complex_get_all_ini", |_: &mut [ZVal]| {
64-
let mut arr = ZArray::new();
65+
let mut arr = EBox::<ZArr>::new();
6566

6667
let complex_enable = ZVal::from(ini_get::<bool>("complex.enable"));
6768
arr.insert("complex.enable", complex_enable);

examples/http-client/src/response.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
use crate::errors::HttpClientError;
1212
use phper::{
13-
arrays::{InsertKey, ZArray},
13+
alloc::EBox,
14+
arrays::{InsertKey, ZArr},
1415
classes::{ClassEntity, StateClass, Visibility},
1516
values::ZVal,
1617
};
@@ -50,16 +51,19 @@ pub fn make_response_class() -> ClassEntity<Option<Response>> {
5051
.ok_or_else(|| HttpClientError::ResponseAfterRead {
5152
method_name: "headers".to_owned(),
5253
})?;
53-
let headers_map = response
54-
.headers()
55-
.iter()
56-
.fold(ZArray::new(), |mut acc, (key, value)| {
57-
let arr = acc.entry(key.as_str()).or_insert(ZVal::from(ZArray::new()));
58-
arr.as_mut_z_arr()
59-
.unwrap()
60-
.insert(InsertKey::NextIndex, ZVal::from(value.as_bytes()));
61-
acc
62-
});
54+
let headers_map =
55+
response
56+
.headers()
57+
.iter()
58+
.fold(EBox::<ZArr>::new(), |mut acc, (key, value)| {
59+
let arr = acc
60+
.entry(key.as_str())
61+
.or_insert(ZVal::from(EBox::<ZArr>::new()));
62+
arr.as_mut_z_arr()
63+
.unwrap()
64+
.insert(InsertKey::NextIndex, ZVal::from(value.as_bytes()));
65+
acc
66+
});
6367
Ok::<_, HttpClientError>(headers_map)
6468
});
6569

examples/http-server/src/request.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
// See the Mulan PSL v2 for more details.
1010

1111
use phper::{
12-
arrays::ZArray,
12+
alloc::EBox,
13+
arrays::ZArr,
1314
classes::{ClassEntity, StateClass, Visibility},
1415
};
1516
use std::convert::Infallible;
@@ -31,7 +32,7 @@ pub fn make_request_class() -> ClassEntity<()> {
3132
// Register the constructor method with public visibility, initialize the
3233
// headers with empty array.
3334
class.add_method("__construct", Visibility::Public, |this, _arguments| {
34-
this.set_property("headers", ZArray::new());
35+
this.set_property("headers", EBox::<ZArr>::new());
3536
Ok::<_, Infallible>(())
3637
});
3738

phper-alloc/src/lib.rs

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -12,85 +12,7 @@
1212
#![warn(clippy::dbg_macro, clippy::print_stdout)]
1313
#![doc = include_str!("../README.md")]
1414

15-
#[macro_use]
16-
mod macros;
17-
18-
use phper_sys::*;
19-
use std::{
20-
borrow::Borrow,
21-
mem::{ManuallyDrop, size_of},
22-
ops::{Deref, DerefMut},
23-
};
24-
25-
/// The Box which use php `emalloc` and `efree` to manage memory.
26-
///
27-
/// TODO Now feature `allocator_api` is still unstable, implement myself, use
28-
/// Box<T, Alloc> later.
29-
pub struct EBox<T> {
30-
ptr: *mut T,
31-
}
32-
33-
impl<T> EBox<T> {
34-
/// Allocates heap memory using `emalloc` then places `x` into it.
35-
///
36-
/// # Panic
37-
///
38-
/// Panic if `size_of::<T>()` equals zero.
39-
#[allow(clippy::useless_conversion)]
40-
pub fn new(x: T) -> Self {
41-
unsafe {
42-
assert_ne!(size_of::<T>(), 0);
43-
let ptr: *mut T = phper_emalloc(size_of::<T>().try_into().unwrap()).cast();
44-
// TODO Deal with ptr is zero, when memory limit is reached.
45-
ptr.write(x);
46-
Self { ptr }
47-
}
48-
}
49-
50-
/// Constructs from a raw pointer.
51-
///
52-
/// # Safety
53-
///
54-
/// Make sure the pointer is from `into_raw`, or created from `emalloc`.
55-
pub unsafe fn from_raw(raw: *mut T) -> Self {
56-
Self { ptr: raw }
57-
}
58-
59-
/// Consumes and returning a wrapped raw pointer.
60-
///
61-
/// Will leak memory.
62-
pub fn into_raw(b: EBox<T>) -> *mut T {
63-
ManuallyDrop::new(b).ptr
64-
}
65-
66-
/// Consumes the `EBox`, returning the wrapped value.
67-
pub fn into_inner(self) -> T {
68-
unsafe { self.ptr.read() }
69-
}
70-
}
71-
72-
impl<T> Deref for EBox<T> {
73-
type Target = T;
74-
75-
fn deref(&self) -> &Self::Target {
76-
unsafe { self.ptr.as_ref().unwrap() }
77-
}
78-
}
79-
80-
impl<T> DerefMut for EBox<T> {
81-
fn deref_mut(&mut self) -> &mut Self::Target {
82-
unsafe { self.ptr.as_mut().unwrap() }
83-
}
84-
}
85-
86-
impl<T> Drop for EBox<T> {
87-
fn drop(&mut self) {
88-
unsafe {
89-
self.ptr.drop_in_place();
90-
phper_efree(self.ptr.cast());
91-
}
92-
}
93-
}
15+
use std::borrow::Borrow;
9416

9517
/// Duplicate an object without deep copy, but to only add the refcount, for php
9618
/// refcount struct.

phper-alloc/src/macros.rs

Lines changed: 0 additions & 21 deletions
This file was deleted.

phper/src/alloc.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//! Memory allocation utilities and boxed types for PHP values.
2+
3+
pub use phper_alloc::{RefClone, ToRefOwned};
4+
use std::{
5+
borrow::{Borrow, BorrowMut},
6+
fmt::{self},
7+
mem::ManuallyDrop,
8+
ops::{Deref, DerefMut},
9+
};
10+
11+
/// A smart pointer for PHP values allocated in the Zend Engine memory.
12+
///
13+
/// `EBox<T>` provides owned access to values allocated in PHP's memory
14+
/// management system. It automatically handles deallocation when dropped,
15+
/// ensuring proper cleanup of PHP resources.
16+
pub struct EBox<T> {
17+
ptr: *mut T,
18+
}
19+
20+
impl<T> EBox<T> {
21+
/// Constructs from a raw pointer.
22+
///
23+
/// # Safety
24+
///
25+
/// Make sure the pointer is from `into_raw`, or created from `emalloc`.
26+
pub unsafe fn from_raw(raw: *mut T) -> Self {
27+
Self { ptr: raw }
28+
}
29+
30+
/// Consumes and returning a wrapped raw pointer.
31+
///
32+
/// Will leak memory.
33+
pub fn into_raw(b: EBox<T>) -> *mut T {
34+
ManuallyDrop::new(b).ptr
35+
}
36+
}
37+
38+
impl<T: fmt::Debug> fmt::Debug for EBox<T> {
39+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40+
fmt::Debug::fmt(&**self, f)
41+
}
42+
}
43+
44+
impl<T> Deref for EBox<T> {
45+
type Target = T;
46+
47+
fn deref(&self) -> &Self::Target {
48+
unsafe { self.ptr.as_ref().unwrap() }
49+
}
50+
}
51+
52+
impl<T> DerefMut for EBox<T> {
53+
fn deref_mut(&mut self) -> &mut Self::Target {
54+
unsafe { self.ptr.as_mut().unwrap() }
55+
}
56+
}
57+
58+
impl<T> Drop for EBox<T> {
59+
fn drop(&mut self) {
60+
unsafe {
61+
self.ptr.drop_in_place();
62+
}
63+
}
64+
}
65+
66+
impl<T> Borrow<T> for EBox<T> {
67+
fn borrow(&self) -> &T {
68+
unsafe { self.ptr.as_ref().unwrap() }
69+
}
70+
}
71+
72+
impl<T> BorrowMut<T> for EBox<T> {
73+
fn borrow_mut(&mut self) -> &mut T {
74+
unsafe { self.ptr.as_mut().unwrap() }
75+
}
76+
}
77+
78+
impl<T> AsRef<T> for EBox<T> {
79+
fn as_ref(&self) -> &T {
80+
unsafe { self.ptr.as_ref().unwrap() }
81+
}
82+
}
83+
84+
impl<T> AsMut<T> for EBox<T> {
85+
fn as_mut(&mut self) -> &mut T {
86+
unsafe { self.ptr.as_mut().unwrap() }
87+
}
88+
}

0 commit comments

Comments
 (0)