fixup yaml to be c++ compliant
[hiphop-php.git] / hphp / hhbbc / representation.h
blob0be3e870b8dd2eabe036b3206887bd12b9cb0212
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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_
19 #include <string>
20 #include <tuple>
21 #include <vector>
22 #include <memory>
23 #include <unordered_map>
24 #include <list>
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 {
38 namespace php {
40 //////////////////////////////////////////////////////////////////////
42 struct Func;
43 struct ExnNode;
44 struct Unit;
46 //////////////////////////////////////////////////////////////////////
48 struct SrcInfo {
49 LineRange loc;
50 SString docComment;
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.
62 struct Block {
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 };
73 Section section;
76 * Blocks have unique ids within a given function.
78 uint32_t id;
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
87 * there is none.
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
95 * to the named block
97 * - taken edges (these are encoded in the last instruction in hhbcs)
99 * - factoredExits (these represent edges traversed for exceptions
100 * mid-block)
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 //////////////////////////////////////////////////////////////////////
113 * Exception regions.
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
119 * time.
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;
142 Id iterId;
143 bool itRef; };
145 using CatchEnt = std::pair<const StringData*,borrowed_ptr<Block>>;
146 struct TryRegion { std::vector<CatchEnt> catches; };
148 struct ExnNode {
149 uint32_t id;
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.
162 struct Param {
164 * Default value for this parameter, or KindOfUninit if it has no
165 * default value.
167 Cell defaultValue;
170 * Pointer to the block we'll enter for default-value initialization
171 * of this parameter, or nullptr if this parameter had no default
172 * value initializer.
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
193 * for reflection.
195 SString phpCode;
198 * Each parameter of a func can have arbitrary user attributes.
200 UserAttributeMap userAttributes;
203 * Whether this parameter is passed by reference.
205 bool byRef : 1;
209 * Metadata about a local variable in a function. Name may be
210 * nullptr, for unnamed locals.
212 struct Local {
213 SString name;
214 uint32_t id;
218 * Metadata about function iterator variables.
220 struct Iter {
221 uint32_t id;
225 * Static local information. For each static local, we need to keep
226 * the php code around for reflection.
228 struct StaticLocalInfo {
229 SString name;
230 SString phpCode;
234 * Representation of a function, class method, or pseudomain function.
236 struct Func {
238 * Basic information about the function.
240 SString name;
241 SrcInfo srcInfo;
242 Attr attrs;
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
256 * vector).
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.)
267 bool top : 1;
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
272 * invoked.
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
297 * instead of yield.
299 bool isAsync : 1;
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 //////////////////////////////////////////////////////////////////////
366 * A class property.
368 * Both static and instance properties use this structure.
370 struct Prop {
371 SString name;
372 Attr attrs;
373 SString docComment;
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).
386 Cell val;
390 * A class constant.
392 struct Const {
393 SString name;
394 Cell val;
397 * We pass through eval'able php code and a string type constraint,
398 * only for exposure to reflection.
400 SString phpCode;
401 SString typeConstraint;
405 * Representation of a php class declaration.
407 struct Class {
409 * Basic information about the class.
411 SString name;
412 SrcInfo srcInfo;
413 Attr attrs;
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
429 * classes).
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.
440 SString parentName;
443 * Names of inherited interfaces.
445 std::vector<SString> interfaceNames;
448 * Names of used traits, and the trait alias/precedence rules (if
449 * any).
451 * This is using the exact structures from the runtime PreClass. In
452 * WholeProgram mode, we won't see these because traits will already
453 * be flattened.
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).
489 struct Unit {
490 MD5 md5;
491 SString filename;
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.
501 struct Program {
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 //////////////////////////////////////////////////////////////////////
523 #endif