mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Improve Closure::call(). Eliminate zend_fcall_info_init() call and reset ZEND_ACC_CLOSURE flag.
This commit is contained in:
parent
70aa967d81
commit
0ec631c996
1 changed files with 17 additions and 17 deletions
|
@ -114,12 +114,13 @@ ZEND_METHOD(Closure, call)
|
|||
zend_closure *closure;
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fci_cache;
|
||||
zval *my_params;
|
||||
int my_param_count = 0;
|
||||
zend_function my_function;
|
||||
zend_object *newobj;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &my_params, &my_param_count) == FAILURE) {
|
||||
fci.param_count = 0;
|
||||
fci.params = NULL;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &fci.params, &fci.param_count) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,24 +133,14 @@ ZEND_METHOD(Closure, call)
|
|||
return;
|
||||
}
|
||||
|
||||
/* This should never happen as closures will always be callable */
|
||||
if (zend_fcall_info_init(zclosure, 0, &fci, &fci_cache, NULL, NULL) != SUCCESS) {
|
||||
ZEND_ASSERT(0);
|
||||
}
|
||||
|
||||
fci.retval = &closure_result;
|
||||
fci.params = my_params;
|
||||
fci.param_count = my_param_count;
|
||||
fci.object = fci_cache.object = newobj;
|
||||
fci_cache.called_scope = Z_OBJCE_P(newthis);
|
||||
|
||||
if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) {
|
||||
if (closure->func.common.fn_flags & ZEND_ACC_GENERATOR) {
|
||||
zval new_closure;
|
||||
zend_create_closure(&new_closure, fci_cache.function_handler, Z_OBJCE_P(newthis), closure->called_scope, newthis);
|
||||
zend_create_closure(&new_closure, &closure->func, Z_OBJCE_P(newthis), closure->called_scope, newthis);
|
||||
closure = (zend_closure *) Z_OBJ(new_closure);
|
||||
fci_cache.function_handler = &closure->func;
|
||||
} else {
|
||||
memcpy(&my_function, fci_cache.function_handler, fci_cache.function_handler->type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function));
|
||||
memcpy(&my_function, &closure->func, closure->func.type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function));
|
||||
my_function.common.fn_flags &= ~ZEND_ACC_CLOSURE;
|
||||
/* use scope of passed object */
|
||||
my_function.common.scope = Z_OBJCE_P(newthis);
|
||||
fci_cache.function_handler = &my_function;
|
||||
|
@ -161,6 +152,15 @@ ZEND_METHOD(Closure, call)
|
|||
}
|
||||
}
|
||||
|
||||
fci_cache.calling_scope = closure->called_scope;
|
||||
fci_cache.called_scope = newobj->ce;
|
||||
fci_cache.object = fci.object = newobj;
|
||||
|
||||
fci.size = sizeof(fci);
|
||||
ZVAL_COPY_VALUE(&fci.function_name, zclosure);
|
||||
fci.retval = &closure_result;
|
||||
fci.no_separation = 1;
|
||||
|
||||
if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) {
|
||||
if (Z_ISREF(closure_result)) {
|
||||
zend_unwrap_reference(&closure_result);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue