2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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>
27 #include <boost/variant.hpp>
29 #include "hphp/util/md5.h"
30 #include "hphp/runtime/base/types.h"
31 #include "hphp/runtime/base/user-attributes.h"
32 #include "hphp/runtime/vm/preclass.h"
33 #include "hphp/runtime/vm/type-alias.h"
34 #include "hphp/runtime/vm/type-constraint.h"
36 #include "hphp/hhbbc/bc.h"
37 #include "hphp/hhbbc/misc.h"
38 #include "hphp/hhbbc/src-loc.h"
40 namespace HPHP
{ namespace HHBBC
{
43 //////////////////////////////////////////////////////////////////////
49 //////////////////////////////////////////////////////////////////////
56 //////////////////////////////////////////////////////////////////////
59 * A basic block in our factored control flow graph.
61 * Blocks terminate on control flow, except exceptional control flow.
62 * We keep a set of "factored edges" representing all possible early
63 * exits due to exceptional control flow.
67 * Blocks in HHBC are each part of a bytecode "section". The section
68 * is either the "primary function body", or a fault funclet. We
69 * represent fault funclet sections with unique ids.
71 * Each section must be a contiguous region of bytecode, with the
72 * primary function body first. These ids are tracked just to
73 * maintain this invariant at emit time.
75 enum class Section
: uint32_t { Main
= 0 };
79 * Blocks have unique ids within a given function.
84 * Instructions in the block. Never empty guarantee.
86 std::vector
<Bytecode
> hhbcs
;
89 * The pointer for this block's exception region, or nullptr if
92 borrowed_ptr
<ExnNode
> exnNode
;
95 * Edges coming out of blocks are repesented in three ways:
97 * - fallthrough edges (the end of the block unconditionally jumps
98 * to the named block). If fallthroughNS is true, this edge
99 * represents a no-surprise jump.
101 * - Taken edges (these are encoded in the last instruction in hhbcs).
103 * - factoredExits (these represent edges traversed for exceptions
106 * For the idea behind the factored exit edge thing, see "Efficient
107 * and Precise Modeling of Exceptions for the Analysis of Java
108 * Programs" (http://dl.acm.org/citation.cfm?id=316171).
110 borrowed_ptr
<Block
> fallthrough
;
111 bool fallthroughNS
= false;
112 std::vector
<borrowed_ptr
<Block
>> factoredExits
;
115 //////////////////////////////////////////////////////////////////////
120 * Each block in the program body can have a pointer to a node in the
121 * exception handler tree. This means they are in all the "exception
122 * regions" for each node in the tree down to that node. This
123 * information is used to construct exception handling regions at emit
126 * There are two types of regions; TryRegions and FaultRegions. These
127 * correspond to the two types of regions described in
128 * bytecode.specification. Note though that although it's not
129 * specified there, in addition to a fault entry offset, fault regions
130 * optionally list some information about iterators if the reason the
131 * fault region is there is to free iterator variables.
133 * Exceptional control flow is also represented more explicitly with
134 * factored exit edges (see php::Block). This tree structure just
135 * exists to get the EHEnts right.
137 * Note: blocks in fault funclets will have factored edges to the
138 * blocks listed as handlers in any ExnNode that contained the
139 * fault-protected region, since those control flow paths are
140 * possible. Generally they will have nullptr for their exnNode
141 * pointers, however, although they may also have other EH-protected
142 * regions inside of them (this currently occurs in the case of
143 * php-level finally blocks cloned into fault funclets).
146 struct FaultRegion
{ borrowed_ptr
<Block
> faultEntry
;
150 using CatchEnt
= std::pair
<const StringData
*,borrowed_ptr
<Block
>>;
151 struct TryRegion
{ std::vector
<CatchEnt
> catches
; };
156 borrowed_ptr
<ExnNode
> parent
;
157 std::vector
<std::unique_ptr
<ExnNode
>> children
;
159 boost::variant
<FaultRegion
,TryRegion
> info
;
162 //////////////////////////////////////////////////////////////////////
165 * Metadata about a parameter to a php function.
169 * Default value for this parameter, or KindOfUninit if it has no
175 * Pointer to the block we'll enter for default-value initialization
176 * of this parameter, or nullptr if this parameter had no default
179 borrowed_ptr
<php::Block
> dvEntryPoint
;
182 * Information about the parameter's typehint, if any.
184 * NOTE: this is represented in the repo as a string type name and
185 * some TypeConstraint::Flags.
187 TypeConstraint typeConstraint
;
190 * User-visible version of the type constraint as a string.
191 * Propagated for reflection.
193 SString userTypeConstraint
;
196 * Evalable php code that will give the default argument. This is
197 * redundant with the dv initializer, but gets propagated through
203 * Each parameter of a func can have arbitrary user attributes.
205 UserAttributeMap userAttributes
;
208 * The type of the arguments for builtin functions, or for HNI
209 * functions with a native implementation. folly::none for
212 folly::Optional
<DataType
> builtinType
;
215 * Whether this parameter is passed by reference.
220 * Whether this parameter is a variadic capture.
226 * Metadata about a local variable in a function. Name may be
227 * nullptr, for unnamed locals.
235 * Metadata about function iterator variables.
242 * Static local information. For each static local, we need to keep
243 * the php code around for reflection.
245 struct StaticLocalInfo
{
251 * Extra information for function with a HNI native implementation.
255 * Return type from the C++ implementation function, as an optional DataType;
256 * folly::none stands for a Variant return.
258 folly::Optional
<DataType
> returnType
;
262 * Representation of a function, class method, or pseudomain function.
266 * Basic information about the function.
273 * Which unit defined this function. If it is a method, the cls
274 * field will be set to the class that contains it.
276 borrowed_ptr
<Unit
> unit
;
277 borrowed_ptr
<Class
> cls
;
280 * Parameters, locals, and iterators.
282 * There are at least as many locals as parameters (parameters are
283 * also locals---the names of parameters are stored in the locals
286 std::vector
<Param
> params
;
287 std::vector
<std::unique_ptr
<Local
>> locals
;
288 std::vector
<std::unique_ptr
<Iter
>> iters
;
289 std::vector
<StaticLocalInfo
> staticLocals
;
292 * Whether or not this function is a top-level function. (Defined
293 * outside of any other function body.)
298 * This is the generated function for a closure body. I.e. this
299 * function contains the code that should run when the closure is
302 bool isClosureBody
: 1;
305 * This is an async function.
310 * This is a generator.
312 bool isGenerator
: 1;
315 * This generator yields key value pairs.
317 bool isPairGenerator
: 1;
320 * All owning pointers to blocks are in this vector, which has the
321 * blocks in an unspecified order. Blocks have borrowed pointers to
322 * each other to represent control flow arcs.
324 std::vector
<std::unique_ptr
<Block
>> blocks
;
327 * Greatest block id in the function plus one.
329 uint32_t nextBlockId
;
332 * Try and fault regions form a tree structure. The tree is hanging
333 * off the func here, with children pointers. Each block that is
334 * within a try or fault region has a pointer to the inner-most
335 * ExnNode protecting it.
337 std::vector
<std::unique_ptr
<ExnNode
>> exnNodes
;
340 * Entry point blocks for default value initializers.
342 * Note that in PHP you can declare functions where some of the
343 * earlier parameters have default values, and later ones don't. In
344 * this case we'll have nulls after the first non-null entry here.
346 std::vector
<borrowed_ptr
<Block
>> dvEntries
;
349 * Entry point to the function when the number of passed args is
350 * equal to the number of parameters.
352 borrowed_ptr
<Block
> mainEntry
;
355 * User attribute list.
357 UserAttributeMap userAttributes
;
360 * User-visible return type specification as a string. This is only
361 * passed through to expose it to reflection.
363 SString returnUserType
;
366 * Return type specified in the source code (ex. "function foo(): Bar").
367 * HHVM checks if the a function's return value matches it's return type
368 * constraint via the VerifyRetType* instructions.
370 TypeConstraint retTypeConstraint
;
373 * If traits are being flattened by hphpc, we keep the original
374 * filename of a function (the file that defined the trait) so
375 * backtraces and things work correctly. Otherwise this is nullptr.
377 SString originalFilename
;
380 * For HNI-based extensions, additional information for functions
381 * with a native-implementation is here. If this isn't a function
382 * with an HNI-based native implementation, this will be nullptr.
384 std::unique_ptr
<NativeInfo
> nativeInfo
;
387 //////////////////////////////////////////////////////////////////////
392 * Both static and instance properties use this structure.
400 * Properties can have string type constraints, which we need to
401 * propagate through just for reflection purposes.
403 SString typeConstraint
;
406 * The default value of the property, for properties with scalar
407 * initializers. May be KindOfUninit in some cases where the
408 * property should not have an initial value (i.e. not even null).
419 // The class that defined this constant.
420 borrowed_ptr
<php::Class
> cls
;
423 * The value will be KindOfUninit if the class constant is defined
424 * using an 86cinit method.
426 * The lack of a value represents an abstract class constant.
428 folly::Optional
<Cell
> val
;
431 * We pass through eval'able php code and a string type constraint,
432 * only for exposure to reflection.
435 SString typeConstraint
;
441 * Representation of a php class declaration.
445 * Basic information about the class.
452 * Which unit defined this class.
454 borrowed_ptr
<Unit
> unit
;
457 * Hoistability of this class. See the description in class.h
458 * formation on hoistability.
460 PreClass::Hoistable hoistability
;
463 * If this class represents a closure, this points to the class that
464 * lexically contains the closure, if there was one. If this class
465 * doesn't represent a closure, this will be nullptr.
467 * The significance of this is that closures created lexically
468 * inside of a class run as if they were part of that class context
469 * (with regard to access checks, etc).
471 borrowed_ptr
<php::Class
> closureContextCls
;
474 * Name of the parent class.
479 * Names of inherited interfaces.
481 std::vector
<LowStringPtr
> interfaceNames
;
484 * Names of used traits, number of declared (i.e., non-trait, non-inherited)
485 * methods, trait alias/precedence rules (if any).
487 * This is using the exact structures from the runtime PreClass. In
488 * WholeProgram mode, we won't see these because traits will already be
491 std::vector
<LowStringPtr
> usedTraitNames
;
492 std::vector
<PreClass::ClassRequirement
> requirements
;
493 std::vector
<PreClass::TraitPrecRule
> traitPrecRules
;
494 std::vector
<PreClass::TraitAliasRule
> traitAliasRules
;
495 int32_t numDeclMethods
;
498 * Methods on the class.
500 std::vector
<std::unique_ptr
<php::Func
>> methods
;
503 * Properties defined on this class.
505 std::vector
<Prop
> properties
;
508 * Constants defined on this class.
510 std::vector
<Const
> constants
;
513 * User attributes for this class declaration.
515 UserAttributeMap userAttributes
;
518 * The underlying base type, if this is an enum
520 TypeConstraint enumBaseTy
;
523 //////////////////////////////////////////////////////////////////////
525 using TypeAlias
= ::HPHP::TypeAlias
;
527 //////////////////////////////////////////////////////////////////////
530 * Representation of a php file (normal compilation unit).
535 int preloadPriority
{0};
536 std::unique_ptr
<Func
> pseudomain
;
537 std::vector
<std::unique_ptr
<Func
>> funcs
;
538 std::vector
<std::unique_ptr
<Class
>> classes
;
539 std::vector
<std::unique_ptr
<TypeAlias
>> typeAliases
;
543 * A php Program is a set of compilation units.
546 std::vector
<std::unique_ptr
<Unit
>> units
;
549 //////////////////////////////////////////////////////////////////////
551 std::string
show(const Func
&);
552 std::string
show(const Class
&);
553 std::string
show(const Unit
&);
554 std::string
show(const Program
&);
555 std::string
local_string(borrowed_ptr
<const php::Local
>);
557 //////////////////////////////////////////////////////////////////////
559 bool check(const Func
&);
560 bool check(const Class
&);
561 bool check(const Unit
&);
562 bool check(const Program
&);
564 //////////////////////////////////////////////////////////////////////