Skip to content

Commit 02be0de

Browse files
committed
refactor: optimizing extends and implements
1 parent 58fef19 commit 02be0de

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

phper/src/classes.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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
/// ```
276281
pub struct StateClass<T> {
277-
inner: Rc<RefCell<*mut zend_class_entry>>,
278-
name: Option<String>,
282+
inner: InnerClassEntry,
279283
_p: PhantomData<T>,
280284
}
281285

282286
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: InnerClassEntry::Name(name.into()),
288291
_p: PhantomData,
289292
}
290293
}
@@ -293,22 +296,27 @@ impl StateClass<()> {
293296
impl<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)]
383390
pub struct Interface {
384-
inner: Rc<RefCell<*mut zend_class_entry>>,
385-
name: Option<String>,
391+
inner: InnerClassEntry,
386392
}
387393

388394
impl 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

Comments
 (0)