Skip to content

Commit 7b302fc

Browse files
committed
Add consumed_args support for fcall arguments
1 parent a83c025 commit 7b302fc

File tree

6 files changed

+17
-1
lines changed

6 files changed

+17
-1
lines changed

Zend/zend_API.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,6 +4238,7 @@ ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags,
42384238
fci->param_count = 0;
42394239
fci->params = NULL;
42404240
fci->named_params = NULL;
4241+
fci->consumed_args = 0;
42414242

42424243
return SUCCESS;
42434244
}

Zend/zend_API.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct _zend_fcall_info {
4949
zval *params;
5050
zend_object *object;
5151
uint32_t param_count;
52+
uint32_t consumed_args;
5253
/* This hashtable can also contain positional arguments (with integer keys),
5354
* which will be appended to the normal params[]. This makes it easier to
5455
* integrate APIs like call_user_func_array(). The usual restriction that

Zend/zend_closures.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ ZEND_METHOD(Closure, call)
155155
fci_cache.object = fci.object = newobj;
156156

157157
fci.size = sizeof(fci);
158+
fci.consumed_args = 0;
158159
ZVAL_OBJ(&fci.function_name, &closure->std);
159160
ZVAL_UNDEF(&closure_result);
160161
fci.retval = &closure_result;

Zend/zend_execute_API.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re
797797
fci.param_count = param_count;
798798
fci.params = params;
799799
fci.named_params = named_params;
800+
fci.consumed_args = 0;
800801

801802
return zend_call_function(&fci, NULL);
802803
}
@@ -905,7 +906,16 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_
905906
}
906907

907908
if (EXPECTED(!must_wrap)) {
908-
ZVAL_COPY(param, arg);
909+
if (EXPECTED(fci->consumed_args == 0)) {
910+
ZVAL_COPY(param, arg);
911+
} else {
912+
if (i < 32 && (fci->consumed_args & (1u << i)) && !Z_ISREF_P(arg) && arg == &fci->params[i]) {
913+
ZVAL_COPY_VALUE(param, arg);
914+
ZVAL_UNDEF(arg);
915+
} else {
916+
ZVAL_COPY(param, arg);
917+
}
918+
}
909919
} else {
910920
Z_TRY_ADDREF_P(arg);
911921
ZVAL_NEW_REF(param, arg);
@@ -1091,6 +1101,7 @@ ZEND_API void zend_call_known_function(
10911101
fci.param_count = param_count;
10921102
fci.params = params;
10931103
fci.named_params = named_params;
1104+
fci.consumed_args = 0;
10941105
ZVAL_UNDEF(&fci.function_name); /* Unused */
10951106

10961107
fcic.function_handler = fn;

ext/dom/xpath_callbacks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat
408408
fci.param_count = param_count;
409409
fci.params = params;
410410
fci.named_params = NULL;
411+
fci.consumed_args = 0;
411412
ZVAL_STRINGL(&fci.function_name, function_name, function_name_length);
412413

413414
zend_call_function(&fci, NULL);

ext/ffi/ffi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v
950950
fci.object = NULL;
951951
fci.param_count = callback_data->arg_count;
952952
fci.named_params = NULL;
953+
fci.consumed_args = 0;
953954

954955
if (callback_data->type->func.args) {
955956
int n = 0;

0 commit comments

Comments
 (0)