@@ -747,20 +747,42 @@ ZEND_API void zend_fcall_info_argn(zend_fcall_info *fci, uint32_t argc, ...);
747747ZEND_API zend_result zend_fcall_info_call (zend_fcall_info * fci , zend_fcall_info_cache * fcc , zval * retval , zval * args );
748748
749749/* Zend FCC API to store and handle PHP userland functions */
750+ static zend_always_inline bool zend_fcc_closure_objects_equals (zend_object * closure1 , zend_object * closure2 )
751+ {
752+ extern ZEND_API zend_class_entry * zend_ce_closure ;
753+ zval closure_zv1 , closure_zv2 ;
754+
755+ if (closure1 == closure2 ) {
756+ return true;
757+ }
758+ if (!closure1 || !closure2 ) {
759+ return false;
760+ }
761+ if (closure1 -> ce != zend_ce_closure || closure2 -> ce != zend_ce_closure ) {
762+ return false;
763+ }
764+
765+ ZVAL_OBJ (& closure_zv1 , closure1 );
766+ ZVAL_OBJ (& closure_zv2 , closure2 );
767+
768+ return zend_compare_objects (& closure_zv1 , & closure_zv2 ) == 0 ;
769+ }
770+
750771static zend_always_inline bool zend_fcc_equals (const zend_fcall_info_cache * a , const zend_fcall_info_cache * b )
751772{
773+ if (a -> closure || b -> closure ) {
774+ return zend_fcc_closure_objects_equals (a -> closure , b -> closure );
775+ }
752776 if (UNEXPECTED ((a -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ) &&
753777 (b -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ))) {
754778 return a -> object == b -> object
755779 && a -> calling_scope == b -> calling_scope
756- && a -> closure == b -> closure
757780 && zend_string_equals (a -> function_handler -> common .function_name , b -> function_handler -> common .function_name )
758781 ;
759782 }
760783 return a -> function_handler == b -> function_handler
761784 && a -> object == b -> object
762785 && a -> calling_scope == b -> calling_scope
763- && a -> closure == b -> closure
764786 ;
765787}
766788
0 commit comments