@@ -328,6 +328,7 @@ typedef struct _zend_fcall_info_cache {
328
328
zend_class_backed_enum_table(ce)
329
329
330
330
#define ZEND_FCI_INITIALIZED (fci ) ((fci).size != 0)
331
+ #define ZEND_FCC_INITIALIZED (fcc ) ((fcc).function_handler != NULL)
331
332
332
333
ZEND_API int zend_next_free_module (void );
333
334
@@ -729,6 +730,36 @@ ZEND_API void zend_fcall_info_argn(zend_fcall_info *fci, uint32_t argc, ...);
729
730
*/
730
731
ZEND_API zend_result zend_fcall_info_call (zend_fcall_info * fci , zend_fcall_info_cache * fcc , zval * retval , zval * args );
731
732
733
+ /* Zend FCC API to store and handle PHP userland functions */
734
+ static zend_always_inline bool zend_fcc_equals (const zend_fcall_info_cache * a , const zend_fcall_info_cache * b )
735
+ {
736
+ return a -> function_handler == b -> function_handler
737
+ && a -> object == b -> object
738
+ && a -> calling_scope == b -> calling_scope
739
+ && a -> closure == b -> closure
740
+ ;
741
+ }
742
+ static zend_always_inline void zend_fcc_addref (zend_fcall_info_cache * fcc )
743
+ {
744
+ if (fcc -> object ) {
745
+ GC_ADDREF (fcc -> object );
746
+ }
747
+ if (fcc -> closure ) {
748
+ GC_ADDREF (fcc -> closure );
749
+ }
750
+ }
751
+ static zend_always_inline void zend_fcc_delref (zend_fcall_info_cache * fcc )
752
+ {
753
+ if (fcc -> object ) {
754
+ OBJ_RELEASE (fcc -> object );
755
+ }
756
+ if (fcc -> closure ) {
757
+ OBJ_RELEASE (fcc -> closure );
758
+ }
759
+ }
760
+
761
+ ZEND_API zval * zend_get_callable_zval_from_fcc (const zend_fcall_info_cache * fcc );
762
+
732
763
/* Can only return FAILURE if EG(active) is false during late engine shutdown.
733
764
* If the call or call setup throws, EG(exception) will be set and the retval
734
765
* will be UNDEF. Otherwise, the retval will be a non-UNDEF value. */
@@ -751,6 +782,12 @@ ZEND_API void zend_call_known_function(
751
782
zend_function * fn , zend_object * object , zend_class_entry * called_scope , zval * retval_ptr ,
752
783
uint32_t param_count , zval * params , HashTable * named_params );
753
784
785
+ static zend_always_inline void zend_call_known_fcc (
786
+ zend_fcall_info_cache * fcc , zval * retval_ptr , uint32_t param_count , zval * params , HashTable * named_params )
787
+ {
788
+ zend_call_known_function (fcc -> function_handler , fcc -> object , fcc -> called_scope , retval_ptr , param_count , params , named_params );
789
+ }
790
+
754
791
/* Call the provided zend_function instance method on an object. */
755
792
static zend_always_inline void zend_call_known_instance_method (
756
793
zend_function * fn , zend_object * object , zval * retval_ptr ,
0 commit comments