@@ -14,6 +14,7 @@ use crate::{
1414 arrays:: ZArr ,
1515 errors:: { ClassNotFoundError , InitializeObjectError , Throwable } ,
1616 functions:: { Function , FunctionEntry , Method , MethodEntity } ,
17+ modules:: global_module,
1718 objects:: { StateObj , StateObject , ZObject } ,
1819 strings:: ZStr ,
1920 sys:: * ,
@@ -23,8 +24,6 @@ use crate::{
2324} ;
2425use std:: {
2526 any:: Any ,
26- borrow:: ToOwned ,
27- convert:: TryInto ,
2827 ffi:: { c_void, CString } ,
2928 fmt:: Debug ,
3029 marker:: PhantomData ,
@@ -849,12 +848,15 @@ pub(crate) type RawVisibility = u32;
849848
850849#[ allow( clippy:: useless_conversion) ]
851850unsafe extern "C" fn create_object ( ce : * mut zend_class_entry ) -> * mut zend_object {
851+ // Get real ce which hold state_constructor.
852+ let real_ce = find_real_ce ( ce) . unwrap ( ) ;
853+
852854 // Alloc more memory size to store state data.
853855 let state_object = phper_zend_object_alloc ( size_of :: < StateObj < ( ) > > ( ) . try_into ( ) . unwrap ( ) , ce) ;
854856 let state_object = StateObj :: < ( ) > :: from_mut_ptr ( state_object) ;
855857
856858 // Find the hack elements hidden behind null builtin_function.
857- let mut func_ptr = ( * ce ) . info . internal . builtin_functions ;
859+ let mut func_ptr = ( * real_ce ) . info . internal . builtin_functions ;
858860 while !( * func_ptr) . fname . is_null ( ) {
859861 func_ptr = func_ptr. offset ( 1 ) ;
860862 }
@@ -904,14 +906,15 @@ unsafe extern "C" fn clone_object(object: *mut zval) -> *mut zend_object {
904906#[ allow( clippy:: useless_conversion) ]
905907unsafe fn clone_object_common ( object : * mut zend_object ) -> * mut zend_object {
906908 let ce = ( * object) . ce ;
909+ let real_ce = find_real_ce ( ce) . unwrap ( ) ;
907910
908911 // Alloc more memory size to store state data.
909912 let new_state_object =
910913 phper_zend_object_alloc ( size_of :: < StateObj < ( ) > > ( ) . try_into ( ) . unwrap ( ) , ce) ;
911914 let new_state_object = StateObj :: < ( ) > :: from_mut_ptr ( new_state_object) ;
912915
913916 // Find the hack elements hidden behind null builtin_function.
914- let mut func_ptr = ( * ( * object ) . ce ) . info . internal . builtin_functions ;
917+ let mut func_ptr = ( * real_ce ) . info . internal . builtin_functions ;
915918 while !( * func_ptr) . fname . is_null ( ) {
916919 func_ptr = func_ptr. offset ( 1 ) ;
917920 }
@@ -947,3 +950,19 @@ unsafe extern "C" fn free_object(object: *mut zend_object) {
947950 // Original destroy call.
948951 zend_object_std_dtor ( object) ;
949952}
953+
954+ /// Find the class that registered by phper.
955+ unsafe fn find_real_ce ( mut ce : * mut zend_class_entry ) -> Option < * mut zend_class_entry > {
956+ let class_entities = global_module ( ) . class_entities ( ) ;
957+
958+ while !ce. is_null ( ) {
959+ for entity in class_entities {
960+ if ClassEntry :: from_ptr ( ce) . get_name ( ) . to_c_str ( ) == Ok ( & entity. class_name ) {
961+ return Some ( ce) ;
962+ }
963+ }
964+ ce = phper_get_parent_class ( ce) ;
965+ }
966+
967+ None
968+ }
0 commit comments