Skip to content

Commit 05b9120

Browse files
committed
Make SetVal method as unsafe, and add Val::set.
1 parent 7b8e2d4 commit 05b9120

File tree

4 files changed

+83
-76
lines changed

4 files changed

+83
-76
lines changed

phper/src/functions.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ where
2828
{
2929
fn call(&self, _: &mut ExecuteData, arguments: &mut [Val], return_value: &mut Val) {
3030
let r = (self.0)(arguments);
31-
r.set_val(return_value);
31+
unsafe {
32+
r.set_val(return_value);
33+
}
3234
}
3335
}
3436

phper/src/values.rs

Lines changed: 67 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
arrays::Array,
66
errors::{Throwable, TypeError},
77
functions::ZendFunction,
8-
objects::Object,
8+
objects::{Object, StatelessObject},
99
strings::ZendString,
1010
sys::*,
1111
types::{get_type_by_const, Type},
@@ -80,16 +80,25 @@ pub struct Val {
8080
}
8181

8282
impl Val {
83-
pub fn new<T: SetVal>(t: T) -> Self {
83+
pub fn new(t: impl SetVal) -> Self {
8484
let mut val = unsafe { zeroed::<Val>() };
85-
SetVal::set_val(t, &mut val);
85+
unsafe {
86+
SetVal::set_val(t, &mut val);
87+
}
8688
val
8789
}
8890

8991
pub fn null() -> Self {
9092
Self::new(())
9193
}
9294

95+
pub fn set(&mut self, t: impl SetVal) {
96+
unsafe {
97+
self.drop_value();
98+
SetVal::set_val(t, self);
99+
}
100+
}
101+
93102
pub unsafe fn from_mut_ptr<'a>(ptr: *mut zval) -> &'a mut Self {
94103
assert!(!ptr.is_null(), "ptr should not be null");
95104
&mut *(ptr as *mut Self)
@@ -207,22 +216,22 @@ impl Val {
207216
}
208217
}
209218

210-
unsafe fn drop_me(&mut self) {
219+
unsafe fn drop_value(&mut self) {
211220
let t = self.get_type();
212221
if t.is_string() {
213-
phper_zend_string_release(self.inner.value.str);
222+
ZendString::free(self.inner.value.str as *mut ZendString);
214223
} else if t.is_array() {
215-
zend_hash_destroy(self.inner.value.arr);
224+
Array::free(self.inner.value.arr as *mut Array);
216225
} else if t.is_object() {
217-
zend_objects_destroy_object(self.inner.value.obj);
226+
Object::free(self.inner.value.obj as *mut StatelessObject);
218227
}
219228
}
220229
}
221230

222231
impl EAllocatable for Val {
223232
fn free(ptr: *mut Self) {
224233
unsafe {
225-
ptr.as_mut().unwrap().drop_me();
234+
ptr.as_mut().unwrap().drop_value();
226235
_efree(ptr.cast());
227236
}
228237
}
@@ -231,167 +240,153 @@ impl EAllocatable for Val {
231240
impl Drop for Val {
232241
fn drop(&mut self) {
233242
unsafe {
234-
self.drop_me();
243+
self.drop_value();
235244
}
236245
}
237246
}
238247

239248
/// The trait for setting the value of [Val], mainly as the return value of
240249
/// functions and methods, and initializer of [Val].
241250
pub trait SetVal {
242-
fn set_val(self, val: &mut Val);
251+
unsafe fn set_val(self, val: &mut Val);
243252
}
244253

245254
impl SetVal for () {
246-
fn set_val(self, val: &mut Val) {
255+
unsafe fn set_val(self, val: &mut Val) {
247256
val.set_type(Type::Null);
248257
}
249258
}
250259

251260
impl SetVal for bool {
252-
fn set_val(self, val: &mut Val) {
261+
unsafe fn set_val(self, val: &mut Val) {
253262
val.set_type(if self { Type::True } else { Type::False });
254263
}
255264
}
256265

257266
impl SetVal for i32 {
258-
fn set_val(self, val: &mut Val) {
267+
unsafe fn set_val(self, val: &mut Val) {
259268
SetVal::set_val(self as i64, val)
260269
}
261270
}
262271

263272
impl SetVal for u32 {
264-
fn set_val(self, val: &mut Val) {
273+
unsafe fn set_val(self, val: &mut Val) {
265274
SetVal::set_val(self as i64, val)
266275
}
267276
}
268277

269278
impl SetVal for i64 {
270-
fn set_val(self, val: &mut Val) {
279+
unsafe fn set_val(self, val: &mut Val) {
271280
val.set_type(Type::Long);
272-
unsafe {
273-
(*val.as_mut_ptr()).value.lval = self;
274-
}
281+
(*val.as_mut_ptr()).value.lval = self;
275282
}
276283
}
277284

278285
impl SetVal for f64 {
279-
fn set_val(self, val: &mut Val) {
286+
unsafe fn set_val(self, val: &mut Val) {
280287
val.set_type(Type::Double);
281-
unsafe {
282-
(*val.as_mut_ptr()).value.dval = self;
283-
}
288+
(*val.as_mut_ptr()).value.dval = self;
284289
}
285290
}
286291

287292
impl SetVal for &str {
288-
fn set_val(self, val: &mut Val) {
289-
unsafe {
290-
phper_zval_stringl(val.as_mut_ptr(), self.as_ptr().cast(), self.len());
291-
}
293+
unsafe fn set_val(self, val: &mut Val) {
294+
phper_zval_stringl(val.as_mut_ptr(), self.as_ptr().cast(), self.len());
292295
}
293296
}
294297

295298
impl SetVal for String {
296-
fn set_val(self, val: &mut Val) {
299+
unsafe fn set_val(self, val: &mut Val) {
297300
let s: &str = &self;
298301
SetVal::set_val(s, val)
299302
}
300303
}
301304

302305
impl SetVal for &[u8] {
303-
fn set_val(self, val: &mut Val) {
304-
unsafe {
305-
// Because php string is binary safe, so can set `&[u8]` to php string.
306-
phper_zval_stringl(val.as_mut_ptr(), self.as_ptr().cast(), self.len());
307-
}
306+
unsafe fn set_val(self, val: &mut Val) {
307+
// Because php string is binary safe, so can set `&[u8]` to php string.
308+
phper_zval_stringl(val.as_mut_ptr(), self.as_ptr().cast(), self.len());
308309
}
309310
}
310311

311312
impl SetVal for Vec<u8> {
312-
fn set_val(self, val: &mut Val) {
313+
unsafe fn set_val(self, val: &mut Val) {
313314
let v: &[u8] = &self;
314315
SetVal::set_val(v, val)
315316
}
316317
}
317318

318319
impl<T: SetVal> SetVal for Vec<T> {
319-
fn set_val(self, val: &mut Val) {
320-
unsafe {
321-
phper_array_init(val.as_mut_ptr());
322-
for (k, v) in self.into_iter().enumerate() {
323-
let v = EBox::new(Val::new(v));
324-
phper_zend_hash_index_update(
325-
(*val.as_mut_ptr()).value.arr,
326-
k as u64,
327-
EBox::into_raw(v).cast(),
328-
);
329-
}
320+
unsafe fn set_val(self, val: &mut Val) {
321+
phper_array_init(val.as_mut_ptr());
322+
for (k, v) in self.into_iter().enumerate() {
323+
let v = EBox::new(Val::new(v));
324+
phper_zend_hash_index_update(
325+
(*val.as_mut_ptr()).value.arr,
326+
k as u64,
327+
EBox::into_raw(v).cast(),
328+
);
330329
}
331330
}
332331
}
333332

334333
/// Setting the val to an array, Because of the feature of [std::collections::HashMap], the item
335334
/// order of array is not guarantee.
336335
impl<K: AsRef<str>, V: SetVal> SetVal for HashMap<K, V> {
337-
fn set_val(self, val: &mut Val) {
336+
unsafe fn set_val(self, val: &mut Val) {
338337
map_set_val(self, val);
339338
}
340339
}
341340

342341
/// Setting the val to an array, which preserves item order.
343342
impl<K: AsRef<str>, V: SetVal> SetVal for IndexMap<K, V> {
344-
fn set_val(self, val: &mut Val) {
343+
unsafe fn set_val(self, val: &mut Val) {
345344
map_set_val(self, val);
346345
}
347346
}
348347

349348
impl<K: AsRef<str>, V: SetVal> SetVal for BTreeMap<K, V> {
350-
fn set_val(self, val: &mut Val) {
349+
unsafe fn set_val(self, val: &mut Val) {
351350
map_set_val(self, val);
352351
}
353352
}
354353

355-
fn map_set_val<K, V, I>(iterator: I, val: &mut Val)
354+
unsafe fn map_set_val<K, V, I>(iterator: I, val: &mut Val)
356355
where
357356
I: IntoIterator<Item = (K, V)>,
358357
K: AsRef<str>,
359358
V: SetVal,
360359
{
361-
unsafe {
362-
phper_array_init(val.as_mut_ptr());
363-
for (k, v) in iterator.into_iter() {
364-
let k = k.as_ref();
365-
let v = EBox::new(Val::new(v));
366-
phper_zend_hash_str_update(
367-
(*val.as_mut_ptr()).value.arr,
368-
k.as_ptr().cast(),
369-
k.len(),
370-
EBox::into_raw(v).cast(),
371-
);
372-
}
360+
phper_array_init(val.as_mut_ptr());
361+
for (k, v) in iterator.into_iter() {
362+
let k = k.as_ref();
363+
let v = EBox::new(Val::new(v));
364+
phper_zend_hash_str_update(
365+
(*val.as_mut_ptr()).value.arr,
366+
k.as_ptr().cast(),
367+
k.len(),
368+
EBox::into_raw(v).cast(),
369+
);
373370
}
374371
}
375372

376373
impl SetVal for EBox<Array> {
377-
fn set_val(self, val: &mut Val) {
378-
unsafe {
379-
let arr = EBox::into_raw(self);
380-
phper_zval_arr(val.as_mut_ptr(), arr.cast());
381-
}
374+
unsafe fn set_val(self, val: &mut Val) {
375+
let arr = EBox::into_raw(self);
376+
phper_zval_arr(val.as_mut_ptr(), arr.cast());
382377
}
383378
}
384379

385380
impl<T> SetVal for EBox<Object<T>> {
386-
fn set_val(self, val: &mut Val) {
381+
unsafe fn set_val(self, val: &mut Val) {
387382
let object = EBox::into_raw(self);
388383
val.inner.value.obj = object.cast();
389384
val.set_type(Type::ObjectEx);
390385
}
391386
}
392387

393388
impl<T: SetVal> SetVal for Option<T> {
394-
fn set_val(self, val: &mut Val) {
389+
unsafe fn set_val(self, val: &mut Val) {
395390
match self {
396391
Some(t) => SetVal::set_val(t, val),
397392
None => SetVal::set_val((), val),
@@ -400,10 +395,10 @@ impl<T: SetVal> SetVal for Option<T> {
400395
}
401396

402397
impl<T: SetVal, E: Throwable> SetVal for Result<T, E> {
403-
fn set_val(self, val: &mut Val) {
398+
unsafe fn set_val(self, val: &mut Val) {
404399
match self {
405400
Ok(t) => t.set_val(val),
406-
Err(e) => unsafe {
401+
Err(e) => {
407402
let class_entry = e.class_entry();
408403
let message = ensure_end_with_zero(e.message());
409404
zend_throw_exception(
@@ -412,15 +407,13 @@ impl<T: SetVal, E: Throwable> SetVal for Result<T, E> {
412407
e.code() as i64,
413408
);
414409
SetVal::set_val((), val);
415-
},
410+
}
416411
}
417412
}
418413
}
419414

420415
impl SetVal for Val {
421-
fn set_val(mut self, val: &mut Val) {
422-
unsafe {
423-
phper_zval_copy(val.as_mut_ptr(), self.as_mut_ptr());
424-
}
416+
unsafe fn set_val(mut self, val: &mut Val) {
417+
phper_zval_copy(val.as_mut_ptr(), self.as_mut_ptr());
425418
}
426419
}

tests/integration/src/objects.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,15 @@ pub fn integrate(module: &mut Module) {
2727
},
2828
vec![],
2929
);
30+
31+
module.add_function(
32+
"integrate_objects_set_val",
33+
|_: &mut [Val]| -> phper::Result<()> {
34+
let o = Object::new_by_std_class();
35+
let mut v = Val::null();
36+
v.set(o);
37+
Ok(())
38+
},
39+
vec![],
40+
);
3041
}

tests/integration/tests/php/objects.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
require_once __DIR__ . '/_common.php';
44

55
integrate_objects_new_drop();
6-
integrate_objects_get_set();
6+
integrate_objects_get_set();
7+
integrate_objects_set_val();

0 commit comments

Comments
 (0)