[php-src] master: Reflection: optimize closure checking

Daniel Scherzer <[email protected]> Fri, 17 Jul 2026 18:44:57 +0000
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Daniel Scherzer (DanielEScherzer)
Date: 2026-07-17T11:40:42-07:00

Commit: https://github.com/php/php-src/commit/8ddd6e38d2bad972ac95a39d0a3ece521a37ca14
Raw diff: https://github.com/php/php-src/commit/8ddd6e38d2bad972ac95a39d0a3ece521a37ca14.diff

Reflection: optimize closure checking

Optimize
- `ReflectionParameter::__construct()`
- `ReflectionClass::getMethods()`

Given that the `Closure` class is declared as `final`, for some class entry
`ce` to represent an instance of a `Closure` it must be exactly
`zend_ce_closure`. Replace the `instanceof_function()` call with a simple
pointer comparison.

Changed paths:
  M  ext/reflection/php_reflection.c


Diff:

diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 89e41a2d11aa..f8fef641f6f4 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -2574,7 +2574,8 @@ ZEND_METHOD(ReflectionParameter, __construct)
 		case IS_OBJECT: {
 				ce = Z_OBJCE_P(reference);
 
-				if (instanceof_function(ce, zend_ce_closure)) {
+				// No need for instanceof_function, the Closure class is final
+				if (ce == zend_ce_closure) {
 					fptr = (zend_function *)zend_get_closure_method_def(Z_OBJ_P(reference));
 					Z_ADDREF_P(reference);
 					is_closure = true;
@@ -4585,7 +4586,8 @@ ZEND_METHOD(ReflectionClass, getMethods)
 		_addmethod(mptr, ce, Z_ARRVAL_P(return_value), filter);
 	} ZEND_HASH_FOREACH_END();
 
-	if (instanceof_function(ce, zend_ce_closure)) {
+	// No need for instanceof_function, the Closure class is final
+	if (ce == zend_ce_closure) {
 		bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF;
 		zval obj_tmp;
 		zend_object *obj;