@@ -30,8 +30,7 @@ use std::{
30
30
marker:: PhantomData ,
31
31
mem:: { ManuallyDrop , replace, size_of, transmute, zeroed} ,
32
32
os:: raw:: c_int,
33
- ptr,
34
- ptr:: null_mut,
33
+ ptr:: { self , null, null_mut} ,
35
34
rc:: Rc ,
36
35
slice,
37
36
} ;
@@ -233,6 +232,12 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
233
232
}
234
233
}
235
234
235
+ #[ derive( Clone ) ]
236
+ enum InnerClassEntry {
237
+ Ptr ( * const zend_class_entry ) ,
238
+ Name ( String ) ,
239
+ }
240
+
236
241
/// The [StateClass] holds [zend_class_entry] and inner state, created by
237
242
/// [Module::add_class](crate::modules::Module::add_class) or
238
243
/// [ClassEntity::bound_class].
@@ -273,45 +278,55 @@ fn find_global_class_entry_ptr(name: impl AsRef<str>) -> *mut zend_class_entry {
273
278
/// module
274
279
/// }
275
280
/// ```
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 > > ,
279
283
_p : PhantomData < T > ,
280
284
}
281
285
282
- impl StateClass < ( ) > {
286
+ impl StateClass < [ ( ) ] > {
283
287
/// Create from name, which will be looked up from globals.
284
288
pub fn from_name ( name : impl Into < String > ) -> Self {
285
289
Self {
286
- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
287
- name : Some ( name. into ( ) ) ,
290
+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Name ( name. into ( ) ) ) ) ,
288
291
_p : PhantomData ,
289
292
}
290
293
}
291
294
}
292
295
293
- impl < T > StateClass < T > {
296
+ impl < T : ? Sized > StateClass < T > {
294
297
fn null ( ) -> Self {
295
298
Self {
296
- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
297
- name : None ,
299
+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Ptr ( null ( ) ) ) ) ,
298
300
_p : PhantomData ,
299
301
}
300
302
}
301
303
302
304
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
+ }
304
313
}
305
314
306
315
/// Converts to class entry.
307
316
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
+ }
312
325
}
313
326
}
327
+ }
314
328
329
+ impl < T : ' static > StateClass < T > {
315
330
/// Create the object from class and call `__construct` with arguments.
316
331
///
317
332
/// If the `__construct` is private, or protected and the called scope isn't
@@ -338,7 +353,6 @@ impl<T> Clone for StateClass<T> {
338
353
fn clone ( & self ) -> Self {
339
354
Self {
340
355
inner : self . inner . clone ( ) ,
341
- name : self . name . clone ( ) ,
342
356
_p : self . _p ,
343
357
}
344
358
}
@@ -381,39 +395,44 @@ impl<T> Clone for StateClass<T> {
381
395
/// ```
382
396
#[ derive( Clone ) ]
383
397
pub struct Interface {
384
- inner : Rc < RefCell < * mut zend_class_entry > > ,
385
- name : Option < String > ,
398
+ inner : Rc < RefCell < InnerClassEntry > > ,
386
399
}
387
400
388
401
impl Interface {
389
402
fn null ( ) -> Self {
390
403
Self {
391
- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
392
- name : None ,
404
+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Ptr ( null ( ) ) ) ) ,
393
405
}
394
406
}
395
407
396
408
/// Create a new interface from global name (eg "Stringable", "ArrayAccess")
397
409
pub fn from_name ( name : impl Into < String > ) -> Self {
398
410
Self {
399
- inner : Rc :: new ( RefCell :: new ( null_mut ( ) ) ) ,
400
- name : Some ( name. into ( ) ) ,
411
+ inner : Rc :: new ( RefCell :: new ( InnerClassEntry :: Name ( name. into ( ) ) ) ) ,
401
412
}
402
413
}
403
414
404
415
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
+ }
407
423
}
408
- * self . inner . borrow_mut ( ) = ptr;
409
424
}
410
425
411
426
/// Converts to class entry.
412
427
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
+ }
417
436
}
418
437
}
419
438
}
@@ -433,7 +452,7 @@ pub struct ClassEntity<T: 'static> {
433
452
state_constructor : Rc < StateConstructor > ,
434
453
method_entities : Vec < MethodEntity > ,
435
454
property_entities : Vec < PropertyEntity > ,
436
- parent : Option < StateClass < ( ) > > ,
455
+ parent : Option < StateClass < [ ( ) ] > > ,
437
456
interfaces : Vec < Interface > ,
438
457
constants : Vec < ConstantEntity > ,
439
458
bound_class : StateClass < T > ,
@@ -588,8 +607,8 @@ impl<T: 'static> ClassEntity<T> {
588
607
/// module
589
608
/// }
590
609
/// ```
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) } ) ;
593
612
}
594
613
595
614
/// Register class to `implements` the interface, due to the class can
@@ -793,7 +812,7 @@ pub struct InterfaceEntity {
793
812
interface_name : CString ,
794
813
method_entities : Vec < MethodEntity > ,
795
814
constants : Vec < ConstantEntity > ,
796
- extends : Vec < Box < dyn Fn ( ) -> & ' static ClassEntry > > ,
815
+ extends : Vec < Interface > ,
797
816
bound_interface : Interface ,
798
817
}
799
818
@@ -840,11 +859,7 @@ impl InterfaceEntity {
840
859
/// interface.extends(Interface::from_name("Stringable"));
841
860
/// ```
842
861
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) ;
848
863
}
849
864
850
865
#[ allow( clippy:: useless_conversion) ]
@@ -861,7 +876,7 @@ impl InterfaceEntity {
861
876
self . bound_interface . bind ( class_ce) ;
862
877
863
878
for interface in & self . extends {
864
- let interface_ce = interface ( ) . as_ptr ( ) ;
879
+ let interface_ce = interface. as_class_entry ( ) . as_ptr ( ) ;
865
880
zend_class_implements ( class_ce, 1 , interface_ce) ;
866
881
}
867
882
0 commit comments