2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HHBBC_REPRESENTATION_H_
17 #define incl_HHBBC_REPRESENTATION_H_
23 #include <unordered_map>
26 #include <boost/variant.hpp>
28 #include "hphp/util/md5.h"
29 #include "hphp/runtime/base/complex-types.h"
30 #include "hphp/runtime/vm/type-alias.h"
31 #include "hphp/runtime/vm/type-constraint.h"
33 #include "hphp/hhbbc/misc.h"
34 #include "hphp/hhbbc/src-loc.h"
35 #include "hphp/hhbbc/bc.h"
37 namespace HPHP
{ namespace HHBBC
{
40 //////////////////////////////////////////////////////////////////////
46 //////////////////////////////////////////////////////////////////////
53 //////////////////////////////////////////////////////////////////////
56 * A basic block in our factored control flow graph.
58 * Blocks terminate on control flow, except exceptional control flow.
59 * We keep a set of "factored edges" representing all possible early
60 * exits due to exceptional control flow.
64 * Blocks in HHBC are each part of a bytecode "section". The section
65 * is either the "primary function body", or a fault funclet. We
66 * represent fault funclet sections with unique ids.
68 * Each section must be a contiguous region of bytecode, with the
69 * primary function body first. These ids are tracked just to
70 * maintain this invariant at emit time.
72 enum class Section
: uint32_t { Main
= 0 };
76 * Blocks have unique ids within a given function.
81 * Instructions in the block. Never empty guarantee.
83 std::vector
<Bytecode
> hhbcs
;
86 * The pointer for this block's exception region, or nullptr if
89 borrowed_ptr
<ExnNode
> exnNode
;
92 * Edges coming out of blocks are repesented in three ways:
94 * - fallthrough edges (the end of the block unconditionally jumps
97 * - taken edges (these are encoded in the last instruction in hhbcs)
99 * - factoredExits (these represent edges traversed for exceptions
102 * For the idea behind the factored exit edge thing, see "Efficient
103 * and Precise Modeling of Exceptions for the Analysis of Java
104 * Programs" (http://dl.acm.org/citation.cfm?id=316171).
106 borrowed_ptr
<Block
> fallthrough
;
107 std::vector
<borrowed_ptr
<Block
>> factoredExits
;
110 //////////////////////////////////////////////////////////////////////
115 * Each block in the program body can have a pointer to a node in the
116 * exception handler tree. This means they are in all the "exception
117 * regions" for each node in the tree down to that node. This
118 * information is used to construct exception handling regions at emit
121 * There are two types of regions; TryRegions and FaultRegions. These
122 * correspond to the two types of regions described in
123 * bytecode.specification. Note though that although it's not
124 * specified there, in addition to a fault entry offset, fault regions
125 * optionally list some information about iterators if the reason the
126 * fault region is there is to free iterator variables.
128 * Exceptional control flow is also represented more explicitly with
129 * factored exit edges (see php::Block). This tree structure just
130 * exists to get the EHEnts right.
132 * Note: blocks in fault funclets will have factored edges to the
133 * blocks listed as handlers in any ExnNode that contained the
134 * fault-protected region, since those control flow paths are
135 * possible. Generally they will have nullptr for their exnNode
136 * pointers, however, although they may also have other EH-protected
137 * regions inside of them (this currently occurs in the case of
138 * php-level finally blocks cloned into fault funclets).
141 struct FaultRegion
{ borrowed_ptr
<Block
> faultEntry
;
145 using CatchEnt
= std::pair
<const StringData
*,borrowed_ptr
<Block
>>;
146 struct TryRegion
{ std::vector
<CatchEnt
> catches
; };
151 borrowed_ptr
<ExnNode
> parent
;
152 std::vector
<std::unique_ptr
<ExnNode
>> children
;
154 boost::variant
<FaultRegion
,TryRegion
> info
;
157 //////////////////////////////////////////////////////////////////////
160 * Metadata about a parameter to a php function.
164 * Default value for this parameter, or KindOfUninit if it has no
170 * Pointer to the block we'll enter for default-value initialization
171 * of this parameter, or nullptr if this parameter had no default
174 borrowed_ptr
<php::Block
> dvEntryPoint
;
177 * Information about the parameter's typehint, if any.
179 * NOTE: this is represented in the repo as a string type name and
180 * some TypeConstraint::Flags.
182 TypeConstraint typeConstraint
;
185 * User-visible version of the type constraint as a string.
186 * Propagated for reflection.
188 SString userTypeConstraint
;
191 * Evalable php code that will give the default argument. This is
192 * redundant with the dv initializer, but gets propagated through
198 * Each parameter of a func can have arbitrary user attributes.
200 UserAttributeMap userAttributes
;
203 * Whether this parameter is passed by reference.
209 * Metadata about a local variable in a function. Name may be
210 * nullptr, for unnamed locals.
218 * Metadata about function iterator variables.
225 * Static local information. For each static local, we need to keep
226 * the php code around for reflection.
228 struct StaticLocalInfo
{
234 * Representation of a function, class method, or pseudomain function.
238 * Basic information about the function.
245 * Which unit defined this function. If it is a method, the cls
246 * field will be set to the class that contains it.
248 borrowed_ptr
<Unit
> unit
;
249 borrowed_ptr
<Class
> cls
;
252 * Parameters, locals, and iterators.
254 * There are at least as many locals as parameters (parameters are
255 * also locals---the names of parameters are stored in the locals
258 std::vector
<Param
> params
;
259 std::vector
<std::unique_ptr
<Local
>> locals
;
260 std::vector
<std::unique_ptr
<Iter
>> iters
;
261 std::vector
<StaticLocalInfo
> staticLocals
;
264 * Whether or not this function is a top-level function. (Defined
265 * outside of any other function body.)
270 * This is the generated function for a closure body. I.e. this
271 * function contains the code that should run when the closure is
274 bool isClosureBody
: 1;
277 * This is the "generator body" function for a continuation.
278 * I.e. this is the code that runs when a generator is asked to
279 * yield a new element.
281 bool isGeneratorBody
: 1;
284 * This is the generator body for a generator closure. (I.e. a
285 * closure with yield statements in it.)
287 bool isGeneratorFromClosure
: 1;
290 * This generator yields key value pairs.
292 bool isPairGenerator
: 1;
295 * This is an async function. This flag is set on both the "inner"
296 * and "outer" functions for a generator when it used async/await
302 * All owning pointers to blocks are in this vector, which has the
303 * blocks in an unspecified order. Blocks have borrowed pointers to
304 * each other to represent control flow arcs.
306 std::vector
<std::unique_ptr
<Block
>> blocks
;
309 * Greatest block id in the function plus one.
311 uint32_t nextBlockId
;
314 * Try and fault regions form a tree structure. The tree is hanging
315 * off the func here, with children pointers. Each block that is
316 * within a try or fault region has a pointer to the inner-most
317 * ExnNode protecting it.
319 std::vector
<std::unique_ptr
<ExnNode
>> exnNodes
;
322 * Entry point blocks for default value initializers.
324 * Note that in PHP you can declare functions where some of the
325 * earlier parameters have default values, and later ones don't. In
326 * this case we'll have nulls after the first non-null entry here.
328 std::vector
<borrowed_ptr
<Block
>> dvEntries
;
331 * Entry point to the function when the number of passed args is
332 * equal to the number of parameters.
334 borrowed_ptr
<Block
> mainEntry
;
337 * User attribute list.
339 UserAttributeMap userAttributes
;
342 * This is the name of "inner" function for a generator. When compiling
343 * a generator, we generate two funtions. The "outer" one stores (with
344 * this field set) allocates the continuation object and returns it. The
345 * "inner" one named here will have isGeneratorBody set.
347 SString generatorBodyName
;
350 * User-visible return type specification as a string. This is only
351 * passed through to expose it to reflection.
353 SString userRetTypeConstraint
;
356 * If traits are being flattened by hphpc, we keep the original
357 * filename of a function (the file that defined the trait) so
358 * backtraces and things work correctly. Otherwise this is nullptr.
360 SString originalFilename
;
363 //////////////////////////////////////////////////////////////////////
368 * Both static and instance properties use this structure.
376 * Properties can have string type constraints, which we need to
377 * propagate through just for reflection purposes.
379 SString typeConstraint
;
382 * The default value of the property, for properties with scalar
383 * initializers. May be KindOfUninit in some cases where the
384 * property should not have an initial value (i.e. not even null).
397 * We pass through eval'able php code and a string type constraint,
398 * only for exposure to reflection.
401 SString typeConstraint
;
405 * Representation of a php class declaration.
409 * Basic information about the class.
416 * Which unit defined this class.
418 borrowed_ptr
<Unit
> unit
;
421 * Hoistability of this class. See the description in class.h
422 * formation on hoistability.
424 PreClass::Hoistable hoistability
;
427 * The function that contains the DefCls for this class, or nullptr
428 * in the case of classes that do not have a DefCls (e.g. closure
431 * The plan was to use this information in part to compute
432 * hoistability at emit time, but it's unused right now. (Using
433 * hphpc's hoistability notions.)
435 // borrowed_ptr<php::Func> definingFunc;
438 * Name of the parent class.
443 * Names of inherited interfaces.
445 std::vector
<SString
> interfaceNames
;
448 * Names of used traits, and the trait alias/precedence rules (if
451 * This is using the exact structures from the runtime PreClass. In
452 * WholeProgram mode, we won't see these because traits will already
455 std::vector
<SString
> usedTraitNames
;
456 std::vector
<PreClass::TraitPrecRule
> traitPrecRules
;
457 std::vector
<PreClass::TraitAliasRule
> traitAliasRules
;
460 * Methods on the class.
462 std::vector
<std::unique_ptr
<php::Func
>> methods
;
465 * Properties defined on this class.
467 std::vector
<Prop
> properties
;
470 * Constants defined on this class.
472 std::vector
<Const
> constants
;
475 * User attributes for this class declaration.
477 UserAttributeMap userAttributes
;
480 //////////////////////////////////////////////////////////////////////
482 using TypeAlias
= ::HPHP::TypeAlias
;
484 //////////////////////////////////////////////////////////////////////
487 * Representation of a php file (normal compilation unit).
492 std::unique_ptr
<Func
> pseudomain
;
493 std::vector
<std::unique_ptr
<Func
>> funcs
;
494 std::vector
<std::unique_ptr
<Class
>> classes
;
495 std::vector
<std::unique_ptr
<TypeAlias
>> typeAliases
;
499 * A php Program is a set of compilation units.
502 std::vector
<std::unique_ptr
<Unit
>> units
;
505 //////////////////////////////////////////////////////////////////////
507 std::string
show(const Func
&);
508 std::string
show(const Class
&);
509 std::string
show(const Unit
&);
510 std::string
show(const Program
&);
512 //////////////////////////////////////////////////////////////////////
514 bool check(const Func
&);
515 bool check(const Class
&);
516 bool check(const Unit
&);
517 bool check(const Program
&);
519 //////////////////////////////////////////////////////////////////////