Skip to content

Commit c958650

Browse files
committed
Add add/del ref FCC, FCC equals and FCC call APIs
1 parent 7443650 commit c958650

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

Zend/zend_API.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4145,6 +4145,26 @@ ZEND_API zend_result zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_
41454145
}
41464146
/* }}} */
41474147

4148+
ZEND_API zval* zend_get_callable_zval_from_fcc(const zend_fcall_info_cache *fcc)
4149+
{
4150+
zval *callable = emalloc(sizeof(zval));
4151+
if (fcc->closure) {
4152+
ZVAL_OBJ_COPY(callable, fcc->closure);
4153+
} else if (fcc->function_handler->common.scope) {
4154+
array_init(callable);
4155+
if (fcc->object) {
4156+
GC_ADDREF(fcc->object);
4157+
add_next_index_object(callable, fcc->object);
4158+
} else {
4159+
add_next_index_str(callable, zend_string_copy(fcc->calling_scope->name));
4160+
}
4161+
add_next_index_str(callable, zend_string_copy(fcc->function_handler->common.function_name));
4162+
} else {
4163+
ZVAL_STR_COPY(callable, fcc->function_handler->common.function_name);
4164+
}
4165+
return callable;
4166+
}
4167+
41484168
ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */
41494169
{
41504170
zend_string *lname;

Zend/zend_API.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ typedef struct _zend_fcall_info_cache {
328328
zend_class_backed_enum_table(ce)
329329

330330
#define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0)
331+
#define ZEND_FCC_INITIALIZED(fcc) ((fcc).function_handler != NULL)
331332

332333
ZEND_API int zend_next_free_module(void);
333334

@@ -729,6 +730,36 @@ ZEND_API void zend_fcall_info_argn(zend_fcall_info *fci, uint32_t argc, ...);
729730
*/
730731
ZEND_API zend_result zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval, zval *args);
731732

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+
732763
/* Can only return FAILURE if EG(active) is false during late engine shutdown.
733764
* If the call or call setup throws, EG(exception) will be set and the retval
734765
* will be UNDEF. Otherwise, the retval will be a non-UNDEF value. */
@@ -751,6 +782,12 @@ ZEND_API void zend_call_known_function(
751782
zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
752783
uint32_t param_count, zval *params, HashTable *named_params);
753784

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+
754791
/* Call the provided zend_function instance method on an object. */
755792
static zend_always_inline void zend_call_known_instance_method(
756793
zend_function *fn, zend_object *object, zval *retval_ptr,

0 commit comments

Comments
 (0)