Commit 046596102d6 for php.net
commit 046596102d607518ca7e629f949a91f853eddaeb
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date: Thu Jul 2 13:32:09 2026 -0700
`ReflectionFunctionAbstract::getClosureUsedVariables()`: optimize arrays
Avoid `array_init(return_value);` in cases where the function does not
correspond to a closure or has no static variables, to avoid an unneeded
allocation for an array that will be empty.
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index a336ab5b885..69ce3ae8a93 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -1862,44 +1862,47 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureUsedVariables)
ZEND_PARSE_PARAMETERS_NONE();
GET_REFLECTION_OBJECT();
- array_init(return_value);
- if (!Z_ISUNDEF(intern->obj)) {
- closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj));
- if (closure_func == NULL ||
- closure_func->type != ZEND_USER_FUNCTION ||
- closure_func->op_array.static_variables == NULL) {
- return;
- }
+ if (Z_ISUNDEF(intern->obj)) {
+ RETURN_EMPTY_ARRAY();
+ }
- const zend_op_array *ops = &closure_func->op_array;
+ closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj));
+ if (closure_func == NULL ||
+ closure_func->type != ZEND_USER_FUNCTION ||
+ closure_func->op_array.static_variables == NULL
+ ) {
+ RETURN_EMPTY_ARRAY();
+ }
- HashTable *static_variables = ZEND_MAP_PTR_GET(ops->static_variables_ptr);
+ const zend_op_array *ops = &closure_func->op_array;
- if (!static_variables) {
- return;
- }
+ HashTable *static_variables = ZEND_MAP_PTR_GET(ops->static_variables_ptr);
- zend_op *opline = ops->opcodes + ops->num_args;
- if (ops->fn_flags & ZEND_ACC_VARIADIC) {
- opline++;
- }
+ if (!static_variables) {
+ RETURN_EMPTY_ARRAY();
+ }
- for (; opline->opcode == ZEND_BIND_STATIC; opline++) {
- if (!(opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) {
- continue;
- }
+ array_init(return_value);
+ zend_op *opline = ops->opcodes + ops->num_args;
+ if (ops->fn_flags & ZEND_ACC_VARIADIC) {
+ opline++;
+ }
- Bucket *bucket = (Bucket*)
- (((char*)static_variables->arData) +
- (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
+ for (; opline->opcode == ZEND_BIND_STATIC; opline++) {
+ if (!(opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) {
+ continue;
+ }
- if (Z_ISUNDEF(bucket->val)) {
- continue;
- }
+ Bucket *bucket = (Bucket*)
+ (((char*)static_variables->arData) +
+ (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
- zend_hash_add_new(Z_ARRVAL_P(return_value), bucket->key, &bucket->val);
- Z_TRY_ADDREF(bucket->val);
+ if (Z_ISUNDEF(bucket->val)) {
+ continue;
}
+
+ zend_hash_add_new(Z_ARRVAL_P(return_value), bucket->key, &bucket->val);
+ Z_TRY_ADDREF(bucket->val);
}
} /* }}} */