Skip to content

Commit 9e1f1d0

Browse files
authored
Migration of ZString, ZArray, ZObject to EBox (#208)
1 parent cdf7ad7 commit 9e1f1d0

File tree

18 files changed

+180
-376
lines changed

18 files changed

+180
-376
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/http-server/tests/integration.rs

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

1111
use axum::http::header::CONTENT_TYPE;
12+
use hyper::StatusCode;
1213
use phper_test::{cli::test_long_term_php_script_with_condition, utils::get_lib_path};
1314
use reqwest::blocking::Client;
1415
use std::{
@@ -39,6 +40,7 @@ fn test_php() {
3940
let client = Client::new();
4041
for _ in 0..5 {
4142
let response = client.get("http://127.0.0.1:9000/").send().unwrap();
43+
assert_eq!(response.status(), StatusCode::OK);
4244
let content_type = response.headers().get(CONTENT_TYPE).unwrap();
4345
assert_eq!(content_type, "text/plain");
4446
let body = response.text().unwrap();

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-doc/doc/_05_internal_types/_01_z_str/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use phper::strings::ZString;
1818
let s = ZString::new("Hello world!");
1919
2020
// Will leak memory.
21-
let ptr = s.into_raw();
21+
let ptr = ZString::into_raw(s);
2222
2323
// retake pointer.
2424
let ss = unsafe { ZString::from_raw(ptr) };

phper-test/src/context.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ impl Context {
8282
ContextCommand { cmd, args }
8383
}
8484

85-
#[cfg_attr(docsrs, doc(cfg(feature = "fpm")))]
8685
pub fn find_php_fpm(&self) -> Option<String> {
8786
use std::ffi::OsStr;
8887

phper-test/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![warn(rust_2018_idioms, missing_docs)]
1212
#![warn(clippy::dbg_macro, clippy::print_stdout)]
13-
#![cfg_attr(docsrs, feature(doc_cfg))]
13+
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
1414
#![doc = include_str!("../README.md")]
1515

1616
pub mod cli;

phper/src/alloc.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) 2025 PHPER Framework Team
2+
// PHPER is licensed under Mulan PSL v2.
3+
// You can use this software according to the terms and conditions of the Mulan
4+
// PSL v2. You may obtain a copy of Mulan PSL v2 at:
5+
// http://license.coscl.org.cn/MulanPSL2
6+
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
7+
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8+
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9+
// See the Mulan PSL v2 for more details.
10+
11+
//! Memory allocation utilities and boxed types for PHP values.
12+
13+
pub use phper_alloc::{RefClone, ToRefOwned};
14+
use std::{
15+
borrow::{Borrow, BorrowMut},
16+
fmt::{self},
17+
mem::ManuallyDrop,
18+
ops::{Deref, DerefMut},
19+
};
20+
21+
/// A smart pointer for PHP values allocated in the Zend Engine memory.
22+
///
23+
/// `EBox<T>` provides owned access to values allocated in PHP's memory
24+
/// management system. It automatically handles deallocation when dropped,
25+
/// ensuring proper cleanup of PHP resources.
26+
pub struct EBox<T> {
27+
ptr: *mut T,
28+
}
29+
30+
impl<T> EBox<T> {
31+
/// Constructs from a raw pointer.
32+
///
33+
/// # Safety
34+
///
35+
/// Make sure the pointer is from `into_raw`, or created from `emalloc`.
36+
pub unsafe fn from_raw(raw: *mut T) -> Self {
37+
Self { ptr: raw }
38+
}
39+
40+
/// Consumes and returning a wrapped raw pointer.
41+
///
42+
/// Will leak memory.
43+
pub fn into_raw(b: EBox<T>) -> *mut T {
44+
ManuallyDrop::new(b).ptr
45+
}
46+
}
47+
48+
impl<T: fmt::Debug> fmt::Debug for EBox<T> {
49+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50+
fmt::Debug::fmt(&**self, f)
51+
}
52+
}
53+
54+
impl<T> Deref for EBox<T> {
55+
type Target = T;
56+
57+
fn deref(&self) -> &Self::Target {
58+
unsafe { self.ptr.as_ref().unwrap() }
59+
}
60+
}
61+
62+
impl<T> DerefMut for EBox<T> {
63+
fn deref_mut(&mut self) -> &mut Self::Target {
64+
unsafe { self.ptr.as_mut().unwrap() }
65+
}
66+
}
67+
68+
impl<T> Drop for EBox<T> {
69+
fn drop(&mut self) {
70+
unsafe {
71+
self.ptr.drop_in_place();
72+
}
73+
}
74+
}
75+
76+
impl<T> Borrow<T> for EBox<T> {
77+
fn borrow(&self) -> &T {
78+
unsafe { self.ptr.as_ref().unwrap() }
79+
}
80+
}
81+
82+
impl<T> BorrowMut<T> for EBox<T> {
83+
fn borrow_mut(&mut self) -> &mut T {
84+
unsafe { self.ptr.as_mut().unwrap() }
85+
}
86+
}
87+
88+
impl<T> AsRef<T> for EBox<T> {
89+
fn as_ref(&self) -> &T {
90+
unsafe { self.ptr.as_ref().unwrap() }
91+
}
92+
}
93+
94+
impl<T> AsMut<T> for EBox<T> {
95+
fn as_mut(&mut self) -> &mut T {
96+
unsafe { self.ptr.as_mut().unwrap() }
97+
}
98+
}

0 commit comments

Comments
 (0)