Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently since
just coming to the part of optimizing traditional ZPP (sharing part with
FAST_ZPP...).
With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if tests
didn't cover something).
At first I assumed Z_PARAM_ZVAL would keep IS_REFERENCE types, since it
doesn't do ZVAL_DEREF(), but this obviously isn't happening with references.
(It seems they're getting DEREF()'d in VM when sending params, I guess...?)
So is there never a need for ZVAL_DEREF() when parsing params? Shouldn't
have 2 FAST_ZPP ZVAL types? Otherwise, why the inconsistency zpp's 'z'?
What am I missing, if anything?? Thanks!
- Matt
Hi again,
----- Original Message -----
From: "Matt Wilmas"
Sent: Tuesday, August 11, 2015
Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently since
just coming to the part of optimizing traditional ZPP (sharing part with
FAST_ZPP...).With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if tests
didn't cover something).
Oops! No, plain zpp 'z' does not have ZVAL_DEREF() applied, of course. But
it's also using zend_parse_arg_zval_DEREF(), which is wrong... (in the case
of "z!" with reference to IS_NULL?).
At first I assumed Z_PARAM_ZVAL would keep IS_REFERENCE types, since it
doesn't do ZVAL_DEREF(), but this obviously isn't happening with
references. (It seems they're getting DEREF()'d in VM when sending params,
I guess...?)
Still stands though that IS_REFERENCE doesn't seem to get through anyway
(and would break functions). Is any ZVAL_DEREF() not necessary?
- Matt
Hi Matt,
On Tue, Aug 11, 2015 at 9:00 PM, Matt Wilmas php_lists@realplain.com
wrote:
Hi again,
----- Original Message -----
From: "Matt Wilmas"
Sent: Tuesday, August 11, 2015Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently
since just coming to the part of optimizing traditional ZPP (sharing part
with FAST_ZPP...).With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if tests
didn't cover something).Oops! No, plain zpp 'z' does not have ZVAL_DEREF() applied, of course.
But it's also using zend_parse_arg_zval_DEREF(), which is wrong... (in the
case of "z!" with reference to IS_NULL?).
Sorry. I don't understand you without context. If you think something is
wrong in current implementation - please, demonstrate it with test cases,
examples or code references. If you talk about your code, then show it.
Thanks. Dmitry.
At first I assumed Z_PARAM_ZVAL would keep IS_REFERENCE types, since it
doesn't do ZVAL_DEREF(), but this obviously isn't happening with
references. (It seems they're getting DEREF()'d in VM when sending params,
I guess...?)Still stands though that IS_REFERENCE doesn't seem to get through anyway
(and would break functions). Is any ZVAL_DEREF() not necessary?
- Matt
Hi Dmitry,
----- Original Message -----
From: "Dmitry Stogov"
Sent: Tuesday, August 11, 2015
Hi Matt,
On Tue, Aug 11, 2015 at 9:00 PM, Matt Wilmas php_lists@realplain.com
wrote:Hi again,
----- Original Message -----
From: "Matt Wilmas"
Sent: Tuesday, August 11, 2015Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently
since just coming to the part of optimizing traditional ZPP (sharing
part
with FAST_ZPP...).With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional
zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if
tests
didn't cover something).Oops! No, plain zpp 'z' does not have ZVAL_DEREF() applied, of course.
But it's also using zend_parse_arg_zval_DEREF(), which is wrong... (in
the
case of "z!" with reference to IS_NULL?).Sorry. I don't understand you without context. If you think something is
wrong in current implementation - please, demonstrate it with test cases,
examples or code references. If you talk about your code, then show it.
Sorry, thought I gave enough context and code references! I can't
demonstrate with a test case, which is why I'm asking about it. :-)
No, not my code changes (you'll have plenty of code to see soon). I'm fine
replicating the current logic exactly, as I have, but the logic of these
couple parts doesn't make sense, to me. Let me try to simplify with couple
examples...
Look at e.g. is_numeric()
or strpos()
(needle). Plain zval param parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.
Or is there no way for them (or any function?) to get a IS_REFERENCE? Then
why is there ZVAL_DEREF() in param parsing functions? We could remove it!
Which is it...?
Thanks. Dmitry.
Thanks,
Matt
On Tue, Aug 11, 2015 at 10:10 PM, Matt Wilmas php_lists@realplain.com
wrote:
Hi Dmitry,
----- Original Message -----
From: "Dmitry Stogov"
Sent: Tuesday, August 11, 2015Hi Matt,
On Tue, Aug 11, 2015 at 9:00 PM, Matt Wilmas php_lists@realplain.com
wrote:Hi again,
----- Original Message -----
From: "Matt Wilmas"
Sent: Tuesday, August 11, 2015Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently
since just coming to the part of optimizing traditional ZPP (sharing
part
with FAST_ZPP...).With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional
zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if
tests
didn't cover something).Oops! No, plain zpp 'z' does not have ZVAL_DEREF() applied, of course.
But it's also using zend_parse_arg_zval_DEREF(), which is wrong... (in
the
case of "z!" with reference to IS_NULL?).Sorry. I don't understand you without context. If you think something is
wrong in current implementation - please, demonstrate it with test cases,
examples or code references. If you talk about your code, then show it.Sorry, thought I gave enough context and code references! I can't
demonstrate with a test case, which is why I'm asking about it. :-)No, not my code changes (you'll have plenty of code to see soon). I'm
fine replicating the current logic exactly, as I have, but the logic of
these couple parts doesn't make sense, to me. Let me try to simplify with
couple examples...Look at e.g.
is_numeric()
orstrpos()
(needle). Plain zval param parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.Or is there no way for them (or any function?) to get a IS_REFERENCE?
Then why is there ZVAL_DEREF() in param parsing functions? We could
remove it!Which is it...?
Functions accepting references are specially marked in arginfo. Normal
function argument can never be IS_REFERENCE. Reference arguments are always
IS_REFERENCE. There is also a rarely used mixed mode where both are
possible. For DEREF-or-not distinction is irrelevant for normal arguments,
it's only important if an argument is already marked to accept a ref.
Nikita
Hi Nikita,
----- Original Message -----
From: "Nikita Popov"
Sent: Tuesday, August 11, 2015
On Tue, Aug 11, 2015 at 10:10 PM, Matt Wilmas php_lists@realplain.com
wrote:[...]
Look at e.g.
is_numeric()
orstrpos()
(needle). Plain zval param
parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.Or is there no way for them (or any function?) to get a IS_REFERENCE?
Then why is there ZVAL_DEREF() in param parsing functions? We could
remove it!Which is it...?
Functions accepting references are specially marked in arginfo. Normal
function argument can never be IS_REFERENCE. Reference arguments are
always
IS_REFERENCE. There is also a rarely used mixed mode where both are
possible. For DEREF-or-not distinction is irrelevant for normal arguments,
it's only important if an argument is already marked to accept a ref.
Thanks. Yeah, OK, I see ZEND_SEND_REF creates a reference (if not already),
which allows the ref'd var to be "recovered" later with ZVAL_DEREF() while
parsing. I guess that's right!
I think any by-reference argument also needs to be separated during
parsing (to not affect anything else). Is that correct logic? If so, we
can say that DEREF is only needed if also separating (which only applies to
array/string/plain zval types, AFAIK).
But what is the "rarely used mixed mode where both are possible?"
Nikita
Thanks,
Matt
On Tue, Aug 11, 2015 at 11:10 PM, Matt Wilmas php_lists@realplain.com
wrote:
Hi Dmitry,
----- Original Message -----
From: "Dmitry Stogov"
Sent: Tuesday, August 11, 2015Hi Matt,
On Tue, Aug 11, 2015 at 9:00 PM, Matt Wilmas php_lists@realplain.com
wrote:Hi again,
----- Original Message -----
From: "Matt Wilmas"
Sent: Tuesday, August 11, 2015Hi Dmitry, all,
Help me understand this. :-) It's been more puzzling to me recently
since just coming to the part of optimizing traditional ZPP (sharing
part
with FAST_ZPP...).With the FAST_ZPP inline macros, why is there a Z_PARAM_ZVAL and
Z_PARAM_ZVAL_DEREF? It seems the zpp 'z' specifier is always like
ZVAL_DEREF, right? So Z_PARAM_ZVAL has no equivalent in traditional
zpp.
At the very least, this would seem to suggest a difference in
behavior/functionality. But I haven't found any (or bug reports, if
tests
didn't cover something).Oops! No, plain zpp 'z' does not have ZVAL_DEREF() applied, of course.
But it's also using zend_parse_arg_zval_DEREF(), which is wrong... (in
the
case of "z!" with reference to IS_NULL?).Sorry. I don't understand you without context. If you think something is
wrong in current implementation - please, demonstrate it with test cases,
examples or code references. If you talk about your code, then show it.Sorry, thought I gave enough context and code references! I can't
demonstrate with a test case, which is why I'm asking about it. :-)No, not my code changes (you'll have plenty of code to see soon). I'm
fine replicating the current logic exactly, as I have, but the logic of
these couple parts doesn't make sense, to me. Let me try to simplify with
couple examples...Look at e.g.
is_numeric()
orstrpos()
(needle). Plain zval param parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.Or is there no way for them (or any function?) to get a IS_REFERENCE?
Then why is there ZVAL_DEREF() in param parsing functions? We could
remove it!
We probably may remove ZVAL_DEREF() for functions arguments passed by
value, but we don't know if argument was passed by value or by reference in
ZPP functions. Actually, in FAST_ZPP for scalars we may probably assume
passing by value and remove ZVAL_DEREF(), but I'm not sure if this is 100%
safe.
Thanks. Dmitry.
Which is it...?
Thanks. Dmitry.
Thanks,
Matt
H Dmitry,
----- Original Message -----
From: "Dmitry Stogov"
Sent: Tuesday, August 11, 2015
On Tue, Aug 11, 2015 at 11:10 PM, Matt Wilmas php_lists@realplain.com
wrote:[...]
Look at e.g.
is_numeric()
orstrpos()
(needle). Plain zval param
parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.Or is there no way for them (or any function?) to get a IS_REFERENCE?
Then why is there ZVAL_DEREF() in param parsing functions? We could
remove it!We probably may remove ZVAL_DEREF() for functions arguments passed by
value, but we don't know if argument was passed by value or by reference
in
ZPP functions. Actually, in FAST_ZPP for scalars we may probably assume
passing by value and remove ZVAL_DEREF(), but I'm not sure if this is 100%
safe.
Yes, speaking of scalars, I had already noticed that it doesn't make sense
to have a "separate" argument for the FAST_ZPP scalar _EX macros, as there's
nothing to separate (same with traditional '/') on simple values. I was
changing those macros, and don't think they're used anyway.
Also, I think those simple/scalar types wouldn't be used with by-reference
arguments (?), as there would be nothing to update...
Like I said in reply to Nikita, it seems like separating is needed for
by-reference args, so only need DEREF if also separating? It looks like
that was the idea with Z_PARAM_ZVAL_EX(). And for other types, separating
only applies to arrays or strings, I believe.
As far as not 100% safe, you mean IS_REFERENCE type causing an error about
wrong type? Shouldn't that only happen if developer indicated by-ref arg,
but then used wrong type in parsing?
On the other hand, it seems like always using ZVAL_DEREF() won't hurt
anything? e.g. part of my confusion was that I thought IS_REFERENCE was
wanting to be kept in some cases (after parsing), but it seems to not be
the case. :-)
Speaking of confusion, it also seems the DEREF stuff is unnecessary in
type.c:php_is_type(), for example.
Thanks. Dmitry.
Thanks,
Matt
On Thu, Aug 13, 2015 at 1:12 AM, Matt Wilmas php_lists@realplain.com
wrote:
H Dmitry,
----- Original Message -----
From: "Dmitry Stogov"
Sent: Tuesday, August 11, 2015On Tue, Aug 11, 2015 at 11:10 PM, Matt Wilmas php_lists@realplain.com
wrote:
[...]
Look at e.g.
is_numeric()
orstrpos()
(needle). Plain zval param
parsing,
so NO ZVAL_DEREF() occurs (FAST_ZPP or traditional). These 2 example
functions don't handle IS_REFERENCE type, so they would break.Or is there no way for them (or any function?) to get a IS_REFERENCE?
Then why is there ZVAL_DEREF() in param parsing functions? We could
remove it!We probably may remove ZVAL_DEREF() for functions arguments passed by
value, but we don't know if argument was passed by value or by reference
in
ZPP functions. Actually, in FAST_ZPP for scalars we may probably assume
passing by value and remove ZVAL_DEREF(), but I'm not sure if this is 100%
safe.Yes, speaking of scalars, I had already noticed that it doesn't make sense
to have a "separate" argument for the FAST_ZPP scalar _EX macros, as
there's nothing to separate (same with traditional '/') on simple values.
I was changing those macros, and don't think they're used anyway.Also, I think those simple/scalar types wouldn't be used with by-reference
arguments (?), as there would be nothing to update...Like I said in reply to Nikita, it seems like separating is needed for
by-reference args, so only need DEREF if also separating? It looks like
that was the idea with Z_PARAM_ZVAL_EX(). And for other types, separating
only applies to arrays or strings, I believe.As far as not 100% safe, you mean IS_REFERENCE type causing an error about
wrong type? Shouldn't that only happen if developer indicated by-ref arg,
but then used wrong type in parsing?
At least this case. We may change ZVAL_DEREF(...) into
ZEND_ASSERT(!Z_ISREF_P(...)), to prevent silence crashes.
Thanks. Dmitry.
On the other hand, it seems like always using ZVAL_DEREF() won't hurt
anything? e.g. part of my confusion was that I thought IS_REFERENCE was
wanting to be kept in some cases (after parsing), but it seems to not be
the case. :-)Speaking of confusion, it also seems the DEREF stuff is unnecessary in
type.c:php_is_type(), for example.Thanks. Dmitry.
Thanks,
Matt