Hi internals,
I was sifting through the bucket o’ bugs and found these two related issues:
https://bugs.php.net/bug.php?id=67829
https://bugs.php.net/bug.php?id=54162 (closed)
They concern the behaviour of the engine when a class defines no constructor or if the class to be instantiated doesn’t exist, which can be seen here: http://3v4l.org/jOQY0
This is obviously a design decision, but doesn’t seem to have a mention in the documentation nor the spec (I couldn’t find it under the ‘new’ operator).
I can add a paragraph in the documentation for it; the question is whether it should also be added to the spec, seeing how HHVM and PHP behave differently in this respect? It could be added as implementation dependent behaviour I suppose?
— @datibbaw
On Thu, Aug 14, 2014 at 8:26 AM, Tjerk Meesters
tjerk.meesters@gmail.com wrote:
Hi internals,
I was sifting through the bucket o’ bugs and found these two related issues:
https://bugs.php.net/bug.php?id=67829
https://bugs.php.net/bug.php?id=54162 (closed)They concern the behaviour of the engine when a class defines no constructor or if the class to be instantiated doesn’t exist, which can be seen here: http://3v4l.org/jOQY0
This is obviously a design decision, but doesn’t seem to have a mention in the documentation nor the spec (I couldn’t find it under the ‘new’ operator).
I can add a paragraph in the documentation for it; the question is whether it should also be added to the spec, seeing how HHVM and PHP behave differently in this respect? It could be added as implementation dependent behaviour I suppose?
This is a known behavior which is part of the VM.
It is designed at http://lxr.php.net/xref/PHP_5_5/Zend/zend_vm_def.h#3383
I guess its an optimisation that prevents the compiler from compiling
a ZEND_DO_FCALL for constructors, which optimizes a bit the VM path
for object construction.
Dmitry should have more informations.
I'm +1 for a documentation or spec mention.
Julien.Pauli
Julien Pauli wrote (on 14/08/2014):
On Thu, Aug 14, 2014 at 8:26 AM, Tjerk Meesters
tjerk.meesters@gmail.com wrote:Hi internals,
I was sifting through the bucket o’ bugs and found these two related issues:
https://bugs.php.net/bug.php?id=67829
https://bugs.php.net/bug.php?id=54162 (closed)They concern the behaviour of the engine when a class defines no constructor or if the class to be instantiated doesn’t exist, which can be seen here: http://3v4l.org/jOQY0
This is obviously a design decision, but doesn’t seem to have a mention in the documentation nor the spec (I couldn’t find it under the ‘new’ operator).
I can add a paragraph in the documentation for it; the question is whether it should also be added to the spec, seeing how HHVM and PHP behave differently in this respect? It could be added as implementation dependent behaviour I suppose?
This is a known behavior which is part of the VM.
It is designed at http://lxr.php.net/xref/PHP_5_5/Zend/zend_vm_def.h#3383I guess its an optimisation that prevents the compiler from compiling
a ZEND_DO_FCALL for constructors, which optimizes a bit the VM path
for object construction.
Dmitry should have more informations.I'm +1 for a documentation or spec mention.
Julien.Pauli
When it came up on StackOverflow chat, it was cheekily dubbed "Rasmus
evaluation", because nobody could find any theory matching that
particular optimisation:
https://chat.stackoverflow.com/transcript/11/2013/9/28/14-17
I'm still not entirely sure it's a good idea, and can't imagine how
anyone would rely on it (if you have a look at that trasnscript, you'll
find some fun attempts at finding an esoteric use). Is it really that
big an optimisation that it's worth such surprising behaviour?
--
Rowan Collins
[IMSoP]
Julien Pauli wrote (on 14/08/2014):
On Thu, Aug 14, 2014 at 8:26 AM, Tjerk Meesters
tjerk.meesters@gmail.com wrote:Hi internals,
I was sifting through the bucket o’ bugs and found these two related
issues:
https://bugs.php.net/bug.php?id=67829
https://bugs.php.net/bug.php?id=54162 (closed)They concern the behaviour of the engine when a class defines no
constructor or if the class to be instantiated doesn’t exist, which can be
seen here: http://3v4l.org/jOQY0This is obviously a design decision, but doesn’t seem to have a mention
in the documentation nor the spec (I couldn’t find it under the ‘new’
operator).I can add a paragraph in the documentation for it; the question is
whether it should also be added to the spec, seeing how HHVM and PHP behave
differently in this respect? It could be added as implementation dependent
behaviour I suppose?This is a known behavior which is part of the VM.
It is designed at http://lxr.php.net/xref/PHP_5_5/Zend/zend_vm_def.h#3383I guess its an optimisation that prevents the compiler from compiling
a ZEND_DO_FCALL for constructors, which optimizes a bit the VM path
for object construction.
Dmitry should have more informations.I'm +1 for a documentation or spec mention.
Julien.Pauli
When it came up on StackOverflow chat, it was cheekily dubbed "Rasmus
evaluation", because nobody could find any theory matching that particular
optimisation: https://chat.stackoverflow.com/transcript/11/2013/9/28/14-17I'm still not entirely sure it's a good idea, and can't imagine how anyone
would rely on it (if you have a look at that trasnscript, you'll find some
fun attempts at finding an esoteric use). Is it really that big an
optimisation that it's worth such surprising behaviour?
Well, in fact the INIT_FCALL and DO_FCALL are generated by the
compiler, but the executor optimizes by jumping over all the opline of
the constructor if this latter is not declared at compile time.
As a side effect, if the argument is to be IS_VAR or IS_CV , it won't
be interpreted, thus this behavior.
It may be possible to interpret the argument, but I think it will need
new OPCodes, like ZEND_NEW_WITH_CTOR and ZEND_NEW_WITHOUT_CTOR , and a
compiler patch to support those.
This may be thought for PHP7, and I think will benefit from the
ast-compiler RFC if its voted.
Dmitry or Nikita could bring more information about this as well.
Julien.Pauli
Julien Pauli wrote (on 14/08/2014):
It may be possible to interpret the argument, but I think it will need
new OPCodes, like ZEND_NEW_WITH_CTOR and ZEND_NEW_WITHOUT_CTOR , and a
compiler patch to support those.
This may be thought for PHP7, and I think will benefit from the
ast-compiler RFC if its voted.
Yeah, to clarify, I was definitely thinking in terms of PHP7, where lots
is already being done for consistency and parser changes.
It may be naive of me, but would it be possible to simply add an
implicit constructor with an empty argument list and body to any class
which doesn't have one?
Because that's kind of what seems logical from the user point of view:
class A { }
class A { public function __construct() {} }
The same could also be achieved by having an implicit ancestor of all
objects, because an empty constructor (and destructor) could be defined
there, then over-ridden by whatever the user declares.
--
Rowan Collins
[IMSoP]
Julien Pauli wrote (on 14/08/2014):
It may be possible to interpret the argument, but I think it will need
new OPCodes, like ZEND_NEW_WITH_CTOR and ZEND_NEW_WITHOUT_CTOR , and a
compiler patch to support those.
This may be thought for PHP7, and I think will benefit from the
ast-compiler RFC if its voted.Yeah, to clarify, I was definitely thinking in terms of PHP7, where lots is
already being done for consistency and parser changes.It may be naive of me, but would it be possible to simply add an implicit
constructor with an empty argument list and body to any class which doesn't
have one?
This would disable the actual executor optimization.
We need to rethink this problem for PHP7's executor.
Julien.Pauli