-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Allow assignment to properties of objects stored in constants #11788
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
Conversation
Hmm, |
Ok, I found a much simpler solution that works for this case too. |
Looking into this patch it's not clear what instructions may be changed. I guess it is only FETCH_CONST and it is probably safe to change its result from TMP to VAR, but it's defenetly not safe for other instructions (as FETCH_DIM/OBJ_R).
Adding ZEND_ASSERT(some_opline->opcode == ZEND_FETCH_CONSTANT) is going to be enough to make this clear.
These approches look worse. |
Ah, thank you for clarifying. You're right, adding an assert would certainly be more clear.
I'm still a bit confused about this. This is my understanding, please correct me if I'm wrong. Sorry if I'm missing the point. |
If you change FETCH_DIM_R/TMP to FETCH_DIM_R/VAR, the following ASSING_DIM/OBJ won't change the element of the first array anyway. In addition the behaviour of FETCH_OBJ_R/TMP -> VAR may be affected by custom object handlers. May be I'm wrong and changing TMP to VAR will work, but anyway I wouldn't recommend to do this without an extra care. |
(Title typo: -cosntants +constants) |
if ((type == BP_VAR_W || type == BP_VAR_RW)) { | ||
if (obj_node.op_type == IS_TMP_VAR) { | ||
ZEND_ASSERT(obj_ast->kind == ZEND_AST_CONST); | ||
obj_node.op_type = IS_VAR; |
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.
This means that FETCH_CONSTANT
opline has result_type IS_TMP_VAR and the following instruction use it as IS_VAR
.
<?php
class Foo {
public $array = [];
}
const FOO = new Foo();
FOO->array[] = 42;
0000 DECLARE_CONST string("FOO") zval(type=11)
0001 T1 = FETCH_CONSTANT string("FOO")
0002 V0 = FETCH_OBJ_W (dim write) V1 string("array")
0003 ASSIGN_DIM V0 NEXT
0004 OP_DATA int(42)
This may confuse some code in optimizer where we check if result and usage types are the same.
Can you also change the result_type of FETCH_CONSANT?
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.
Good catch. I wonder if at that point it's better to just adjust the VM handlers to TMPVAR
, rather than convoluting the compiler. I suppose alternatively we could use a QM_ASSIGN
here too, unless the optimizer removes it again.
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.
Do you see any problem in setting FETCH_CONSANT.result_type to IS_TMP_VAR?
I wonder if at that point it's better to just adjust the VM handlers to TMPVAR
This should introduce some overhead for all modified FETCH_..._W/RW or no?
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.
Do you see any problem in setting FETCH_CONSANT.result_type to IS_TMP_VAR?
I don't see a problem. It might just introduce slightly more complexity in the compiler.
This should introduce some overhead for all modified FETCH_..._W/RW or no?
I didn't think so, because we're changing them from VAR
to TMPVAR
. This should not actually change the specialized handlers. I will verify whether my assumption is correct. However, I will try your suggestion (changing result of FETCH_CONSTANT) first.
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.
I mean changing FETCH_CONSTANT.result_type only for this case.
ZEND_ASSERT(opline->opcode == ZEND_FETCH_CONSTANT);
opline->result_type = IS_TMP_VAR;
May be my idea is wrong.
Doesn't seem worth the trouble. |
Fixes GH-11781