40 \ August 2019 \ http://www.phparch.com
Generated Singletons
Internal Apparatus
abstract, and the executable PHP code
did not change. We merely changed
which file it’s in, and the class name. It
makes sense, then, that the code gener-
ator generates the same code as before.
We’ve now demonstrated things like
abstract or private don’t make any
difference to the code generator.
Listing 4 showed our empty Camden-
StatePark class. What should we expect
for the generated code? I was surprised.
I was expecting a very-short generat-
ed-code listing, given that the class is
empty. However, it isn’t. It gets inter-
esting! See Output 3.
Our first section, lines 1–13, has
changed. How might we quickly focus
in on the changes? Let’s identify what
has not changed and eliminate that.
The rest is of interest. The preamble,
lines 1-3, is roughly the same. Lines L0–
L2 look the same, just no-op’s. The last
line, RETURN 1, looks the same as well.
Now we can examine what changed.
We recognize L3–L5 as the function
calling sequence. In this case, we’re
implementing require_once. The next
lines are different; we’re fetching the
parent class and declaring the current
class as the child class. No doubt
the PHP virtual machine does some
housekeeping at this point to keep the
class-inheritance tree up to date. Line
L8 is a good reminder that class names
and namespaces are not case sensitive.
The class name has been converted to a
lower-case string.
The next section, lines 15–22, is also
identified as mainline code, $_main.
Line 17 explains what is happening.
We’re seeing the mainline code for the
parent class. Lines 18–22 (L0–L4 of the
second section) show the now-familiar
no-op’s and RETURN 1.
The third and fourth sections are
the same code we saw before. This is
the generated code for the parent class,
__construct() and getInstance(). This
outcome was a surprise to me! The generated code for the child class incorporates the generated code for the entire parent class.
Is this true for every child class? It appears so! I won’t repeat the same listing here for the CarleyStatePark generated code.
Instead, Output 4 is the diff between CamdenStatePark and CarleyStatePark. The only differences are the class and file names.
Output 3. Class CamdenStatePark generated code
- $_main: ; (lines=10, args=0, vars=0, tmps=3)
- ; (before optimizer)
- ; /PragmaticPHP/pragma/src/GeneratedSingleton/CamdenStatePark.php:1-12
- L0 (2): NOP
- L1 (4): NOP
- L2 (5): EXT_STMT
- L3 (5): EXT_FCALL_BEGIN
- L4 (5): INCLUDE_OR_EVAL (require_once) string("StatePark.php")
- L5 (5): EXT_FCALL_END
- L6 (10): EXT_STMT
- L7 (10): V1 = FETCH_CLASS string("App\GeneratedSingleton\StatePark")
- L8 (10): DECLARE_INHERITED_CLASS_DELAYED
string("app\generatedsingleton\camdenstatepark") V1 - L9 (12): RETURN int(1)
- $_main: ; (lines=5, args=0, vars=0, tmps=1)
- ; (before optimizer)
- ; /PragmaticPHP/pragma/src/GeneratedSingleton/StatePark.php:1-21
- L0 (2): NOP
- L1 (4): NOP
- L2 (6): EXT_STMT
- L3 (6): NOP
- L4 (21): RETURN int(1)
- App\GeneratedSingleton\StatePark::__construct: ; (lines=3, args=0, vars=0, tmps=0)
- ; (before optimizer)
- ; /PragmaticPHP/pragma/src/GeneratedSingleton/StatePark.php:10-11
- L0 (10): EXT_NOP
- L1 (11): EXT_STMT
- L2 (11): RETURN null
- App\GeneratedSingleton\StatePark::getInstance: ; (lines=19, args=0, vars=0, tmps=7)
- ; (before optimizer)
- ; /PragmaticPHP/pragma/src/GeneratedSingleton/StatePark.php:13-18
- L0 (13): EXT_NOP
- L1 (14): EXT_STMT
- L2 (14): V0 = FETCH_STATIC_PROP_R string("instance") (self) (exception)
- L3 (14): T1 = BOOL_NOT V0
- L4 (14): JMPZ T1 L12
- L5 (15): EXT_STMT
- L6 (15): V3 = NEW 0 (static) (exception)
- L7 (15): EXT_FCALL_BEGIN
- L8 (15): DO_FCALL
- L9 (15): EXT_FCALL_END
- L10 (15): V2 = FETCH_STATIC_PROP_W string("instance") (self) (exception)
- L11 (15): ASSIGN V2 V3
- L12 (17): EXT_STMT
- L13 (17): V6 = FETCH_STATIC_PROP_R string("instance") (self) (exception)
- L14 (17): VERIFY_RETURN_TYPE V6
- L15 (17): RETURN V6
- L16 (18): EXT_STMT
- L17 (18): VERIFY_RETURN_TYPE
- L18 (18): RETURN null
- LIVE RANGES:
- 3: L10 - L11 (tmp/var)
- 6: L14 - L15 (tmp/var)