@@ -753,20 +753,42 @@ ZEND_API void zend_fcall_info_argn(zend_fcall_info *fci, uint32_t argc, ...);
753753ZEND_API zend_result zend_fcall_info_call (zend_fcall_info * fci , zend_fcall_info_cache * fcc , zval * retval , zval * args );
754754
755755/* Zend FCC API to store and handle PHP userland functions */
756+ static zend_always_inline bool zend_fcc_closure_objects_equals (zend_object * closure1 , zend_object * closure2 )
757+ {
758+ extern ZEND_API zend_class_entry * zend_ce_closure ;
759+ zval closure_zv1 , closure_zv2 ;
760+
761+ if (closure1 == closure2 ) {
762+ return true;
763+ }
764+ if (!closure1 || !closure2 ) {
765+ return false;
766+ }
767+ if (closure1 -> ce != zend_ce_closure || closure2 -> ce != zend_ce_closure ) {
768+ return false;
769+ }
770+
771+ ZVAL_OBJ (& closure_zv1 , closure1 );
772+ ZVAL_OBJ (& closure_zv2 , closure2 );
773+
774+ return zend_compare_objects (& closure_zv1 , & closure_zv2 ) == 0 ;
775+ }
776+
756777static zend_always_inline bool zend_fcc_equals (const zend_fcall_info_cache * a , const zend_fcall_info_cache * b )
757778{
779+ if (a -> closure || b -> closure ) {
780+ return zend_fcc_closure_objects_equals (a -> closure , b -> closure );
781+ }
758782 if (UNEXPECTED ((a -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ) &&
759783 (b -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ))) {
760784 return a -> object == b -> object
761785 && a -> calling_scope == b -> calling_scope
762- && a -> closure == b -> closure
763786 && zend_string_equals (a -> function_handler -> common .function_name , b -> function_handler -> common .function_name )
764787 ;
765788 }
766789 return a -> function_handler == b -> function_handler
767790 && a -> object == b -> object
768791 && a -> calling_scope == b -> calling_scope
769- && a -> closure == b -> closure
770792 ;
771793}
772794
0 commit comments