@@ -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 ;
@@ -3550,6 +3576,10 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35503576 zend_enum_register_funcs (ce );
35513577 }
35523578
3579+ #ifdef ZEND_WIN32
3580+ zend_link_hooked_object_iter (ce );
3581+ #endif
3582+
35533583 if (parent ) {
35543584 if (!(parent -> ce_flags & ZEND_ACC_LINKED )) {
35553585 add_dependency_obligation (ce , parent );
@@ -3838,6 +3868,10 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
38383868 zend_begin_record_errors ();
38393869 }
38403870
3871+ #ifdef ZEND_WIN32
3872+ zend_link_hooked_object_iter (ce );
3873+ #endif
3874+
38413875 zend_do_inheritance_ex (ce , parent_ce , status == INHERITANCE_SUCCESS );
38423876 if (parent_ce && parent_ce -> num_interfaces ) {
38433877 zend_do_inherit_interfaces (ce , parent_ce );
0 commit comments