Classes in mixed
This PR introduce a possibility to store objects inside a mixed
Reason
For a long time in KPHP, the mixed type included only primitive types, which was a significant difference from Zend PHP. This approach was taken to ensure that classes and primitive types do not mix, thereby achieving high performance. However, this is not always convenient. Additionally, this functionality, together with ArrayAccess support, will help to decouple code built on mixed and hash tables (e.g., mixed $user; $user['age'] => User $user; $user->age). This PR adds the ability to explicitly convert objects to the mixed type (to_mixed). Access to objects in mixed, you should use smart casts:
mixed $m = foo(...);
if ($m instanceof User)) {
// use $m as if it has type User
}
Implementation
Mixed layout consists of two integer values, first one for tag and the second one for the payload. In case of objects, we store pointer to an object. But there is a caveat: this pointer point to object that was casted into may_be_mixed_base abstract class that virtually inherited by every class in extends-chain and every interface in implements-chain. It allows to use RTTI that helps to cast an object into parent classes inside C++ (in codegen, class like class A extends B implements I1, I2, I3 will be converted into
class A : inherit_virtually<B, I1, I2, I3> {}
). That's why such a snippet
class A extends B implements I1, I2 { ... }
mixed $a = create(...);
if ($a instanceof B) { ... }
if ($a instanceof I1) { ... }
if ($a instanceof I2) { ... }
works now.