phparchitect-2019-08

(Rick Simeone) #1
http://www.phparch.com \ August 2019 \ 37

Generated Singletons


Internal Apparatus


passing no parameters to the constructor (parameter count
is 0).
FCALL means “function call”. EXT_FCALL_BEGIN (line L7)
throughEXT_FCALL_END (line L9) implement the function call.
This is a minimal function call. No parameters are being
passed, and the function does not even have a specified name.
We know from the NEW 0 (self) instruction we are, in fact,
calling the __construct() method of the current class or its
parent class. Even without examining the virtual machine, we
know that’s how PHP works.
Line L10 is weird. We’re fetching the static property “for
writing,” meaning we are going to write to (i.e., modify
the value of ) the static property. That’s the _W suffix in the
FETCH_STATIC_PROP_W instruction and, in effect, we are binding
internal variable V2 to that static property. The next line, L11,
assigns the value in V3 to V2.
Wait. Shouldn’t that be the other way around? No. We are
writing to, not reading from, the static property bound to V2.
When we put something into V2, it gets sent to static property
self::$instance. When we’re reading generated code we need
to be paying awfully close attention!
We know we’re moving V3 to V2 and thus writing that value
to self::$instance. That’s great, but what’s V3? We set V3 back
on line L6. When we created the object (as new self;), we
placed the object pointer in the temporary variable 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

Our getInstance() method returns the object. Line L12
is the placeholder informing any active debugger that we’re
beginning a new PHP statement. Line L13 is identical to L2,
except that we’re now placing the value of static::$instance
in V6 rather than V0 as before.
Line L14 exists because we specified a return type. We’ll see
the difference below. After verifying the return type at L14, we
return the object pointer at line L15.
We can ignore the final lines, L16–L18, because they repre-
sent dead code. The code generator produces this sequence
(these three instructions) when reaching the closing brace of
a function or method. The code optimizer then removes that
code because it can’t be reached. Program flow never skips
past the PHP return statement to reach the closing brace.

L16 (18): EXT_STMT
L17 (18): VERIFY_RETURN_TYPE
L18 (18): RETURN null

OSMI Mental Health in Tech Survey


Take our 20 minute survey to give us


information about your mental health


experiences in the tech industry. At the


end of 2019, we’ll publish the results


under Creative Commons licensing.


Take the survey: https://osmihelp.org/research

Free download pdf