From a3312136708c7ba164ab7932b67be99efc721ac8 Mon Sep 17 00:00:00 2001 From: ju1ius Date: Thu, 24 Nov 2022 11:17:12 +0100 Subject: [PATCH] Add instance_of() and get_class_entry() methods on ZendObject (#197) * adds `ZendObject::get_class_entry()` to retrieve the class entry of an object without casting pointers * adds `ZendObject::instance_of()` to allow more idiomatic instanceof checks. * adds a mention that `ZendObject::is_instance::()` does not check the parent classes or interfaces. This bit me when I tried to check if `my_object.is_instance::()` and it didn't work. --- src/types/object.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/types/object.rs b/src/types/object.rs index 62fd1487de..24c70d8194 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -80,6 +80,17 @@ impl ZendObject { unsafe { ZBox::from_raw(this.get_mut_zend_obj()) } } + /// Returns the [`ClassEntry`] associated with this object. + /// + /// # Panics + /// + /// Panics if the class entry is invalid. + pub fn get_class_entry(&self) -> &'static ClassEntry { + // SAFETY: it is OK to panic here since PHP would segfault anyway + // when encountering an object with no class entry. + unsafe { self.ce.as_ref() }.expect("Could not retrieve class entry.") + } + /// Attempts to retrieve the class name of the object. pub fn get_class_name(&self) -> Result { unsafe { @@ -91,8 +102,21 @@ impl ZendObject { } } + /// Returns whether this object is an instance of the given [`ClassEntry`]. + /// + /// This method checks the class and interface inheritance chain. + /// + /// # Panics + /// + /// Panics if the class entry is invalid. + pub fn instance_of(&self, ce: &ClassEntry) -> bool { + self.get_class_entry().instance_of(ce) + } + /// Checks if the given object is an instance of a registered class with /// Rust type `T`. + /// + /// This method doesn't check the class and interface inheritance chain. pub fn is_instance(&self) -> bool { (self.ce as *const ClassEntry).eq(&(T::get_metadata().ce() as *const _)) }