New flag and error message for class to memo key conversion
[hiphop-php.git] / hphp / hhbbc / representation.h
blobc96fdd9a77c5ff82535298241c69626c05b12d48
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 #pragma once
18 #include <list>
19 #include <memory>
20 #include <string>
21 #include <tuple>
22 #include <unordered_map>
23 #include <utility>
24 #include <vector>
26 #include <boost/variant.hpp>
28 #include "hphp/util/atomic-vector.h"
29 #include "hphp/util/compact-vector.h"
30 #include "hphp/util/copy-ptr.h"
31 #include "hphp/util/sha1.h"
33 #include "hphp/runtime/base/user-attributes.h"
34 #include "hphp/runtime/vm/coeffects.h"
35 #include "hphp/runtime/vm/constant.h"
36 #include "hphp/runtime/vm/func.h"
37 #include "hphp/runtime/vm/preclass.h"
38 #include "hphp/runtime/vm/type-alias.h"
39 #include "hphp/runtime/vm/type-constraint.h"
41 #include "hphp/hhbbc/bc.h"
42 #include "hphp/hhbbc/misc.h"
43 #include "hphp/hhbbc/src-loc.h"
45 namespace HPHP::HHBBC::php {
47 //////////////////////////////////////////////////////////////////////
49 struct ExnNode;
50 struct Func;
51 struct Unit;
52 struct WideFunc;
54 //////////////////////////////////////////////////////////////////////
56 struct SrcInfo {
57 LineRange loc;
58 LSString docComment;
61 //////////////////////////////////////////////////////////////////////
64 * A basic block in our factored control flow graph.
66 * Blocks terminate on control flow, except exceptional control flow.
67 * We keep a set of "throw exits" representing all possible early
68 * exits due to exceptional control flow.
70 struct Block {
72 * Instructions in the block. Never empty guarantee.
74 BytecodeVec hhbcs;
77 * The id of this block's ExnNode, or NoExnNodeId if there is none.
79 ExnNodeId exnNodeId{NoExnNodeId};
82 * Edges coming out of blocks are repesented in three ways:
84 * - fallthrough edges (the end of the block unconditionally jumps
85 * to the named block). If fallthroughNS is true, this edge
86 * represents a no-surprise jump.
88 * - throwExit (the edges traversed for exceptions from this block)
90 * - Taken edges (these are encoded in the last instruction in hhbcs).
92 * For the idea behind the factored exit edge thing, see "Efficient
93 * and Precise Modeling of Exceptions for the Analysis of Java
94 * Programs" (http://dl.acm.org/citation.cfm?id=316171).
96 BlockId fallthrough{NoBlockId};
97 BlockId throwExit{NoBlockId};
99 union {
100 uint8_t initializer{0};
101 struct {
102 bool catchEntry: 1;
103 bool fallthroughNS: 1;
104 bool multiPred: 1;
105 bool multiSucc: 1;
106 bool dead: 1;
111 //////////////////////////////////////////////////////////////////////
114 * Exception regions.
116 * Each block in the program body can have a pointer to a node in the
117 * exception handler tree. This means they are in all the "exception
118 * regions" for each node in the tree down to that node. This
119 * information is used to construct exception handling regions at emit
120 * time.
122 * The catch region is described in bytecode.specification. Note though
123 * that although it's not specified there, in addition to an entry offset,
124 * these regions optionally list some information about iterators if the
125 * reason the region is there is to free iterator variables.
127 * Exceptional control flow is also represented more explicitly with
128 * factored exit edges (see php::Block). This tree structure just
129 * exists to get the EHEnts right.
132 struct CatchRegion { BlockId catchEntry;
133 Id iterId; };
135 struct ExnNode {
136 ExnNodeId idx;
137 uint32_t depth;
138 CompactVector<ExnNodeId> children;
139 ExnNodeId parent;
140 CatchRegion region;
143 //////////////////////////////////////////////////////////////////////
146 * Metadata about a parameter to a php function.
148 struct Param {
150 * Default value for this parameter, or KindOfUninit if it has no
151 * default value.
153 TypedValue defaultValue;
156 * Pointer to the block we'll enter for default-value initialization
157 * of this parameter, or nullptr if this parameter had no default
158 * value initializer.
160 BlockId dvEntryPoint;
163 * Information about the parameter's typehint, if any.
165 * NOTE: this is represented in the repo as a string type name and
166 * some TypeConstraint::Flags.
168 TypeConstraint typeConstraint;
171 * User-visible version of the type constraint as a string.
172 * Propagated for reflection.
174 LSString userTypeConstraint;
176 CompactVector<TypeConstraint> upperBounds;
179 * Each parameter of a func can have arbitrary user attributes.
181 UserAttributeMap userAttributes;
184 * Evalable php code that will give the default argument. This is
185 * redundant with the dv initializer, but gets propagated through
186 * for reflection.
188 LSString phpCode;
191 * The type of the arguments for builtin functions, or for HNI
192 * functions with a native implementation. std::nullopt for
193 * non-builtins.
195 Optional<DataType> builtinType;
198 * Whether this parameter is passed as inout.
200 bool inout: 1;
203 * Whether this parameter is passed as readonly.
205 bool readonly: 1;
208 * Whether this parameter is a variadic capture.
210 bool isVariadic: 1;
214 * Metadata about a local variable in a function. Name may be
215 * nullptr, for unnamed locals.
217 struct Local {
218 LSString name;
219 uint32_t id : 31;
220 uint32_t killed : 1;
221 uint32_t nameId : 31;
222 uint32_t unusedName : 1;
226 * Extra information for function with a HNI native implementation.
228 struct NativeInfo {
230 * Return type from the C++ implementation function, as an optional DataType;
231 * std::nullopt stands for a Variant return.
233 Optional<DataType> returnType;
236 using BlockVec = CompactVector<copy_ptr<Block>>;
239 * Separate out the fields that need special attention when copying,
240 * so that Func can just have default copy/move semantics.
242 struct FuncBase {
243 FuncBase() = default;
244 FuncBase(const FuncBase&);
245 FuncBase(FuncBase&&) = delete;
246 FuncBase& operator=(const FuncBase&) = delete;
249 * Catch regions form a tree structure. The tree is hanging
250 * off the func here, with children ids. Each block that is
251 * within a catch region has the index into this array of the
252 * inner-most ExnNode protecting it.
254 * Note that this is updated during the concurrent analyze pass.
256 CompactVector<ExnNode> exnNodes;
259 * For HNI-based extensions, additional information for functions
260 * with a native-implementation is here. If this isn't a function
261 * with an HNI-based native implementation, this will be nullptr.
263 std::unique_ptr<NativeInfo> nativeInfo;
265 private:
267 * All owning pointers to blocks are in this vector, which has the
268 * blocks in an unspecified order. Blocks use BlockIds to represent
269 * control flow arcs. The id of a block is its index in this vector.
271 * Use WideFunc to access this data.
273 copy_ptr<CompactVector<char>> rawBlocks;
275 friend struct WideFunc;
279 * Representation of a function, class method, or pseudomain function.
281 struct Func : FuncBase {
283 * An index, so we can lookup auxiliary structures efficiently
285 uint32_t idx;
288 * Basic information about the function.
290 LSString name;
291 SrcInfo srcInfo;
292 Attr attrs;
295 * Parameters and locals.
297 * There are at least as many locals as parameters (parameters are also
298 * locals - the names of parameters are stored in the locals vector.)
300 CompactVector<Param> params;
301 CompactVector<Local> locals;
305 * Which unit defined this function. If it is a method, the cls
306 * field will be set to the class that contains it.
308 Unit* unit;
309 Class* cls;
312 * Entry point blocks for default value initializers.
314 * Note that in PHP you can declare functions where some of the
315 * earlier parameters have default values, and later ones don't. In
316 * this case we'll have NoBlockIds after the first valid entry here.
318 CompactVector<BlockId> dvEntries;
321 * The number of (nested) iterators used within this function.
323 IterId numIters;
326 * The number of closures used within this function.
328 ClosureId numClosures;
331 * Entry point to the function when the number of passed args is
332 * equal to the number of parameters.
334 BlockId mainEntry;
337 * User-visible return type specification as a string. This is only
338 * passed through to expose it to reflection.
340 LSString returnUserType;
343 * If traits are being flattened by hphpc, we keep the original
344 * filename of a function (the file that defined the trait) so
345 * backtraces and things work correctly. Otherwise this is nullptr.
346 * Similarly, if hhbbc did the flattening itself, we need the original
347 * unit, to get to the srcLocs. Once we stop flattening in hphpc, we can
348 * drop the originalFilename.
350 LSString originalFilename;
351 Unit* originalUnit{};
354 * The refernece of the trait where the method was originally defined.
355 * This is used to detected if a method is imported multiple
356 * times via different use-chains as the pair (name, originalClass)
357 * uniquely identifies a method.
359 Class* originalClass;
362 * This is the generated function for a closure body. I.e. this
363 * function contains the code that should run when the closure is
364 * invoked.
366 bool isClosureBody : 1;
369 * This is an async function.
371 bool isAsync : 1;
374 * This is a generator.
376 bool isGenerator : 1;
379 * This generator yields key value pairs.
381 bool isPairGenerator : 1;
383 bool isMemoizeWrapper : 1;
384 bool isMemoizeWrapperLSB : 1;
386 bool isMemoizeImpl : 1;
389 * This is a reified function.
391 bool isReified : 1;
393 bool noContextSensitiveAnalysis: 1;
395 bool hasInOutArgs : 1;
397 bool sampleDynamicCalls : 1;
399 bool hasCreateCl : 1; // Function has CreateCl opcode
401 bool isReadonlyReturn : 1;
403 bool isReadonlyThis : 1;
406 * Type parameter upper bounds. May be enforced and used for optimizations.
408 bool hasParamsWithMultiUBs : 1;
409 bool hasReturnWithMultiUBs : 1;
410 CompactVector<TypeConstraint> returnUBs;
413 * Return type specified in the source code (ex. "function foo(): Bar").
414 * HHVM checks if the a function's return value matches it's return type
415 * constraint via the VerifyRetType* instructions.
417 TypeConstraint retTypeConstraint;
420 * Static coeffects in bit encoding
422 RuntimeCoeffects requiredCoeffects{RuntimeCoeffects::none()};
423 RuntimeCoeffects coeffectEscapes{RuntimeCoeffects::none()};
426 * Lists of all static coeffect names and coeffect rules
428 CompactVector<LowStringPtr> staticCoeffects;
429 CompactVector<CoeffectRule> coeffectRules;
432 * User attribute list.
434 UserAttributeMap userAttributes;
438 //////////////////////////////////////////////////////////////////////
441 * A class property.
443 * Both static and instance properties use this structure.
445 struct Prop {
446 LSString name;
447 Attr attrs;
448 UserAttributeMap userAttributes;
449 LSString docComment;
451 LSString userType;
452 TypeConstraint typeConstraint;
453 CompactVector<TypeConstraint> ubs;
456 * The default value of the property, for properties with scalar
457 * initializers. May be KindOfUninit in some cases where the
458 * property should not have an initial value (i.e. not even null).
460 TypedValue val;
464 * A class constant.
466 struct Const {
467 LSString name;
469 // The class that defined this constant.
470 php::Class* cls;
473 * The value will be KindOfUninit if the class constant is defined
474 * using an 86cinit method.
477 Optional<TypedValue> val;
479 std::vector<LowStringPtr> coeffects;
481 SArray resolvedTypeStructure;
483 ConstModifiers::Kind kind;
485 using Invariance = PreClass::Const::Invariance;
486 Invariance invariance : 2;
487 bool isAbstract : 1;
488 bool isFromTrait : 1;
492 * Similar to FuncBase - separate the fields that need special
493 * attention when copying.
495 struct ClassBase {
496 ClassBase() = default;
497 ClassBase(const ClassBase&);
498 ClassBase(ClassBase&&) = delete;
499 ClassBase& operator=(const ClassBase&) = delete;
502 * Methods on the class. If there's an 86cinit, it must be last.
504 CompactVector<std::unique_ptr<php::Func>> methods;
508 * Representation of a php class declaration.
510 struct Class : ClassBase {
512 * Basic information about the class.
514 LSString name;
515 SrcInfo srcInfo;
516 Attr attrs;
519 * The id used to reference the class within its unit
521 int32_t id;
524 * Which unit defined this class.
526 Unit* unit;
529 * Name of the parent class.
531 LSString parentName;
534 * If this class represents a closure, this points to the class that
535 * lexically contains the closure, if there was one. If this class
536 * doesn't represent a closure, this will be nullptr.
538 * The significance of this is that closures created lexically
539 * inside of a class run as if they were part of that class context
540 * (with regard to access checks, etc).
542 php::Class* closureContextCls;
545 * Names of inherited interfaces.
547 CompactVector<LowStringPtr> interfaceNames;
550 * Names of included enums.
552 CompactVector<LowStringPtr> includedEnumNames;
555 * Names of used traits, number of declared (i.e., non-trait, non-inherited)
556 * methods, trait alias/precedence rules (if any).
558 * This is using the exact structures from the runtime PreClass. In
559 * WholeProgram mode, we won't see these because traits will already be
560 * flattened.
562 CompactVector<LowStringPtr> usedTraitNames;
563 CompactVector<PreClass::ClassRequirement> requirements;
564 CompactVector<PreClass::TraitPrecRule> traitPrecRules;
565 CompactVector<PreClass::TraitAliasRule> traitAliasRules;
568 * Properties defined on this class.
570 CompactVector<Prop> properties;
573 * Constants defined on this class.
575 CompactVector<Const> constants;
578 * User attributes for this class declaration.
580 UserAttributeMap userAttributes;
583 * The underlying base type, if this is an enum
585 TypeConstraint enumBaseTy;
588 * This is a reified class.
590 bool hasReifiedGenerics : 1;
592 * This class has at least one const instance property.
594 bool hasConstProp : 1;
596 * Dynamic construction of this class can yield at most a warning and is
597 * sampled at a user defined rate.
599 bool sampleDynamicConstruct : 1;
602 struct Constant {
603 Unit* unit;
604 LSString name;
605 TypedValue val;
606 Attr attrs;
609 struct TypeAlias {
610 Unit* unit;
611 SrcInfo srcInfo;
612 LSString name;
613 LSString value;
614 Attr attrs;
615 AnnotType type;
616 bool nullable; // null is allowed; for ?Foo aliases
617 UserAttributeMap userAttrs;
618 Array typeStructure{ArrayData::CreateDict()};
619 Array resolvedTypeStructure;
622 //////////////////////////////////////////////////////////////////////
625 * Information regarding a runtime/parse error in a unit
627 struct FatalInfo {
628 Location::Range fatalLoc;
629 FatalOp fatalOp;
630 std::string fatalMsg;
634 * Representation of a php file (normal compilation unit).
636 struct Unit {
637 int64_t sn{-1};
638 SHA1 sha1;
639 LSString filename;
640 std::unique_ptr<FatalInfo> fatalInfo{nullptr};
641 CompactVector<std::unique_ptr<Func>> funcs;
642 CompactVector<std::unique_ptr<Class>> classes;
643 CompactVector<std::unique_ptr<TypeAlias>> typeAliases;
644 CompactVector<std::unique_ptr<Constant>> constants;
645 CompactVector<SrcLoc> srcLocs;
646 UserAttributeMap metaData;
647 UserAttributeMap fileAttributes;
651 * A php Program is a set of compilation units.
653 struct Program {
654 std::mutex lock;
655 std::atomic<uint32_t> nextFuncId{};
656 std::vector<std::unique_ptr<Unit>> units;
657 std::vector<php::Func*> constInits;
660 //////////////////////////////////////////////////////////////////////
662 std::string show(const Func&);
663 std::string show(const Func&, const Block&);
664 std::string show(const Func&, const Bytecode& bc);
665 std::string show(const Class&);
666 std::string show(const Unit&);
667 std::string show(const Program&);
668 std::string local_string(const Func&, LocalId);
670 inline std::string show(const Func* f, const Bytecode& bc) {
671 return show(*f, bc);
674 //////////////////////////////////////////////////////////////////////
676 bool check(const Func&);
677 bool check(const Class&);
678 bool check(const Unit&);
679 bool check(const Program&);
681 //////////////////////////////////////////////////////////////////////