@@ -468,7 +468,6 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler,
468468 char * error = NULL ;
469469 php_output_handler * handler = NULL ;
470470 php_output_handler_alias_ctor_t alias = NULL ;
471- php_output_handler_user_func_t * user = NULL ;
472471
473472 switch (Z_TYPE_P (output_handler )) {
474473 case IS_NULL :
@@ -480,22 +479,23 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler,
480479 break ;
481480 }
482481 ZEND_FALLTHROUGH ;
483- default :
484- user = ecalloc (1 , sizeof (php_output_handler_user_func_t ));
485- if (SUCCESS == zend_fcall_info_init (output_handler , 0 , & user -> fci , & user -> fcc , & handler_name , & error )) {
482+ default : {
483+ zend_fcall_info_cache * fcc = ecalloc (1 , sizeof (* fcc ));
484+
485+ if (zend_is_callable_ex (output_handler , NULL , 0 , & handler_name , fcc , & error )) {
486486 handler = php_output_handler_init (handler_name , chunk_size , PHP_OUTPUT_HANDLER_ABILITY_FLAGS (flags ) | PHP_OUTPUT_HANDLER_USER );
487- ZVAL_COPY ( & user -> zoh , output_handler );
488- handler -> func .user = user ;
487+ zend_fcc_addref ( fcc );
488+ handler -> func .user_fcc = fcc ;
489489 } else {
490- efree (user );
491- }
492- if (error ) {
490+ efree (fcc );
491+ ZEND_ASSERT (error );
493492 php_error_docref ("ref.outcontrol" , E_WARNING , "%s" , error );
494493 efree (error );
495494 }
496495 if (handler_name ) {
497496 zend_string_release_ex (handler_name , 0 );
498497 }
498+ }
499499 }
500500
501501 return handler ;
@@ -707,8 +707,8 @@ PHPAPI void php_output_handler_dtor(php_output_handler *handler)
707707 efree (handler -> buffer .data );
708708 }
709709 if (handler -> flags & PHP_OUTPUT_HANDLER_USER ) {
710- zval_ptr_dtor ( & handler -> func .user -> zoh );
711- efree (handler -> func .user );
710+ zend_fcc_dtor ( handler -> func .user_fcc );
711+ efree (handler -> func .user_fcc );
712712 }
713713 if (handler -> dtor && handler -> opaq ) {
714714 handler -> dtor (handler -> opaq );
@@ -966,13 +966,12 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
966966 /* ob_mode */
967967 ZVAL_LONG (& ob_args [1 ], (zend_long ) context -> op );
968968
969- /* Set FCI info */
970- handler -> func .user -> fci .param_count = 2 ;
971- handler -> func .user -> fci .params = ob_args ;
972- handler -> func .user -> fci .retval = & retval ;
973- handler -> func .user -> fci .consumed_args = zend_fci_consumed_arg (0 );
969+ zend_call_known_fcc_ex (handler -> func .user_fcc , & retval , 2 , ob_args , NULL , zend_fci_consumed_arg (0 ));
974970
975- if (SUCCESS == zend_call_function (& handler -> func .user -> fci , & handler -> func .user -> fcc ) && Z_TYPE (retval ) != IS_UNDEF ) {
971+ zval_ptr_dtor (& ob_args [0 ]);
972+ zval_ptr_dtor (& ob_args [1 ]);
973+
974+ if (Z_TYPE (retval ) != IS_UNDEF ) {
976975 if (handler -> flags & PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT ) {
977976 // Make sure that we don't get lost in the current output buffer
978977 // by disabling it
@@ -1027,8 +1026,6 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
10271026 }
10281027
10291028 /* Free arguments and return value */
1030- zval_ptr_dtor (& ob_args [0 ]);
1031- zval_ptr_dtor (& ob_args [1 ]);
10321029 zval_ptr_dtor (& retval );
10331030
10341031 } else {
0 commit comments