@@ -14,23 +14,22 @@ use crate::{
14
14
arrays:: ZArr ,
15
15
errors:: { ClassNotFoundError , InitializeObjectError , Throwable } ,
16
16
functions:: { Function , FunctionEntry , Method , MethodEntity } ,
17
- objects:: { CStateObject , StateObj , StateObject , ZObj , ZObject } ,
17
+ objects:: { StateObj , StateObject , ZObject } ,
18
18
strings:: ZStr ,
19
19
sys:: * ,
20
20
types:: Scalar ,
21
21
utils:: ensure_end_with_zero,
22
22
values:: ZVal ,
23
23
} ;
24
24
use once_cell:: sync:: OnceCell ;
25
- use phper_alloc:: ToRefOwned ;
26
25
use std:: {
27
26
any:: Any ,
28
27
borrow:: ToOwned ,
29
28
convert:: TryInto ,
30
29
ffi:: { c_void, CString } ,
31
30
fmt:: Debug ,
32
31
marker:: PhantomData ,
33
- mem:: { size_of, zeroed} ,
32
+ mem:: { size_of, zeroed, ManuallyDrop } ,
34
33
os:: raw:: c_int,
35
34
ptr:: null_mut,
36
35
rc:: Rc ,
@@ -156,8 +155,11 @@ impl ClassEntry {
156
155
if !phper_object_init_ex ( val. as_mut_ptr ( ) , ptr) {
157
156
Err ( InitializeObjectError :: new ( self . get_name ( ) . to_str ( ) ?. to_owned ( ) ) . into ( ) )
158
157
} else {
158
+ // Can't drop val here! Otherwise the object will be dropped too (wasting me a
159
+ // day of debugging time here).
160
+ let mut val = ManuallyDrop :: new ( val) ;
159
161
let ptr = phper_z_obj_p ( val. as_mut_ptr ( ) ) ;
160
- Ok ( ZObj :: from_mut_ptr ( ptr) . to_ref_owned ( ) )
162
+ Ok ( ZObject :: from_raw ( ptr) )
161
163
}
162
164
}
163
165
}
@@ -218,7 +220,7 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
218
220
/// ```rust
219
221
/// use phper::classes::{ClassEntity, StateClass};
220
222
///
221
- /// pub static FOO_CLASS: StateClass<FooState> = StateClass::new ();
223
+ /// pub static FOO_CLASS: StateClass<FooState> = StateClass::null ();
222
224
///
223
225
/// #[derive(Default)]
224
226
/// pub struct FooState;
@@ -238,7 +240,7 @@ pub struct StateClass<T> {
238
240
impl < T > StateClass < T > {
239
241
/// Create empty [StateClass], with null
240
242
/// [zend_class_entry](crate::sys::zend_class_entry).
241
- pub const fn new ( ) -> Self {
243
+ pub const fn null ( ) -> Self {
242
244
Self {
243
245
inner : AtomicPtr :: new ( null_mut ( ) ) ,
244
246
_p : PhantomData ,
@@ -263,18 +265,22 @@ impl<T> StateClass<T> {
263
265
) -> crate :: Result < StateObject < T > > {
264
266
self . as_class_entry ( )
265
267
. new_object ( arguments)
266
- . map ( StateObject :: new)
268
+ . map ( ZObject :: into_raw)
269
+ . map ( StateObject :: < T > :: from_raw_object)
267
270
}
268
271
269
272
/// Create the object from class, without calling `__construct`.
270
273
///
271
274
/// **Be careful when `__construct` is necessary.**
272
275
pub fn init_object ( & ' static self ) -> crate :: Result < StateObject < T > > {
273
- self . as_class_entry ( ) . init_object ( ) . map ( StateObject :: new)
276
+ self . as_class_entry ( )
277
+ . init_object ( )
278
+ . map ( ZObject :: into_raw)
279
+ . map ( StateObject :: < T > :: from_raw_object)
274
280
}
275
281
}
276
282
277
- pub ( crate ) type StateConstructor = dyn Fn ( ) -> Box < dyn Any > ;
283
+ pub ( crate ) type StateConstructor = dyn Fn ( ) -> * mut dyn Any ;
278
284
279
285
/// Builder for registering class.
280
286
///
@@ -316,7 +322,11 @@ impl<T: 'static> ClassEntity<T> {
316
322
) -> Self {
317
323
Self {
318
324
class_name : ensure_end_with_zero ( class_name) ,
319
- state_constructor : Rc :: new ( move || Box :: new ( state_constructor ( ) ) ) ,
325
+ state_constructor : Rc :: new ( move || {
326
+ let state = state_constructor ( ) ;
327
+ let boxed = Box :: new ( state) as Box < dyn Any > ;
328
+ Box :: into_raw ( boxed)
329
+ } ) ,
320
330
method_entities : Vec :: new ( ) ,
321
331
property_entities : Vec :: new ( ) ,
322
332
parent : None ,
@@ -571,7 +581,7 @@ fn get_object_handlers() -> &'static zend_object_handlers {
571
581
static HANDLERS : OnceCell < zend_object_handlers > = OnceCell :: new ( ) ;
572
582
HANDLERS . get_or_init ( || unsafe {
573
583
let mut handlers = std_object_handlers;
574
- handlers. offset = CStateObject :: offset ( ) as c_int ;
584
+ handlers. offset = StateObj :: < ( ) > :: offset ( ) as c_int ;
575
585
handlers. free_obj = Some ( free_object) ;
576
586
handlers
577
587
} )
@@ -580,15 +590,15 @@ fn get_object_handlers() -> &'static zend_object_handlers {
580
590
#[ allow( clippy:: useless_conversion) ]
581
591
unsafe extern "C" fn create_object ( ce : * mut zend_class_entry ) -> * mut zend_object {
582
592
// Alloc more memory size to store state data.
583
- let state_object: * mut CStateObject =
584
- phper_zend_object_alloc ( size_of :: < CStateObject > ( ) . try_into ( ) . unwrap ( ) , ce ) . cast ( ) ;
593
+ let state_object = phper_zend_object_alloc ( size_of :: < StateObj < ( ) > > ( ) . try_into ( ) . unwrap ( ) , ce ) ;
594
+ let state_object = StateObj :: < ( ) > :: from_mut_ptr ( state_object ) ;
585
595
586
596
// Common initialize process.
587
- let object = CStateObject :: as_mut_object ( state_object ) ;
597
+ let object = state_object . as_mut_object ( ) . as_mut_ptr ( ) ;
588
598
zend_object_std_init ( object, ce) ;
589
599
object_properties_init ( object, ce) ;
590
600
rebuild_object_properties ( object) ;
591
- object. handlers = get_object_handlers ( ) ;
601
+ ( * object) . handlers = get_object_handlers ( ) ;
592
602
593
603
// Get state constructor.
594
604
let mut func_ptr = ( * ce) . info . internal . builtin_functions ;
@@ -599,17 +609,18 @@ unsafe extern "C" fn create_object(ce: *mut zend_class_entry) -> *mut zend_objec
599
609
let state_constructor = func_ptr as * mut * const StateConstructor ;
600
610
let state_constructor = state_constructor. read ( ) ;
601
611
602
- // Call the state constructor.
603
- let data: Box < dyn Any > = ( state_constructor. as_ref ( ) . unwrap ( ) ) ( ) ;
604
- * CStateObject :: as_mut_state ( state_object) = Box :: into_raw ( data) ;
612
+ // Call the state constructor and store the state .
613
+ let data = ( state_constructor. as_ref ( ) . unwrap ( ) ) ( ) ;
614
+ * state_object. as_mut_any_state ( ) = data;
605
615
606
616
object
607
617
}
608
618
609
619
unsafe extern "C" fn free_object ( object : * mut zend_object ) {
620
+ let state_object = StateObj :: < ( ) > :: from_mut_object_ptr ( object) ;
621
+
610
622
// Drop the state.
611
- let state_object = CStateObject :: fetch_ptr ( object) ;
612
- CStateObject :: drop_state ( state_object) ;
623
+ state_object. drop_state ( ) ;
613
624
614
625
// Original destroy call.
615
626
zend_object_std_dtor ( object) ;
0 commit comments