Skip to content

Commit 50a2de7

Browse files
committed
Do not build unnecessary FCI in Reflection
1 parent c9cbe52 commit 50a2de7

File tree

1 file changed

+20
-65
lines changed

1 file changed

+20
-65
lines changed

ext/reflection/php_reflection.c

+20-65
Original file line numberDiff line numberDiff line change
@@ -1973,9 +1973,8 @@ ZEND_METHOD(ReflectionFunction, invoke)
19731973
{
19741974
zval retval;
19751975
zval *params;
1976-
int result, num_args;
1976+
uint32_t num_args;
19771977
HashTable *named_params;
1978-
zend_fcall_info fci;
19791978
zend_fcall_info_cache fcc;
19801979
reflection_object *intern;
19811980
zend_function *fptr;
@@ -1986,14 +1985,6 @@ ZEND_METHOD(ReflectionFunction, invoke)
19861985

19871986
GET_REFLECTION_OBJECT_PTR(fptr);
19881987

1989-
fci.size = sizeof(fci);
1990-
ZVAL_UNDEF(&fci.function_name);
1991-
fci.object = NULL;
1992-
fci.retval = &retval;
1993-
fci.param_count = num_args;
1994-
fci.params = params;
1995-
fci.named_params = named_params;
1996-
19971988
fcc.function_handler = fptr;
19981989
fcc.called_scope = NULL;
19991990
fcc.object = NULL;
@@ -2003,29 +1994,25 @@ ZEND_METHOD(ReflectionFunction, invoke)
20031994
Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0);
20041995
}
20051996

2006-
result = zend_call_function(&fci, &fcc);
1997+
zend_call_known_fcc(&fcc, &retval, num_args, params, named_params);
20071998

2008-
if (result == FAILURE) {
1999+
if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) {
20092000
zend_throw_exception_ex(reflection_exception_ptr, 0,
20102001
"Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
20112002
RETURN_THROWS();
20122003
}
20132004

2014-
if (Z_TYPE(retval) != IS_UNDEF) {
2015-
if (Z_ISREF(retval)) {
2016-
zend_unwrap_reference(&retval);
2017-
}
2018-
ZVAL_COPY_VALUE(return_value, &retval);
2005+
if (Z_ISREF(retval)) {
2006+
zend_unwrap_reference(&retval);
20192007
}
2008+
ZVAL_COPY_VALUE(return_value, &retval);
20202009
}
20212010
/* }}} */
20222011

20232012
/* {{{ Invokes the function and pass its arguments as array. */
20242013
ZEND_METHOD(ReflectionFunction, invokeArgs)
20252014
{
20262015
zval retval;
2027-
int result;
2028-
zend_fcall_info fci;
20292016
zend_fcall_info_cache fcc;
20302017
reflection_object *intern;
20312018
zend_function *fptr;
@@ -2037,14 +2024,6 @@ ZEND_METHOD(ReflectionFunction, invokeArgs)
20372024

20382025
GET_REFLECTION_OBJECT_PTR(fptr);
20392026

2040-
fci.size = sizeof(fci);
2041-
ZVAL_UNDEF(&fci.function_name);
2042-
fci.object = NULL;
2043-
fci.retval = &retval;
2044-
fci.param_count = 0;
2045-
fci.params = NULL;
2046-
fci.named_params = params;
2047-
20482027
fcc.function_handler = fptr;
20492028
fcc.called_scope = NULL;
20502029
fcc.object = NULL;
@@ -2054,20 +2033,18 @@ ZEND_METHOD(ReflectionFunction, invokeArgs)
20542033
Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0);
20552034
}
20562035

2057-
result = zend_call_function(&fci, &fcc);
2036+
zend_call_known_fcc(&fcc, &retval, /* num_params */ 0, /* params */ NULL, params);
20582037

2059-
if (result == FAILURE) {
2038+
if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) {
20602039
zend_throw_exception_ex(reflection_exception_ptr, 0,
20612040
"Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
20622041
RETURN_THROWS();
20632042
}
20642043

2065-
if (Z_TYPE(retval) != IS_UNDEF) {
2066-
if (Z_ISREF(retval)) {
2067-
zend_unwrap_reference(&retval);
2068-
}
2069-
ZVAL_COPY_VALUE(return_value, &retval);
2044+
if (Z_ISREF(retval)) {
2045+
zend_unwrap_reference(&retval);
20702046
}
2047+
ZVAL_COPY_VALUE(return_value, &retval);
20712048
}
20722049
/* }}} */
20732050

@@ -3360,10 +3337,8 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
33603337
zval *params = NULL, *object;
33613338
HashTable *named_params = NULL;
33623339
reflection_object *intern;
3363-
zend_function *mptr;
3364-
int argc = 0, result;
3365-
zend_fcall_info fci;
3366-
zend_fcall_info_cache fcc;
3340+
zend_function *mptr, *callback;
3341+
uint32_t argc = 0;
33673342
zend_class_entry *obj_ce;
33683343

33693344
GET_REFLECTION_OBJECT_PTR(mptr);
@@ -3413,40 +3388,20 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
34133388
RETURN_THROWS();
34143389
}
34153390
}
3391+
/* Copy the zend_function when calling via handler (e.g. Closure::__invoke()) */
3392+
callback = _copy_function(mptr);
3393+
zend_call_known_function(callback, (object ? Z_OBJ_P(object) : NULL), intern->ce, &retval, argc, params, named_params);
34163394

3417-
fci.size = sizeof(fci);
3418-
ZVAL_UNDEF(&fci.function_name);
3419-
fci.object = object ? Z_OBJ_P(object) : NULL;
3420-
fci.retval = &retval;
3421-
fci.param_count = argc;
3422-
fci.params = params;
3423-
fci.named_params = named_params;
3424-
3425-
fcc.function_handler = mptr;
3426-
fcc.called_scope = intern->ce;
3427-
fcc.object = object ? Z_OBJ_P(object) : NULL;
3428-
3429-
/*
3430-
* Copy the zend_function when calling via handler (e.g. Closure::__invoke())
3431-
*/
3432-
if ((mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
3433-
fcc.function_handler = _copy_function(mptr);
3434-
}
3435-
3436-
result = zend_call_function(&fci, &fcc);
3437-
3438-
if (result == FAILURE) {
3395+
if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) {
34393396
zend_throw_exception_ex(reflection_exception_ptr, 0,
34403397
"Invocation of method %s::%s() failed", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
34413398
RETURN_THROWS();
34423399
}
34433400

3444-
if (Z_TYPE(retval) != IS_UNDEF) {
3445-
if (Z_ISREF(retval)) {
3446-
zend_unwrap_reference(&retval);
3447-
}
3448-
ZVAL_COPY_VALUE(return_value, &retval);
3401+
if (Z_ISREF(retval)) {
3402+
zend_unwrap_reference(&retval);
34493403
}
3404+
ZVAL_COPY_VALUE(return_value, &retval);
34503405
}
34513406
/* }}} */
34523407

0 commit comments

Comments
 (0)