@@ -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_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 ( Rc < RefCell < * mut 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].
@@ -274,17 +279,15 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
274279/// }
275280/// ```
276281pub struct StateClass < T > {
277- inner : Rc < RefCell < * mut zend_class_entry > > ,
278- name : Option < String > ,
282+ inner : InnerClassEntry ,
279283 _p : PhantomData < T > ,
280284}
281285
282286impl 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 : InnerClassEntry :: Name ( name. into ( ) ) ,
288291 _p : PhantomData ,
289292 }
290293 }
@@ -293,22 +296,27 @@ impl StateClass<()> {
293296impl < T > StateClass < T > {
294297 fn null ( ) -> Self {
295298 Self {
296- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
297- name : None ,
299+ inner : InnerClassEntry :: Ptr ( Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ) ,
298300 _p : PhantomData ,
299301 }
300302 }
301303
302304 fn bind ( & self , ptr : * mut zend_class_entry ) {
303- * self . inner . borrow_mut ( ) = ptr;
305+ match & self . inner {
306+ InnerClassEntry :: Ptr ( p) => {
307+ * p. borrow_mut ( ) = 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+ match & self . inner {
318+ InnerClassEntry :: Ptr ( ptr) => unsafe { ClassEntry :: from_mut_ptr ( * ptr. borrow ( ) ) } ,
319+ InnerClassEntry :: Name ( name) => ClassEntry :: from_globals ( name) . unwrap ( ) ,
312320 }
313321 }
314322
@@ -338,7 +346,6 @@ impl<T> Clone for StateClass<T> {
338346 fn clone ( & self ) -> Self {
339347 Self {
340348 inner : self . inner . clone ( ) ,
341- name : self . name . clone ( ) ,
342349 _p : self . _p ,
343350 }
344351 }
@@ -381,39 +388,39 @@ impl<T> Clone for StateClass<T> {
381388/// ```
382389#[ derive( Clone ) ]
383390pub struct Interface {
384- inner : Rc < RefCell < * mut zend_class_entry > > ,
385- name : Option < String > ,
391+ inner : InnerClassEntry ,
386392}
387393
388394impl Interface {
389395 fn null ( ) -> Self {
390396 Self {
391- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
392- name : None ,
397+ inner : InnerClassEntry :: Ptr ( Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ) ,
393398 }
394399 }
395400
396401 /// Create a new interface from global name (eg "Stringable", "ArrayAccess")
397402 pub fn from_name ( name : impl Into < String > ) -> Self {
398403 Self {
399- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
400- name : Some ( name. into ( ) ) ,
404+ inner : InnerClassEntry :: Name ( name. into ( ) ) ,
401405 }
402406 }
403407
404408 fn bind ( & self , ptr : * mut zend_class_entry ) {
405- if self . name . is_some ( ) {
406- panic ! ( "Cannot bind() an Interface created with from_name()" ) ;
409+ match & self . inner {
410+ InnerClassEntry :: Ptr ( p) => {
411+ * p. borrow_mut ( ) = ptr;
412+ }
413+ InnerClassEntry :: Name ( _) => {
414+ unreachable ! ( "Cannot bind() an Interface created with from_name()" ) ;
415+ }
407416 }
408- * self . inner . borrow_mut ( ) = ptr;
409417 }
410418
411419 /// Converts to class entry.
412420 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 ( ) ) }
421+ match & self . inner {
422+ InnerClassEntry :: Ptr ( ptr) => unsafe { ClassEntry :: from_mut_ptr ( * ptr. borrow ( ) ) } ,
423+ InnerClassEntry :: Name ( name) => ClassEntry :: from_globals ( name) . unwrap ( ) ,
417424 }
418425 }
419426}
@@ -793,7 +800,7 @@ pub struct InterfaceEntity {
793800 interface_name : CString ,
794801 method_entities : Vec < MethodEntity > ,
795802 constants : Vec < ConstantEntity > ,
796- extends : Vec < Box < dyn Fn ( ) -> & ' static ClassEntry > > ,
803+ extends : Vec < Interface > ,
797804 bound_interface : Interface ,
798805}
799806
@@ -840,11 +847,7 @@ impl InterfaceEntity {
840847 /// interface.extends(Interface::from_name("Stringable"));
841848 /// ```
842849 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- } ) ) ;
850+ self . extends . push ( interface) ;
848851 }
849852
850853 #[ allow( clippy:: useless_conversion) ]
@@ -861,7 +864,7 @@ impl InterfaceEntity {
861864 self . bound_interface . bind ( class_ce) ;
862865
863866 for interface in & self . extends {
864- let interface_ce = interface ( ) . as_ptr ( ) ;
867+ let interface_ce = interface. as_class_entry ( ) . as_ptr ( ) ;
865868 zend_class_implements ( class_ce, 1 , interface_ce) ;
866869 }
867870
0 commit comments