On 27/10/2019 02:12, Mike Schinkel wrote:
While reading the [RFC] Union Types v2 thread and comments from Dmitry[1], and especially
Benjamin[2] who suggested "building a static analysis tool which could prove that
certain type checks would never fail, and prime OpCache" it occurred to me that a
PHP pre-compiler could potentially be used to resolve numerous issues the community has
been debating.
I chose the phrase "static analysis tool" deliberately, because I wanted
to think about the minimum requirements for such a tool, rather than its
long-term possibilities. The basic requirements are fairly straight-forward:
- a static analyser that can infer types in a PHP program; we know
that's possible from a number of third-party tools, although they do
rely on docblock comments for things the language doesn't (yet) let you
define
- the ability to generate OpCodes for some code and store it to disk;
this is more or less what OpCache does if enabled for CLI mode
However, combining those usefully may not be that easy.
The first problem is that OpCache is designed to work one file at a
time, because a program can load any combination of files at run-time.
Static analysers, on the other hand, need to process a whole directory
at a time, so that calls can be matched to definitions; multiple
definitions of the same function or class tend to cause problems, even
though only one is loaded at run-time. So we'd probably need some
built-in definition of a "package", which could be analysed and compiled
as one unit, and didn't rely on any run-time loading.
The second problem is that, as I understand it, type checks aren't
actually separate OpCodes, so eliminating them from the compiled program
may not be that easy. There are some cases where you can just eliminate
the type check from a definition, e.g.:
class A {
private int $x=1;
private function foo(int $x) { }
public function bar() {
$this->foo($this->x);
}
}
Since we know that function foo is only ever called with the correctly
typed argument, we can compile it as though it had no type declaration.
However, in the seemingly obvious case Benjamin gave, the optimisation
isn't so easy:
function x(): int {}
function y(int $foo) {}
y(x());
We can't eliminate the type check for all calls to x(), or for all calls
to y(), but we want to eliminate the duplicate check for that particular
line. So the OpCodes need to represent that somehow. I've no idea how
easy or hard that would be.
In order to extend this to a full compiler, we need at least one more
thing: a stable compilation target. What I mean by that is that if I
distribute a package in binary form, it needs to run on a reasonably
large range of PHP versions and installations. My understanding is that
the OpCodes in the Zend VM are not designed to be stable across
versions, so you can't just ship today's OpCache output like you would a
Java class file or .net assembly. Again, I don't know how much effort it
would be to make the VM work as such a stable target.
4. Ability to deprecate features for pre-compiled code while still supporting
them when not precompiled.
Unlike P++, Editions, or Strict Mode, this would undeniably define that
the deprecated features were "the wrong way". If the engine had to
support the feature anyway, I'm not sure what the advantage would be of
tying it to "compiled vs non-compiled", rather than opting in via a
declare() statement or package config.
Regards,
--
Rowan Tommins (né Collins)
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php