Skip to content

Commit 895993e

Browse files
committed
Refacting ZArray and ZVal.
1 parent fd0c825 commit 895993e

File tree

23 files changed

+347
-203
lines changed

23 files changed

+347
-203
lines changed

examples/hello/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ pub fn get_module() -> Module {
6060
|_: &mut [ZVal]| {
6161
let mut arr = ZArray::new();
6262

63-
let hello_enable = ZVal::new(Ini::get::<bool>("hello.enable"));
63+
let hello_enable = ZVal::from(Ini::get::<bool>("hello.enable"));
6464
arr.insert("hello.enable", hello_enable);
6565

66-
let hello_description = ZVal::new(Ini::get::<String>("hello.description"));
66+
let hello_description = ZVal::from(Ini::get::<String>("hello.description"));
6767
arr.insert("hello.description", hello_description);
6868

6969
arr
@@ -87,7 +87,7 @@ pub fn get_module() -> Module {
8787
"setFoo",
8888
Visibility::Public,
8989
|this: &mut Object<()>, arguments: &mut [ZVal]| -> phper::Result<()> {
90-
this.set_property("foo", ZVal::new(arguments[0].as_string_value()?));
90+
this.set_property("foo", ZVal::from(arguments[0].as_string_value()?));
9191
Ok(())
9292
},
9393
vec![Argument::by_val("foo")],

examples/http-client/src/client.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub fn make_client_builder_class() -> DynamicClass<ClientBuilder> {
3131
"timeout",
3232
Visibility::Public,
3333
|this, arguments| {
34-
let ms = arguments[0].as_long()?;
34+
let ms = arguments[0].as_long().unwrap();
3535
let state: &mut ClientBuilder = this.as_mut_state();
3636
replace_and_set(state, |builder| {
3737
builder.timeout(Duration::from_millis(ms as u64))
@@ -45,7 +45,7 @@ pub fn make_client_builder_class() -> DynamicClass<ClientBuilder> {
4545
"cookie_store",
4646
Visibility::Public,
4747
|this, arguments| {
48-
let enable = arguments[0].as_bool()?;
48+
let enable = arguments[0].as_bool().unwrap();
4949
let state = this.as_mut_state();
5050
replace_and_set(state, |builder| builder.cookie_store(enable));
5151
Ok::<_, HttpClientError>(this.duplicate())
@@ -84,7 +84,7 @@ pub fn make_client_class() -> DynamicClass<Option<Client>> {
8484
"get",
8585
Visibility::Public,
8686
|this, arguments| {
87-
let url = arguments[0].to_string()?;
87+
let url = arguments[0].as_z_str().unwrap().to_str().unwrap();
8888
let client = this.as_state().as_ref().unwrap();
8989
let request_builder = client.get(url);
9090
let mut object =
@@ -100,7 +100,7 @@ pub fn make_client_class() -> DynamicClass<Option<Client>> {
100100
"post",
101101
Visibility::Public,
102102
|this, arguments| {
103-
let url = arguments[0].to_string()?;
103+
let url = arguments[0].as_z_str().unwrap().to_str().unwrap();
104104
let client = this.as_state().as_ref().unwrap();
105105
let request_builder = client.post(url);
106106
let mut object =

examples/http-client/src/response.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
use crate::{errors::HttpClientError, utils::replace_and_get};
1212
use indexmap::map::IndexMap;
1313
use phper::{
14+
arrays::{InsertKey, ZArray},
1415
classes::{DynamicClass, Visibility},
1516
objects::Object,
17+
values::ZVal,
1618
};
1719
use reqwest::blocking::Response;
1820

@@ -65,10 +67,11 @@ pub fn make_response_class() -> DynamicClass<Option<Response>> {
6567
response
6668
.headers()
6769
.iter()
68-
.fold(IndexMap::new(), |mut acc, (key, value)| {
69-
acc.entry(key.as_str().to_owned())
70-
.or_insert(vec![])
71-
.push(value.as_bytes().to_owned());
70+
.fold(ZArray::new(), |mut acc, (key, value)| {
71+
let arr = acc.entry(key.as_str()).or_insert(ZVal::from(ZArray::new()));
72+
arr.as_mut_z_arr()
73+
.unwrap()
74+
.insert(InsertKey::NextIndex, ZVal::from(value.as_bytes()));
7275
acc
7376
});
7477
Ok::<_, HttpClientError>(headers_map)

examples/http-server/src/errors.rs

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

1111
use hyper::header::{InvalidHeaderName, InvalidHeaderValue};
1212
use phper::classes::{ClassEntry, DynamicClass};
13-
use std::net::AddrParseError;
13+
use std::{net::AddrParseError, str::Utf8Error};
1414

1515
const EXCEPTION_CLASS_NAME: &str = "HttpServer\\HttpServerException";
1616

@@ -21,6 +21,9 @@ pub enum HttpServerError {
2121
#[throwable(transparent)]
2222
Phper(#[from] phper::Error),
2323

24+
#[error(transparent)]
25+
Utf8Error(#[from] Utf8Error),
26+
2427
#[error(transparent)]
2528
AddrParse(#[from] AddrParseError),
2629

examples/http-server/src/response.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub fn make_response_class() -> DynamicClass<Response<Body>> {
2626
|this, arguments| {
2727
let response: &mut Response<Body> = this.as_mut_state();
2828
response.headers_mut().insert(
29-
HeaderName::from_bytes(arguments[0].to_string()?.as_bytes())?,
30-
HeaderValue::from_bytes(arguments[1].to_string()?.as_bytes())?,
29+
HeaderName::from_bytes(arguments[0].as_z_str().unwrap().to_bytes())?,
30+
HeaderValue::from_bytes(arguments[1].as_z_str().unwrap().to_bytes())?,
3131
);
3232
Ok::<_, HttpServerError>(())
3333
},
@@ -39,7 +39,7 @@ pub fn make_response_class() -> DynamicClass<Response<Body>> {
3939
Visibility::Public,
4040
|this, arguments| {
4141
let response: &mut Response<Body> = this.as_mut_state();
42-
*response.body_mut() = arguments[0].as_bytes()?.to_vec().into();
42+
*response.body_mut() = arguments[0].as_z_str().unwrap().to_bytes().to_vec().into();
4343
Ok::<_, phper::Error>(())
4444
},
4545
vec![Argument::by_val("data")],

examples/http-server/src/server.rs

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,24 @@ use hyper::{
1818
Body, Request, Response, Server, StatusCode,
1919
};
2020
use phper::{
21+
alloc::EBox,
2122
classes::{ClassEntry, DynamicClass, StatelessClassEntry, Visibility},
22-
errors::Error::Throw,
23+
errors::{Error::Throw, MapMustBeTypeError},
2324
functions::Argument,
25+
types::TypeInfo,
2426
values::ZVal,
2527
};
26-
use std::{convert::Infallible, mem::replace, net::SocketAddr, sync::Arc};
28+
use std::{
29+
cell::RefCell,
30+
convert::Infallible,
31+
mem::replace,
32+
net::SocketAddr,
33+
ptr::null_mut,
34+
sync::{
35+
atomic::{AtomicPtr, Ordering},
36+
Arc,
37+
},
38+
};
2739
use tokio::{runtime::Handle, sync::Mutex};
2840

2941
const HTTP_SERVER_CLASS_NAME: &str = "HttpServer\\HttpServer";
@@ -39,11 +51,15 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
3951
"__construct",
4052
Visibility::Public,
4153
|this, arguments| {
42-
let host = arguments[0].to_string()?;
43-
let port = arguments[1].as_long()?;
44-
this.set_property("host", ZVal::new(&*host));
45-
this.set_property("port", ZVal::new(port));
46-
let addr = format!("{}:{}", host, port).parse::<SocketAddr>()?;
54+
let host = arguments[0]
55+
.as_z_str()
56+
.map_must_be_type_error(TypeInfo::string(), arguments[0].get_type_info())?;
57+
let port = arguments[1]
58+
.as_long()
59+
.map_must_be_type_error(TypeInfo::string(), arguments[0].get_type_info())?;
60+
this.set_property("host", host);
61+
this.set_property("port", port);
62+
let addr = format!("{}:{}", host.to_str()?, port).parse::<SocketAddr>()?;
4763
let builder = Server::bind(&addr);
4864
*this.as_mut_state() = Some(builder);
4965
Ok::<_, HttpServerError>(())
@@ -55,7 +71,7 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
5571
"onRequest",
5672
Visibility::Public,
5773
|this, arguments| {
58-
this.set_property("onRequestHandle", ZVal::new(arguments[0].duplicate()?));
74+
this.set_property("onRequestHandle", arguments[0].clone());
5975
Ok::<_, phper::Error>(())
6076
},
6177
vec![Argument::by_val("handle")],
@@ -65,60 +81,53 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
6581
"start",
6682
Visibility::Public,
6783
|this, _| {
84+
static HANDLE: AtomicPtr<ZVal> = AtomicPtr::new(null_mut());
85+
6886
let builder = replace(this.as_mut_state(), None).unwrap();
6987
let handle = this
7088
.duplicate_property("onRequestHandle")
7189
.map_err(phper::Error::NotRefCountedType)?;
72-
let handle = Arc::new(Mutex::new(handle));
73-
74-
let make_svc = make_service_fn(move |_conn| {
75-
let handle = handle.clone();
76-
77-
async move {
78-
Ok::<_, Infallible>(service_fn(move |_: Request<Body>| {
79-
let handle = handle.clone();
80-
async move {
81-
match async move {
82-
let mut handle = handle.lock().await;
83-
84-
let request =
85-
StatelessClassEntry::from_globals(HTTP_REQUEST_CLASS_NAME)?
86-
.new_object([])?;
87-
let request = ZVal::new(request);
88-
89-
let mut response = ClassEntry::<Response<Body>>::from_globals(
90-
HTTP_RESPONSE_CLASS_NAME,
91-
)?
90+
HANDLE.store(EBox::into_raw(handle), Ordering::SeqCst);
91+
92+
let make_svc = make_service_fn(move |_conn| async move {
93+
Ok::<_, Infallible>(service_fn(move |_: Request<Body>| async move {
94+
match async move {
95+
let handle = unsafe { HANDLE.load(Ordering::SeqCst).as_mut().unwrap() };
96+
97+
let request = StatelessClassEntry::from_globals(HTTP_REQUEST_CLASS_NAME)?
98+
.new_object([])?;
99+
let request = ZVal::from(request);
100+
101+
let mut response =
102+
ClassEntry::<Response<Body>>::from_globals(HTTP_RESPONSE_CLASS_NAME)?
92103
.new_object([])?;
93-
let response_val = response.duplicate();
94-
let response_val = ZVal::new(response_val);
95-
96-
match handle.call([request, response_val]) {
97-
Err(Throw(ex)) => {
98-
*response.as_mut_state().status_mut() =
99-
StatusCode::INTERNAL_SERVER_ERROR;
100-
*response.as_mut_state().body_mut() = ex.to_string().into();
101-
}
102-
Err(e) => return Err(e.into()),
103-
_ => {}
104-
}
105-
106-
let response = replace_and_get(response.as_mut_state());
107-
Ok::<Response<Body>, HttpServerError>(response)
108-
}
109-
.await
110-
{
111-
Ok(response) => Ok::<Response<Body>, Infallible>(response),
112-
Err(e) => {
113-
let mut response = Response::new("".into());
114-
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
115-
*response.body_mut() = e.to_string().into();
116-
Ok::<Response<Body>, Infallible>(response)
117-
}
104+
let response_val = response.duplicate();
105+
let response_val = ZVal::from(response_val);
106+
107+
match handle.call([request, response_val]) {
108+
Err(Throw(ex)) => {
109+
*response.as_mut_state().status_mut() =
110+
StatusCode::INTERNAL_SERVER_ERROR;
111+
*response.as_mut_state().body_mut() = ex.to_string().into();
118112
}
113+
Err(e) => return Err(e.into()),
114+
_ => {}
115+
}
116+
117+
let response = replace_and_get(response.as_mut_state());
118+
Ok::<Response<Body>, HttpServerError>(response)
119+
}
120+
.await
121+
{
122+
Ok(response) => Ok::<Response<Body>, Infallible>(response),
123+
Err(e) => {
124+
let mut response = Response::new("".into());
125+
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
126+
*response.body_mut() = e.to_string().into();
127+
Ok::<Response<Body>, Infallible>(response)
119128
}
120-
}))
121-
}
129+
}
130+
}))
122131
});
123132

124133
let server = builder.serve(make_svc);

phper-alloc/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::{
2020

2121
/// The Box which use php `emalloc` and `efree` to manage memory.
2222
///
23-
/// TODO now feature `allocator_api` is still unstable, implement myself, use
23+
/// TODO Now feature `allocator_api` is still unstable, implement myself, use
2424
/// Box<T, Alloc> later.
2525
pub struct EBox<T> {
2626
ptr: *mut T,
@@ -36,6 +36,7 @@ impl<T> EBox<T> {
3636
unsafe {
3737
assert_ne!(size_of::<T>(), 0);
3838
let ptr: *mut T = phper_emalloc(size_of::<T>().try_into().unwrap()).cast();
39+
// TODO Deal with ptr is zero, when memory limit is reached.
3940
ptr.write(x);
4041
Self { ptr }
4142
}
@@ -58,6 +59,10 @@ impl<T> EBox<T> {
5859
forget(b);
5960
ptr
6061
}
62+
63+
pub fn into_inner(self) -> T {
64+
unsafe { self.ptr.read() }
65+
}
6166
}
6267

6368
impl<T> Deref for EBox<T> {

phper-sys/php_wrapper.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ void phper_zval_double(zval *zv, double d) {
250250
ZVAL_DOUBLE(zv, d);
251251
}
252252

253-
int phper_z_type_info_p(zval *zv) {
253+
uint32_t phper_z_type_info_p(const zval *zv) {
254254
return Z_TYPE_INFO_P(zv);
255255
}
256256

@@ -262,8 +262,8 @@ void phper_zval_str(zval *zv, zend_string *s) {
262262
ZVAL_STR(zv, s);
263263
}
264264

265-
zend_array *phper_zend_new_array(uint32_t nSize) {
266-
return zend_new_array(nSize);
265+
zend_array *phper_zend_new_array(uint32_t size) {
266+
return zend_new_array(size);
267267
}
268268

269269
zend_array *phper_zend_array_dup(zend_array *source) {

phper/src/arrays.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ impl ZArr {
170170
array: self,
171171
}
172172
}
173+
174+
pub fn entry<'a>(&mut self, key: impl Into<Key<'a>>) -> Entry<'a> {
175+
todo!()
176+
}
173177
}
174178

175179
impl ToOwned for ZArr {
@@ -213,6 +217,12 @@ impl ZArray {
213217
}
214218
}
215219

220+
impl Default for ZArray {
221+
fn default() -> Self {
222+
Self::new()
223+
}
224+
}
225+
216226
impl Deref for ZArray {
217227
type Target = ZArr;
218228

@@ -289,3 +299,15 @@ impl<'a> Iterator for Iter<'a> {
289299
}
290300
}
291301
}
302+
303+
// TODO Implement it.
304+
pub enum Entry<'a> {
305+
Occupied(PhantomData<&'a ()>),
306+
Vacant(PhantomData<&'a ()>),
307+
}
308+
309+
impl<'a> Entry<'a> {
310+
pub fn or_insert(&mut self, val: ZVal) -> &'a mut ZVal {
311+
todo!()
312+
}
313+
}

phper/src/constants.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2019 jmjoy
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+
// TODO Add constant.

0 commit comments

Comments
 (0)