Skip to content

Commit e40543a

Browse files
authored
zend_closures.c: In Closure::__invoke() call the closure directly (#17372)
This prevents a bunch of indirection which ultimately calls `zend_closure_get_closure()` anyway via the `get_closure` object handler.
1 parent 17ea79b commit e40543a

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

Zend/zend_closures.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ typedef struct _zend_closure {
4040
ZEND_API zend_class_entry *zend_ce_closure;
4141
static zend_object_handlers closure_handlers;
4242

43+
static zend_result zend_closure_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only);
44+
4345
ZEND_METHOD(Closure, __invoke) /* {{{ */
4446
{
4547
zend_function *func = EX(func);
@@ -51,9 +53,12 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
5153
Z_PARAM_VARIADIC_WITH_NAMED(args, num_args, named_args)
5254
ZEND_PARSE_PARAMETERS_END();
5355

54-
if (call_user_function_named(CG(function_table), NULL, ZEND_THIS, return_value, num_args, args, named_args) == FAILURE) {
55-
RETVAL_FALSE;
56-
}
56+
zend_fcall_info_cache fcc = {
57+
.closure = Z_OBJ_P(ZEND_THIS),
58+
};
59+
zend_closure_get_closure(Z_OBJ_P(ZEND_THIS), &fcc.calling_scope, &fcc.function_handler, &fcc.object, false);
60+
fcc.called_scope = fcc.calling_scope;
61+
zend_call_known_fcc(&fcc, return_value, num_args, args, named_args);
5762

5863
/* destruct the function also, then - we have allocated it in get_method */
5964
zend_string_release_ex(func->internal_function.function_name, 0);

0 commit comments

Comments
 (0)