@@ -26,6 +26,12 @@ zend_async_globals_t zend_async_globals_api = { 0 };
2626
2727#define ASYNC_THROW_ERROR (error ) zend_throw_error(NULL, error);
2828
29+ static zend_always_inline zend_ulong ptr_to_index (void * ptr )
30+ {
31+ zend_ulong key = (zend_ulong ) ptr ;
32+ return (key >> 3 ) | (key << ((sizeof (key ) * 8 ) - 3 ));
33+ }
34+
2935/* Forward declarations */
3036static void zend_async_main_handlers_shutdown (void );
3137
@@ -473,8 +479,15 @@ static zend_always_inline zend_async_waker_trigger_t *waker_trigger_create(
473479 initial_capacity = 2 ;
474480 }
475481
482+ #ifdef __cplusplus
483+ // Account for the [1] element already included in sizeof()
484+ size_t total_size = sizeof (zend_async_waker_trigger_t )
485+ + (initial_capacity - 1 ) * sizeof (zend_async_event_callback_t * );
486+ #else
487+ // Flexible array member doesn't contribute to sizeof()
476488 size_t total_size = sizeof (zend_async_waker_trigger_t )
477489 + initial_capacity * sizeof (zend_async_event_callback_t * );
490+ #endif
478491 zend_async_waker_trigger_t * trigger = (zend_async_waker_trigger_t * ) emalloc (total_size );
479492
480493 trigger -> length = 0 ;
@@ -715,11 +728,9 @@ void coroutine_event_callback_dispose(
715728 ((zend_coroutine_event_callback_t * ) callback )-> event = NULL ;
716729
717730 // Find the trigger for this event
718- // @todo zend_rotr3
719- zval * trigger_zval = zend_hash_index_find (& waker -> events , (zend_ulong ) event );
731+ zend_async_waker_trigger_t * trigger = zend_hash_index_find_ptr (& waker -> events , ptr_to_index (event ));
720732
721- if (trigger_zval != NULL ) {
722- zend_async_waker_trigger_t * trigger = Z_PTR_P (trigger_zval );
733+ if (trigger != NULL ) {
723734
724735 // Remove only this specific callback from the trigger
725736 for (uint32_t i = 0 ; i < trigger -> length ; i ++ ) {
@@ -732,10 +743,10 @@ void coroutine_event_callback_dispose(
732743
733744 // If no more callbacks in trigger, remove the entire event
734745 if (trigger -> length == 0 ) {
735- zend_hash_index_del (& waker -> events , ( zend_ulong ) event );
746+ zend_hash_index_del (& waker -> events , ptr_to_index ( event ) );
736747
737748 if (waker -> triggered_events != NULL ) {
738- zend_hash_index_del (waker -> triggered_events , ( zend_ulong ) event );
749+ zend_hash_index_del (waker -> triggered_events , ptr_to_index ( event ) );
739750 }
740751 }
741752 }
@@ -758,7 +769,7 @@ ZEND_API void zend_async_waker_add_triggered_event(
758769 }
759770
760771 if (EXPECTED (zend_hash_index_add_ptr (
761- coroutine -> waker -> triggered_events , ( zend_ulong ) event , event )
772+ coroutine -> waker -> triggered_events , ptr_to_index ( event ) , event )
762773 != NULL )) {
763774 ZEND_ASYNC_EVENT_ADD_REF (event );
764775 }
@@ -771,7 +782,7 @@ ZEND_API bool zend_async_waker_is_event_exists(
771782 return false;
772783 }
773784
774- return zend_hash_index_find (& coroutine -> waker -> events , ( zend_ulong ) event ) != NULL ;
785+ return zend_hash_index_find (& coroutine -> waker -> events , ptr_to_index ( event ) ) != NULL ;
775786}
776787
777788ZEND_API void zend_async_resume_when (zend_coroutine_t * coroutine , zend_async_event_t * event ,
@@ -835,7 +846,7 @@ ZEND_API void zend_async_resume_when(zend_coroutine_t *coroutine, zend_async_eve
835846 }
836847
837848 if (EXPECTED (coroutine -> waker != NULL )) {
838- zval * trigger_zval = zend_hash_index_find (& coroutine -> waker -> events , ( zend_ulong ) event );
849+ zval * trigger_zval = zend_hash_index_find (& coroutine -> waker -> events , ptr_to_index ( event ) );
839850 zend_async_waker_trigger_t * trigger ;
840851
841852 if (UNEXPECTED (trigger_zval != NULL )) {
@@ -850,7 +861,7 @@ ZEND_API void zend_async_resume_when(zend_coroutine_t *coroutine, zend_async_eve
850861 trigger = waker_trigger_add_callback (trigger , & event_callback -> base );
851862
852863 if (UNEXPECTED (zend_hash_index_add_ptr (
853- & coroutine -> waker -> events , ( zend_ulong ) event , trigger )
864+ & coroutine -> waker -> events , ptr_to_index ( event ) , trigger )
854865 == NULL )) {
855866 // This should not happen with new events, but handle gracefully
856867 efree (trigger );
0 commit comments