-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflection: show the type of object constants used as default properties #15922
Conversation
dc0b08e
to
d20a362
Compare
d20a362
to
80e5784
Compare
Somehow, the updated tests were run on an older version of the patch?
I'll rebase the patch so that the tests run again, I have no idea how this could even happen |
80e5784
to
ca134b1
Compare
Yeah the tests pass locally, don't know what went wrong in CI. The idea of the patch seems good to me. |
Okay - I figured since this was kind of a new feature I should target master, but I'll switch (lesson learned from 16192 - force push before changing target branch) |
When a property default is based on a global constant, show the type of the default. Previously, `format_default_value()` assumed that non-scalar and non-array defaults were always going to be `IS_CONSTANT_AST` pointers, and when the AST expression had been evaluated and produced an object, depending on when the `ReflectionClass` or `ReflectionProperty` instance had been created, the default was shown as one of `callable`, `__CLASS__`, or `...`. Instead, if the default value is an object (`IS_OBJECT`), show the type of that object. Add test cases for each of the `callable`, `__CLASS__`, and `...` cases to confirm that they all now properly show the type of the constant. Closes phpgh-15902
ca134b1
to
033eec7
Compare
Split from patch in phpGH-15922 since lazy ghosts are 8.4+
Well, this got ugly, since until 998bce1 there was already an IS_OBJECT handling, so the news entry is kind of misleading (it wasn't going to be a core dump, just an assertion failure, and I'm not sure the reproduction cases would have had the output I claimed) and the change was weird. When this is upmerged to 8.4, please keep the IS_OBJECT check with
when rebasing past 998bce1. I sent #16490 for the lazy ghost tests |
@nielsdos (or someone else with rights) can you re-trigger the github actions? It seems that when I changed the target branch those didn't trigger jobs to run again, so only circleci is actually testing |
033eec7
to
55e7000
Compare
Thanks, but again CI is somehow reflecting an old version of the patch...??? |
No, it's more likely to be related to the configuration, e.g. opcache/jit. |
Oh, I guess it isn't using the old version that is searching for the constant name, but rather it isn't an object (IS_OBJECT) when tested and so the IS_CONSTANT_AST is still reached - not sure how to fix this, I'm not very familiar with opcache/jit |
Try: diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index cbb071626a..88ca1cd634 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -884,7 +884,10 @@ static zval *property_get_default(zend_property_info *prop_info) {
ZVAL_DEINDIRECT(prop);
return prop;
} else {
- return &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
+ if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
+ return &EG(uninitialized_zval);
+ }
+ return &CE_DEFAULT_PROPERTIES_TABLE(ce)[OBJ_PROP_TO_NUM(prop_info->offset)];
}
} |
55e7000
to
77b8ec1
Compare
Thanks - that works locally, lets see if GitHub CI agrees |
new C; | ||
|
||
$reflector = new ReflectionClass(C::class); | ||
var_dump( (string)$reflector ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the spaces inside parens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this can just use echo $reflector;
, the var_dump
doesn't really have a purpose.
if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { | ||
return &EG(uninitialized_zval); | ||
} | ||
return &CE_DEFAULT_PROPERTIES_TABLE(ce)[OBJ_PROP_TO_NUM(prop_info->offset)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note though that this is actually kind of breaking. We're changing the default value to show the evaluated constant, rather than the constant AST. This was already the case when not using opcache, because we're evaluating the AST in-place. However, when using opcache, the AST is locked in shm and copied into "userspace" to be evaluated there. Adjusting this makes sense IMO to match the behavior of opcache and non-opcache, but I think that's better fixed on master
.
Maybe you can propose this in a separate PR on master
, and adjust tests to disable opcache (opcache.enable_cli=0
in --INI--
).
Not sure why I didn't see notifications for the replies, but since 8.2 is no longer supported, I recreated this at #17781 incorporating the feedback from @iluuu1994 above |
When a property default is based on a global constant, show the type of the default. Previously,
format_default_value()
assumed that non-scalar and non-array defaults were always going to beIS_CONSTANT_AST
pointers, and when the AST expression had been evaluated and produced an object, depending on when theReflectionClass
orReflectionProperty
instance had been created, the default was shown as one ofcallable
,__CLASS__
, or...
.Instead, if the default value is an object (
IS_OBJECT
), show the type of that object.Add test cases for each of the
callable
,__CLASS__
, and...
cases to confirm that they all now properly show the name of the constant.Closes gh-15902