@@ -923,9 +923,7 @@ static void zend_ffi_callback_hash_dtor(zval *zv) /* {{{ */
923923 zend_ffi_callback_data * callback_data = Z_PTR_P (zv );
924924
925925 ffi_closure_free (callback_data -> callback );
926- if (callback_data -> fcc .function_handler -> common .fn_flags & ZEND_ACC_CLOSURE ) {
927- OBJ_RELEASE (ZEND_CLOSURE_OBJECT (callback_data -> fcc .function_handler ));
928- }
926+ zend_fcc_dtor (& callback_data -> fcc );
929927 for (int i = 0 ; i < callback_data -> arg_count ; ++ i ) {
930928 if (callback_data -> arg_types [i ]-> type == FFI_TYPE_STRUCT ) {
931929 efree (callback_data -> arg_types [i ]);
@@ -941,43 +939,34 @@ static void zend_ffi_callback_hash_dtor(zval *zv) /* {{{ */
941939static void zend_ffi_callback_trampoline (ffi_cif * cif , void * ret , void * * args , void * data ) /* {{{ */
942940{
943941 zend_ffi_callback_data * callback_data = (zend_ffi_callback_data * )data ;
944- zend_fcall_info fci ;
942+ zval * params ;
945943 zend_ffi_type * ret_type ;
946944 zval retval ;
947945 ALLOCA_FLAG (use_heap )
948946
949- fci .size = sizeof (zend_fcall_info );
950- ZVAL_UNDEF (& fci .function_name );
951- fci .retval = & retval ;
952- fci .params = do_alloca (sizeof (zval ) * callback_data -> arg_count , use_heap );
953- fci .object = NULL ;
954- fci .param_count = callback_data -> arg_count ;
955- fci .named_params = NULL ;
947+ params = do_alloca (sizeof (zval ) * callback_data -> arg_count , use_heap );
956948
957949 if (callback_data -> type -> func .args ) {
958950 int n = 0 ;
959951 zend_ffi_type * arg_type ;
960952
961953 ZEND_HASH_PACKED_FOREACH_PTR (callback_data -> type -> func .args , arg_type ) {
962954 arg_type = ZEND_FFI_TYPE (arg_type );
963- zend_ffi_cdata_to_zval (NULL , args [n ], arg_type , BP_VAR_R , & fci . params [n ], (zend_ffi_flags )(arg_type -> attr & ZEND_FFI_ATTR_CONST ), 0 , 0 );
955+ zend_ffi_cdata_to_zval (NULL , args [n ], arg_type , BP_VAR_R , & params [n ], (zend_ffi_flags )(arg_type -> attr & ZEND_FFI_ATTR_CONST ), 0 , 0 );
964956 n ++ ;
965957 } ZEND_HASH_FOREACH_END ();
966958 }
967959
968- ZVAL_UNDEF (& retval );
969- if (zend_call_function (& fci , & callback_data -> fcc ) != SUCCESS ) {
970- zend_throw_error (zend_ffi_exception_ce , "Cannot call callback" );
971- }
960+ zend_call_known_fcc (& callback_data -> fcc , & retval , callback_data -> arg_count , params , NULL );
972961
973962 if (callback_data -> arg_count ) {
974963 int n = 0 ;
975964
976965 for (n = 0 ; n < callback_data -> arg_count ; n ++ ) {
977- zval_ptr_dtor (& fci . params [n ]);
966+ zval_ptr_dtor (& params [n ]);
978967 }
979968 }
980- free_alloca (fci . params , use_heap );
969+ free_alloca (params , use_heap );
981970
982971 if (EG (exception )) {
983972 zend_error_noreturn (E_ERROR , "Throwing from FFI callbacks is not allowed" );
@@ -1035,12 +1024,14 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
10351024 arg_count = type -> func .args ? zend_hash_num_elements (type -> func .args ) : 0 ;
10361025 if (arg_count < fcc .function_handler -> common .required_num_args ) {
10371026 zend_throw_error (zend_ffi_exception_ce , "Attempt to assign an invalid callback, insufficient number of arguments" );
1027+ zend_release_fcall_info_cache (& fcc );
10381028 return NULL ;
10391029 }
10401030
10411031 callback = ffi_closure_alloc (sizeof (ffi_closure ), & code );
10421032 if (!callback ) {
10431033 zend_throw_error (zend_ffi_exception_ce , "Cannot allocate callback" );
1034+ zend_release_fcall_info_cache (& fcc );
10441035 return NULL ;
10451036 }
10461037
@@ -1067,6 +1058,7 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
10671058 }
10681059 efree (callback_data );
10691060 ffi_closure_free (callback );
1061+ zend_release_fcall_info_cache (& fcc );
10701062 return NULL ;
10711063 }
10721064 n ++ ;
@@ -1082,6 +1074,7 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
10821074 }
10831075 efree (callback_data );
10841076 ffi_closure_free (callback );
1077+ zend_release_fcall_info_cache (& fcc );
10851078 return NULL ;
10861079 }
10871080
@@ -1103,6 +1096,7 @@ free_on_failure: ;
11031096 }
11041097 efree (callback_data );
11051098 ffi_closure_free (callback );
1099+ zend_release_fcall_info_cache (& fcc );
11061100 return NULL ;
11071101 }
11081102
@@ -1112,9 +1106,7 @@ free_on_failure: ;
11121106 }
11131107 zend_hash_next_index_insert_ptr (FFI_G (callbacks ), callback_data );
11141108
1115- if (fcc .function_handler -> common .fn_flags & ZEND_ACC_CLOSURE ) {
1116- GC_ADDREF (ZEND_CLOSURE_OBJECT (fcc .function_handler ));
1117- }
1109+ zend_fcc_addref (& callback_data -> fcc );
11181110
11191111 return code ;
11201112}
0 commit comments