Skip to content

reflection: refactor ReflectionReference to allocate a zval* - #24045

Open
Girgias wants to merge 3 commits into
php:masterfrom
Girgias:2026-10-reflection-reference-not-reuse-closure-object
Open

Girgias wants to merge 3 commits into
php:masterfrom
Girgias:2026-10-reflection-reference-not-reuse-closure-object

Conversation

@Girgias

@Girgias Girgias commented Oct 1, 2026

Copy link
Copy Markdown
Member

Rather than re-using the reflection_object.obj field that usually holds a zend_object* to a Closure.

Precondition for a future refactoring to convert the reflection_object.obj from zval to zend_object*

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is a good idea, it's kinda neat that you can store the data in the embedded zval. Having 8 extra bytes (for the type info) in the structure is not critical. Trading this for an extra allocation doesn't seem to be good for performance either, not that any of this is likely performance critical anyway

Comment thread ext/reflection/php_reflection.c Outdated
}
case REF_TYPE_REFERENCE:
zval_ptr_dtor(intern->ptr);
efree(intern->ptr);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZEND_FALLTHROUGH

@Girgias

Girgias commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

I'm not sure this is a good idea, it's kinda neat that you can store the data in the embedded zval. Having 8 extra bytes (for the type info) in the structure is not critical. Trading this for an extra allocation doesn't seem to be good for performance either, not that any of this is likely performance critical anyway

Arguably it's confusing that a zval field called "obj" is being used to store a reference, especially when the 71 other usages are all about dealing with closures. This feature is very targeted as explained from the RFC: https://wiki.php.net/rfc/reference_reflection. However there is no explanation about the odd reusing of the zval on the associated PR.

@ndossche

ndossche commented Oct 2, 2026

Copy link
Copy Markdown
Member

I'm not sure this is a good idea, it's kinda neat that you can store the data in the embedded zval. Having 8 extra bytes (for the type info) in the structure is not critical. Trading this for an extra allocation doesn't seem to be good for performance either, not that any of this is likely performance critical anyway

Arguably it's confusing that a zval field called "obj" is being used to store a reference, especially when the 71 other usages are all about dealing with closures. This feature is very targeted as explained from the RFC: https://wiki.php.net/rfc/reference_reflection. However there is no explanation about the odd reusing of the zval on the associated PR.

You could use a union then to make the code clearer

Rather than re-using the reflection_object.obj field that usually holds a zend_object* to a Closure.

Precondition for a future refactoring to convert the reflection_object.obj from zval to zend_object*
@Girgias
Girgias force-pushed the 2026-10-reflection-reference-not-reuse-closure-object branch from 0a6bf00 to 85f79d7 Compare October 2, 2026 18:11
Comment on lines +7355 to +7358
//if (Z_TYPE_P(ref) != IS_REFERENCE) {
// zend_throw_exception(reflection_exception_ptr, "Corrupted ReflectionReference object", 0);
// RETURN_THROWS();
//}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't have any tests for this case and I don't really see how this could happen.

@Girgias

Girgias commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

You could use a union then to make the code clearer

Running with the union idea to instead store a zend_reference* seems to work. Which also mean when converting the closure storage from the zval to a zend_object* we still gain the struct size reduction. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants