@@ -787,12 +787,29 @@ zend_result pmmpthread_copy_closure(const pmmpthread_ident_t* owner, zend_closur
787787 );
788788 } else {
789789 HashTable * static_variables = NULL ;
790- if (closure_obj -> func .type == ZEND_USER_FUNCTION && closure_obj -> func .op_array .static_variables != NULL ) {
791- //if this is a real closure, we need to update the static_variables from the original closure object
792- //so that the copied closure has the correct use()d variables
793- //this should not modify the original closure
794- //these have to be copied before the closure is created, to maintain the original behaviour
795- static_variables = pmmpthread_copy_statics (owner , closure_obj -> func .op_array .static_variables );
790+ #if PHP_VERSION_ID >= 80200
791+ HashTable * static_variables_ptr = NULL ;
792+ #endif
793+ if (closure_obj -> func .type == ZEND_USER_FUNCTION ){
794+ if (closure_obj -> func .op_array .static_variables != NULL ) {
795+ //if this is a real closure, we need to update the static_variables from the original closure object
796+ //so that the copied closure has the correct use()d variables
797+ //this should not modify the original closure
798+ //these have to be copied before the closure is created, to maintain the original behaviour
799+ static_variables = pmmpthread_copy_statics (owner , closure_obj -> func .op_array .static_variables );
800+ }
801+ #if PHP_VERSION_ID >= 80200
802+ //in PHP 8.5, the static_variables field is not overwritten when creating a new closure, so it may be different
803+ //than the static_variables_ptr, which will typically contain bound variables
804+ HashTable * origin_static_variables_ptr = ZEND_MAP_PTR_GET (closure_obj -> func .op_array .static_variables_ptr );
805+ if (origin_static_variables_ptr != NULL ) {
806+ if (origin_static_variables_ptr != closure_obj -> func .op_array .static_variables ) {
807+ static_variables_ptr = pmmpthread_copy_statics (owner , origin_static_variables_ptr );
808+ } else {
809+ static_variables_ptr = static_variables ;
810+ }
811+ }
812+ #endif
796813 }
797814
798815 //we don't know where the definition for this closure is, so create a definition from this copy of it
@@ -810,15 +827,15 @@ zend_result pmmpthread_copy_closure(const pmmpthread_ident_t* owner, zend_closur
810827 if (static_variables != NULL ) {
811828 zend_closure * new_closure = (zend_closure * )Z_OBJ_P (pzval );
812829 ZEND_ASSERT (new_closure -> func .type == ZEND_USER_FUNCTION );
813- if (new_closure -> func .op_array .static_variables != NULL ) {
830+ if (ZEND_MAP_PTR_GET ( new_closure -> func .op_array .static_variables_ptr ) != NULL ) {
814831 //the closure may have static_variables allocated from its original creation by zend_compile.c
815- zend_array_release (new_closure -> func .op_array .static_variables );
832+ zend_array_release (ZEND_MAP_PTR_GET ( new_closure -> func .op_array .static_variables_ptr ) );
816833 }
817834 new_closure -> func .op_array .static_variables = static_variables ;
818835#if PHP_VERSION_ID >= 80200
819836 ZEND_MAP_PTR_INIT (
820837 new_closure -> func .op_array .static_variables_ptr ,
821- new_closure -> func . op_array . static_variables
838+ static_variables_ptr
822839 );
823840#else
824841 //this is not strictly necessary for 8.1, but is here for the sake of completeness
0 commit comments