@@ -1746,6 +1746,32 @@ ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_proper
17461746 return zend_perform_covariant_type_check (ce , prop_info -> type , ce , value_arg_info -> type );
17471747}
17481748
1749+ #ifdef ZEND_WIN32
1750+ /* Hooked properties set get_iterator, which causes issues on Windows. Windows
1751+ * attaches multiple processes to the same shm, with each process potentially
1752+ * having different addresses to the corresponding get_iterator function due to
1753+ * ASLR. This prevents us from caching the class.
1754+ *
1755+ * To at least cache the unlinked class, avoid early-binding on Windows, and set
1756+ * get_iterator during inheritance. The linked class may not use inheritance
1757+ * cache. */
1758+ static void zend_link_hooked_object_iter (zend_class_entry * ce ) {
1759+ if (!ce -> get_iterator && ce -> num_hooked_props ) {
1760+ ce -> get_iterator = zend_hooked_object_get_iterator ;
1761+ ce -> ce_flags &= ~ZEND_ACC_CACHEABLE ;
1762+ if (CG (current_linking_class ) == ce ) {
1763+ HashTable * ht = (HashTable * )ce -> inheritance_cache ;
1764+ if (ht ) {
1765+ zend_hash_destroy (ht );
1766+ FREE_HASHTABLE (ht );
1767+ ce -> inheritance_cache = NULL ;
1768+ }
1769+ CG (current_linking_class ) = NULL ;
1770+ }
1771+ }
1772+ }
1773+ #endif
1774+
17491775ZEND_API void zend_do_inheritance_ex (zend_class_entry * ce , zend_class_entry * parent_ce , bool checked ) /* {{{ */
17501776{
17511777 zend_property_info * property_info ;
@@ -3544,6 +3570,10 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35443570 orig_linking_class = CG (current_linking_class );
35453571 CG (current_linking_class ) = is_cacheable ? ce : NULL ;
35463572
3573+ #ifdef ZEND_WIN32
3574+ zend_link_hooked_object_iter (ce );
3575+ #endif
3576+
35473577 if (ce -> ce_flags & ZEND_ACC_ENUM ) {
35483578 /* Only register builtin enum methods during inheritance to avoid persisting them in
35493579 * opcache. */
0 commit comments