@@ -30,8 +30,7 @@ use std::{
3030 marker:: PhantomData ,
3131 mem:: { ManuallyDrop , replace, size_of, transmute, zeroed} ,
3232 os:: raw:: c_int,
33- ptr,
34- ptr:: null_mut,
33+ ptr:: { self , null, null_mut} ,
3534 rc:: Rc ,
3635 slice,
3736} ;
@@ -233,6 +232,12 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
233232 }
234233}
235234
235+ #[ derive( Clone ) ]
236+ enum InnerClassEntry {
237+ Ptr ( * const zend_class_entry ) ,
238+ Name ( String ) ,
239+ }
240+
236241/// The [StateClass] holds [zend_class_entry] and inner state, created by
237242/// [Module::add_class](crate::modules::Module::add_class) or
238243/// [ClassEntity::bound_class].
@@ -273,45 +278,55 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
273278/// module
274279/// }
275280/// ```
276- pub struct StateClass < T > {
277- inner : Rc < RefCell < * mut zend_class_entry > > ,
278- name : Option < String > ,
281+ pub struct StateClass < T : ?Sized > {
282+ inner : Rc < RefCell < InnerClassEntry > > ,
279283 _p : PhantomData < T > ,
280284}
281285
282- impl StateClass < ( ) > {
286+ impl StateClass < [ ( ) ] > {
283287 /// Create from name, which will be looked up from globals.
284288 pub fn from_name ( name : impl Into < String > ) -> Self {
285289 Self {
286- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
287- name : Some ( name. into ( ) ) ,
290+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Name ( name. into ( ) ) ) ) ,
288291 _p : PhantomData ,
289292 }
290293 }
291294}
292295
293- impl < T > StateClass < T > {
296+ impl < T : ? Sized > StateClass < T > {
294297 fn null ( ) -> Self {
295298 Self {
296- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
297- name : None ,
299+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Ptr ( null ( ) ) ) ) ,
298300 _p : PhantomData ,
299301 }
300302 }
301303
302304 fn bind ( & self , ptr : * mut zend_class_entry ) {
303- * self . inner . borrow_mut ( ) = ptr;
305+ match & mut * self . inner . borrow_mut ( ) {
306+ InnerClassEntry :: Ptr ( p) => {
307+ * p = ptr;
308+ }
309+ InnerClassEntry :: Name ( _) => {
310+ unreachable ! ( "Cannot bind() an StateClass created with from_name()" ) ;
311+ }
312+ }
304313 }
305314
306315 /// Converts to class entry.
307316 pub fn as_class_entry ( & self ) -> & ClassEntry {
308- if let Some ( name) = & self . name {
309- ClassEntry :: from_globals ( name) . unwrap ( )
310- } else {
311- unsafe { ClassEntry :: from_mut_ptr ( * self . inner . borrow ( ) ) }
317+ let inner = self . inner . borrow ( ) . clone ( ) ;
318+ match inner {
319+ InnerClassEntry :: Ptr ( ptr) => unsafe { ClassEntry :: from_ptr ( ptr) } ,
320+ InnerClassEntry :: Name ( name) => {
321+ let entry = ClassEntry :: from_globals ( name) . unwrap ( ) ;
322+ * self . inner . borrow_mut ( ) = InnerClassEntry :: Ptr ( entry. as_ptr ( ) ) ;
323+ entry
324+ }
312325 }
313326 }
327+ }
314328
329+ impl < T : ' static > StateClass < T > {
315330 /// Create the object from class and call `__construct` with arguments.
316331 ///
317332 /// If the `__construct` is private, or protected and the called scope isn't
@@ -338,7 +353,6 @@ impl<T> Clone for StateClass<T> {
338353 fn clone ( & self ) -> Self {
339354 Self {
340355 inner : self . inner . clone ( ) ,
341- name : self . name . clone ( ) ,
342356 _p : self . _p ,
343357 }
344358 }
@@ -381,39 +395,44 @@ impl<T> Clone for StateClass<T> {
381395/// ```
382396#[ derive( Clone ) ]
383397pub struct Interface {
384- inner : Rc < RefCell < * mut zend_class_entry > > ,
385- name : Option < String > ,
398+ inner : Rc < RefCell < InnerClassEntry > > ,
386399}
387400
388401impl Interface {
389402 fn null ( ) -> Self {
390403 Self {
391- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
392- name : None ,
404+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Ptr ( null ( ) ) ) ) ,
393405 }
394406 }
395407
396408 /// Create a new interface from global name (eg "Stringable", "ArrayAccess")
397409 pub fn from_name ( name : impl Into < String > ) -> Self {
398410 Self {
399- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
400- name : Some ( name. into ( ) ) ,
411+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Name ( name. into ( ) ) ) ) ,
401412 }
402413 }
403414
404415 fn bind ( & self , ptr : * mut zend_class_entry ) {
405- if self . name . is_some ( ) {
406- panic ! ( "Cannot bind() an Interface created with from_name()" ) ;
416+ match & mut * self . inner . borrow_mut ( ) {
417+ InnerClassEntry :: Ptr ( p) => {
418+ * p = ptr;
419+ }
420+ InnerClassEntry :: Name ( _) => {
421+ unreachable ! ( "Cannot bind() an Interface created with from_name()" ) ;
422+ }
407423 }
408- * self . inner . borrow_mut ( ) = ptr;
409424 }
410425
411426 /// Converts to class entry.
412427 pub fn as_class_entry ( & self ) -> & ClassEntry {
413- if let Some ( name) = & self . name {
414- ClassEntry :: from_globals ( name) . unwrap ( )
415- } else {
416- unsafe { ClassEntry :: from_mut_ptr ( * self . inner . borrow ( ) ) }
428+ let inner = self . inner . borrow ( ) . clone ( ) ;
429+ match inner {
430+ InnerClassEntry :: Ptr ( ptr) => unsafe { ClassEntry :: from_ptr ( ptr) } ,
431+ InnerClassEntry :: Name ( name) => {
432+ let entry = ClassEntry :: from_globals ( name) . unwrap ( ) ;
433+ * self . inner . borrow_mut ( ) = InnerClassEntry :: Ptr ( entry. as_ptr ( ) ) ;
434+ entry
435+ }
417436 }
418437 }
419438}
@@ -433,7 +452,7 @@ pub struct ClassEntity<T: 'static> {
433452 state_constructor : Rc < StateConstructor > ,
434453 method_entities : Vec < MethodEntity > ,
435454 property_entities : Vec < PropertyEntity > ,
436- parent : Option < StateClass < ( ) > > ,
455+ parent : Option < StateClass < [ ( ) ] > > ,
437456 interfaces : Vec < Interface > ,
438457 constants : Vec < ConstantEntity > ,
439458 bound_class : StateClass < T > ,
@@ -588,8 +607,8 @@ impl<T: 'static> ClassEntity<T> {
588607 /// module
589608 /// }
590609 /// ```
591- pub fn extends < S : ' static > ( & mut self , parent : StateClass < S > ) {
592- self . parent = Some ( unsafe { transmute :: < StateClass < S > , StateClass < ( ) > > ( parent) } ) ;
610+ pub fn extends < S : ? Sized > ( & mut self , parent : StateClass < S > ) {
611+ self . parent = Some ( unsafe { transmute :: < StateClass < S > , StateClass < [ ( ) ] > > ( parent) } ) ;
593612 }
594613
595614 /// Register class to `implements` the interface, due to the class can
@@ -793,7 +812,7 @@ pub struct InterfaceEntity {
793812 interface_name : CString ,
794813 method_entities : Vec < MethodEntity > ,
795814 constants : Vec < ConstantEntity > ,
796- extends : Vec < Box < dyn Fn ( ) -> & ' static ClassEntry > > ,
815+ extends : Vec < Interface > ,
797816 bound_interface : Interface ,
798817}
799818
@@ -840,11 +859,7 @@ impl InterfaceEntity {
840859 /// interface.extends(Interface::from_name("Stringable"));
841860 /// ```
842861 pub fn extends ( & mut self , interface : Interface ) {
843- self . extends . push ( Box :: new ( move || {
844- let entry: & ' static ClassEntry =
845- unsafe { std:: mem:: transmute ( interface. as_class_entry ( ) ) } ;
846- entry
847- } ) ) ;
862+ self . extends . push ( interface) ;
848863 }
849864
850865 #[ allow( clippy:: useless_conversion) ]
@@ -861,7 +876,7 @@ impl InterfaceEntity {
861876 self . bound_interface . bind ( class_ce) ;
862877
863878 for interface in & self . extends {
864- let interface_ce = interface ( ) . as_ptr ( ) ;
879+ let interface_ce = interface. as_class_entry ( ) . as_ptr ( ) ;
865880 zend_class_implements ( class_ce, 1 , interface_ce) ;
866881 }
867882
0 commit comments