Optimize idx/ArrayGet for OOB/undefined index on static arrays by keeping a side...
[hiphop-php.git] / hphp / doc / ir.specification
bloba095d9b239216b25f4b02a3e735ce32bb64a9b11
1 *******************************************
2 * HipHop Intermediate Representation (HHIR)
3 *******************************************
7 Introduction
8 ------------
10 The HipHop Intermediate Representation (IR) is a typed, in-memory,
11 static-single-assignment, intermediate-level representation of HHBC programs
12 used for just in time compilation, with these goals:
14   1. Complete. The IR represents a program or program fragment entirely,
15      without reference to HHBC or other upstream forms of the program.
17   2. Type-Safe. Since the IR deals directly with refined types and internal VM
18      types, all operations are typesafe. All instruction parameters have a
19      parameter type P, and all variables have a type S. Given an instruction
20      with source parameter type P and variable type S, S must be equal to or
21      more refined than P (S == P or S <: P).
23   3. Machine Independent. Since this IR is intended to be used in a JIT
24      compiler, it will always be used in a machine specific context.
25      Nevertheless, we rely on machine independence in order to separate
26      concerns and increase portability of the VM. Passes which manipulate IR
27      based on PHP or HHBC semantics should be portable. Passes which deal with
28      machine specifics (such as register allocation) should be done in the
29      lower level IR (vasm). Types are machine independent.
31 The unit of compilation is the IRUnit, which is a collection of Blocks
32 containing IRInstructions that produce and consume SSATmp values. Blocks are
33 single-entry, single-exit sequences of instructions (i.e. basic
34 blocks). Instructions may be annotated with Type parameter which modifies the
35 instruction's behavior, or with additional compile-time constant data (see
36 extra-data.h). Each SSATmp has a Type which describes the set of values it may
37 hold, over its entire live range. Instructions may have side effects, which
38 occur in execution order.
40 The static single assignment form guarantees the following two invariants for a
41 well-formed compilation unit:
43   1. Each SSATmp is assigned to by exactly one IRInstruction.
45   2. Definitions dominate uses. Every path to an IRInstruction using an SSATmp
46      first executes the IRInstruction defining the SSATmp.
48 Any pass that generates or manipulates IR must preserve these invariants,
49 however it is possible and expected for the invariants to be temporarily broken
50 during IR generation or during an optimization pass.
53 Control Flow
54 ------------
56 IRUnits have one entry block, zero or more exit blocks, and zero or more catch
57 blocks. Exit blocks leave the compilation unit in the middle of the same PHP
58 function using one of several instructions that exit a compilation unit
59 (e.g. ReqBindJmp). Catch blocks are blocks that are reachable from exceptional
60 control flow edges, and are executed during unwinding if an exception
61 propagates through the instruction that had it as a `taken' edge.
63 No SSATmps are defined on entry to the main Block.
65 Blocks which are join points may start with a DefLabel with destination
66 SSATmps. In that case, each predecessor must be a Jmp passing a matching number
67 of sources. In this case the Jmp acts as a tail-call, passing arguments the
68 same way a plain call would.
70 Together, the sources of the Jmp instructions and the destinations of the
71 DefLabel instructions act as traditional SSA Phi pseudo-functions; The type of
72 the DefLabel's destination is the type-union of the corresponding sources.
73 Because the Jmp sources are at the ends of blocks, they do not violate the SSA
74 dominator rule (rule 2, above).
77 Types
78 -----
80 For an overview of the HHIR type system, see the "Type System" section in
81 hackers-guide/jit-core.md.
84 SSATmps
85 -------
87 An SSATmp represents a virtual register. Since HHIR uses SSA, an SSATmp may
88 only be assigned to by one instruction. The type of an SSATmp represents the
89 set of values it may hold at the point it is defined, which is invariant over
90 the lifetime of the variable (from the definition point to the last use).
93 IRInstructions
94 --------------
96 An instruction is an executable operation with zero or more inputs (sources),
97 zero or one result (destination), and possible side effects such as accessing
98 memory, doing I/O, and which may branch or throw an exception. Some
99 instructions have a Type parameter which modifies its behavior, or other "extra
100 data" in an arbitrary C++ struct (see extra-data.h).
102 Each instruction has a signature which describes its effect, parameter types,
103 and return type, for example:
105   IsType<T>, D(Bool), S(Cell), NF
107 The first column is the instruction name (and optional Type parameter in <>).
109 The second column describes the result (destination) using one of the D*
110 macros documented in hphp/runtime/vm/jit/ir-opcode.h, or ND for no destination.
112 The third column describes the sources, separated by whitespace, using macros
113 documented in hphp/runtime/vm/jit/ir-opcode.h, or NA if there are no sources.
115 The fourth column contains the flags, described below. The short name of the
116 flag (used in this file) is given first, with the long name that it expands to
117 in hphp/runtime/vm/jit/ir-opcode.cpp in parentheses after it.
121   The instruction has no flags.
123 PRc (ProducesRC)
125   The instruction produces a value with an unconsumed reference that must be
126   consumed, either by DecRefing it or storing it somewhere in memory.
128 CRc (ConsumesRC)
130   The instruction consumes a reference to one or more of its sources, either by
131   decreasing its refcount or storing the reference to memory.
133 T (Terminal)
135   The instruction has no next instruction; it either jumps, returns, or throws.
137 B (Branch)
139   The instruction has a (sometimes optional) taken edge. Instructions that are
140   conditional branches (i.e. a Branch that is not Terminal) will also have a
141   next edge.
143 P (Passthrough)
145   The value of the instruction's dest is the same as one of its inputs; it
146   differs only in the type of the variable, or some other property that doesn't
147   affect the value of the variable itself.
149 MProp (MInstrProp)
151   The instruction may affect the type and/or value of its base operand,
152   operating on object properties.
154 MElem (MInstrElem)
156   The instruction may affect the type and/or value of its base operand,
157   operating on array elements.
159 LA (Layout-Agnostic)
161 The instruction is generic over array-like inputs and outputs. Most ops that
162 deal with array-like types can only handle their default ("Vanilla") layouts.
163 We whitelist those ops that are generic over layout.
166 Instruction set
167 ---------------
169 1. Checks and Asserts
171 | CheckType<T>, DRefineS(0), S(Cell), B|P
173   Check that the type of the src S0 is T, and if so copy it to D, and
174   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
175   this means S0 still /may/ be a subtype of T in block B in some circumstances.
177   Specifically, subtypes of Type::Static may not be checked precisely,
178   depending on the type of the source.  This means the instruction may take the
179   branch in some circumstances even when S0 is a subtype of T, if T has a
180   non-empty intersection with Type::Static.
182   Also note that many types are not supported as the typeParam right now.
184 | CheckNullptr, ND, S(Cls|StaticStr|Nullptr), B
186   If S0 is not a null pointer, branch to block B. This is used to check the
187   return value of a native helper that returns a potentially null StringData*.
189 | AssertType<T>, DRefineS(0), S(Cell,MemToCell), P
191   Assert that the type of S0 is T, copying it to D.
193 | CheckTypeMem<T>, ND, S(MemToCell), B
195   If the value pointed to by S0 is not type T, branch to the block B.
197 | CheckVArray, DCheckDV(Packed), S(Arr), B|P|LA
199   Check that S0 is a varray, and if so copy it to D, and fallthrough. If S0 is
200   not a varray, branch to block B.
202 | CheckDArray, DCheckDV(Mixed), S(Arr), B|P|LA
204   Check that S0 is a darray, and if so copy it to D, and fallthrough. If S0 is
205   not a darray, branch to block B.
207 | CheckDVArray, D(Arr), S(Arr), B|P|LA
209   Check that S0 is a darray or varray, and if so copy it to D, and fallthrough.
210   If S0 is not a darray or varray, branch to block B.
212 | CheckIter<iterId,iterType>, ND, S(FramePtr), B
214   Check that specialization type of the given iterator `iterId` on the frame S0
215   is `iterType`; if it is not, branch to block B.
217 | CheckLoc<T,localId>, ND, S(FramePtr), B
219   Check that type of the given localId on the frame S0 is T; if not, branch to
220   block B.
222 | CheckStk<T,offset>, ND, S(StkPtr), B
224   Check that the type of the cell on the stack pointed to by S0 at offset (in
225   cells) is T; if not, branch to block B.
227 | CheckMBase<T>, ND, S(LvalToCell), B
229   Check that the value pointed to by the member base register S0 has type T; if
230   not, branch to block B.  This is functionally the same as CheckTypeMem.
232 | AssertLoc<T,localId>, ND, S(FramePtr), NF
234   Asserts that type of the supplied local on the frame S0 is T. This is used
235   for local type information, and is similar to CheckLoc except it doesn't
236   imply a runtime check (the assertion must've already been proven to be true)
237   and cannot cause control flow.
239 | AssertStk<T,offset>, ND, S(StkPtr), NF
241   Assert that stack element at `offset' (in cells) from S0 has type T. This is
242   similar to a CheckStk except that it does not imply a runtime check and
243   cannot cause control flow.
245 | AssertMBase<T>, ND, NA, NF
247   Assert that the value pointed to by the member base register has type T.
248   This is similar to a CheckMBase except that it does not imply a runtime check
249   and cannot cause control flow.
251   These instructions convert either a Cell or a Str to a primitive type (Bool,
252   Int, Dbl) and return the resulting value. They may throw an exception upon
253   failed type coercion. They are encoded along with callee Func, fn, and the
254   integer position of the argument, argNum, being coerced.
256 | CheckInit, ND, S(Cell), B
258   If S0's type is Uninit, branch to block B.
260 | CheckInitMem, ND, S(MemToCell), B
262   If the value pointed to by S0 has type Uninit, branch to block B.
264 | CheckCold<TransID>, ND, NA, B
266   Check if the counter associated with translation TransID is cold (i.e. within
267   a fixed threshold). If it's not (i.e. such translation has reached the
268   "hotness threshold"), then branch to block B.
270 | CheckInOuts<firstBit,mask,vals>, ND, S(Func) S(Int), B
272   Perform inout-ness guard checks. Operands:
274     S0 - function pointer for the callee
275     S1 - num params expected in the func
276     firstBit - first bit to check, must be a multiple of 64
277     mask - mask to check
278     vals - values to check
280   For each bit `i` set in the mask, checks whether inout-ness of parameter
281   `firstBit + i` of S0 is equal to the bit `i` of vals.
283   If any of the checks fail, branch to block B.
285 | EndGuards, ND, NA, NF
287   A no-op at runtime, this instruction serves to mark the end of the initial
288   sequence of guards in a trace.
290 | CheckNonNull, DSubtract(0, Nullptr), S(Cls|Func|Obj|Str|PtrToCell|TCA|Nullptr), B
292   If the value in S0 is Nullptr, branch to block B. If S0 cannot be Nullptr, or
293   always is Nullptr, this check may be optimized away.
295 | AssertNonNull, DSubtract(0, Nullptr), S(StaticStr|Nullptr), P
297   Returns S0, with Nullptr removed from its type. This instruction currently
298   supports a very limited range of types but can be expanded if needed.
300 | CheckSmashableClass, ND, S(Smashable) S(Cls), B
302   If the lower 32 bits of S0 does not match class pointer S1, branch to block B.
304 2. Arithmetic
306 | AddInt, D(Int), S(Int) S(Int), NF
308 | SubInt, D(Int), S(Int) S(Int), NF
310 | MulInt, D(Int), S(Int) S(Int), NF
312 | AddIntO, D(Int), S(Int) S(Int), B
314 | SubIntO, D(Int), S(Int) S(Int), B
316 | MulIntO, D(Int), S(Int) S(Int), B
318 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
320 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
322 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
324 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
326 | DivInt, D(Int), S(Int) S(Int), NF
328 | Floor, D(Dbl), S(Dbl), NF
330 | Ceil, D(Dbl), S(Dbl), NF
332 | AbsDbl, D(Dbl), S(Dbl), NF
334 | Sqrt, D(Dbl), S(Dbl), NF
336 | AndInt, D(Int), S(Int) S(Int), NF
338 | OrInt, D(Int), S(Int) S(Int), NF
340 | XorInt, D(Int), S(Int) S(Int), NF
342 | Shl, D(Int), S(Int) S(Int), NF
344 | Shr, D(Int), S(Int) S(Int), NF
346 | Lshr, D(Int), S(Int) S(Int), NF
348   Double arithmetic, integer arithmetic, and integer bitwise operations.
349   Performs the operation described by the opcode name on S0 and S1, and puts
350   the result in D.
352   Undefined behavior occurs if Mod is given a divisor of zero, or if the
353   divisor is -1 and the dividend is the minimum representable integer.
355   AbsDbl computes the absolute value of a double-precision value.
357   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
358   or NAN depending on the dividend; and should the result of a division be zero
359   the sign will follow the normal sign rules for division.
361   DivInt will perform integer division of S1 by S0. S0 should not be zero and
362   must divide S1.
364   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
366   Lshr is logical right shift.
368   Floor and Ceil will return an integral value not greater, or not less
369   than their input respectively. Their use requires SSE 4.1, availability
370   should be checked before they are emitted.
372   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
373   branch to block B on integer overflow.
375 | XorBool, D(Bool), S(Bool) S(Bool), NF
377   Logical XOR of the two sources. (Note that && and || do not have
378   corresponding opcodes because they're handled at the bytecode level, to
379   implement short-circuiting.)
381 | Mod, D(Int), S(Int) S(Int), NF
383   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
386 3. Type conversions
388 To array conversions:
390 | ConvBoolToArr,                D(Arr), S(Bool),                     PRc
392 | ConvDblToArr,                 D(Arr), S(Dbl),                      PRc
394 | ConvIntToArr,                 D(Arr), S(Int),                      PRc
396 | ConvObjToArr,                 D(Arr), S(Obj),                      PRc|CRc
398 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
400 | ConvVecToArr,                 D(Arr), S(Vec),                      PRc|CRc
402 | ConvDictToArr,                D(Arr), S(Dict),                     PRc|CRc
404 | ConvKeysetToArr,              D(Arr), S(Keyset),                   PRc|CRc
406 | ConvFuncToArr,                D(Arr), S(Func),                     PRc
408 | ConvClsMethToArr,             D(Arr), S(ClsMeth),                  PRc|CRc
410 | ConvTVToArr,                  D(Arr), S(Cell),                     PRc|CRc
412 | ConvArrToNonDVArr,            D(Arr), S(Arr),                      PRc|CRc
415 To vec conversions:
417 | ConvArrToVec,                 D(Vec), S(Arr),                      PRc|CRc
419 | ConvDictToVec,                D(Vec), S(Dict),                     PRc|CRc
421 | ConvKeysetToVec,              D(Vec), S(Keyset),                   PRc|CRc
423 | ConvClsMethToVec,             D(Vec), S(ClsMeth),                  PRc|CRc
425 | ConvObjToVec,                 D(Vec), S(Obj),                      PRc|CRc
428 To dict conversions:
430 | ConvArrToDict,                D(Dict), S(Arr),                     PRc|CRc
432 | ConvVecToDict,                D(Dict), S(Vec),                     PRc|CRc
434 | ConvKeysetToDict,             D(Dict), S(Keyset),                  PRc|CRc
436 | ConvClsMethToDict,            D(Dict), S(ClsMeth),                 PRc|CRc
438 | ConvObjToDict,                D(Dict), S(Obj),                     PRc|CRc
441 To keyset conversions:
443 | ConvArrToKeyset,              D(Keyset), S(Arr),                   PRc|CRc
445 | ConvVecToKeyset,              D(Keyset), S(Vec),                   PRc|CRc
447 | ConvDictToKeyset,             D(Keyset), S(Dict),                  PRc|CRc
449 | ConvClsMethToKeyset,          D(Keyset), S(ClsMeth),               PRc|CRc
451 | ConvObjToKeyset,              D(Keyset), S(Obj),                   PRc|CRc
454 To varray conversions:
456 | ConvArrToVArr,                DVArr, S(Arr),                        PRc|CRc
458 | ConvVecToVArr,                DVArr, S(Vec),                        PRc|CRc
460 | ConvDictToVArr,               DVArr, S(Dict),                       PRc|CRc
462 | ConvKeysetToVArr,             DVArr, S(Keyset),                     PRc|CRc
464 | ConvClsMethToVArr,            DVArr, S(ClsMeth),                    PRc|CRc
466 | ConvObjToVArr,                DVArr, S(Obj),                        PRc|CRc
469 To darray conversion:
471 | ConvArrToDArr,                DDArr, S(Arr),                       PRc|CRc
473 | ConvVecToDArr,                DDArr, S(Vec),                       PRc|CRc
475 | ConvDictToDArr,               DDArr, S(Dict),                      PRc|CRc
477 | ConvKeysetToDArr,             DDArr, S(Keyset),                    PRc|CRc
479 | ConvClsMethToDArr,            DDArr, S(ClsMeth),                   PRc|CRc
481 | ConvObjToDArr,                DDArr, S(Obj),                       PRc|CRc
484 To bool conversions:
486 | ConvArrToBool,               D(Bool), S(Arr),                           NF
488 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
490 | ConvIntToBool,               D(Bool), S(Int),                           NF
492 | ConvStrToBool,               D(Bool), S(Str),                           NF
494 | ConvObjToBool,               D(Bool), S(Obj),                           NF
496 | ConvTVToBool,                D(Bool), S(Cell),                          NF
499 To double conversions:
501 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
503 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
505 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
507 | ConvObjToDbl,                 D(Dbl), S(Obj),                           NF
509 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
511 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
513 | ConvTVToDbl,                  D(Dbl), S(Cell),                          NF
516 To int conversions:
518 | ConvBoolToInt,                D(Int), S(Bool),                          NF
520 | ConvDblToInt,                 D(Int), S(Dbl),                           NF
522 | ConvObjToInt,                 D(Int), S(Obj),                           NF
524 | ConvStrToInt,                 D(Int), S(Str),                           NF
526 | ConvResToInt,                 D(Int), S(Res),                           NF
528 | ConvTVToInt,                  D(Int), S(Cell),                          NF
531 To string conversions:
533 | ConvDblToStr,                 D(Str), S(Dbl),                           PRc
535 | ConvIntToStr,                 D(Str), S(Int),                           PRc
537 | ConvObjToStr,                 D(Str), S(Obj),                           PRc
539 | ConvResToStr,                 D(Str), S(Res),                           PRc
541 | ConvTVToStr,                  D(Str), S(Cell),                          PRc
544   All the above opcodes convert S0 from its current type to the destination
545   type, according to the PHP semantics of such a conversion.
547 | DblAsBits,                    D(Int), S(Dbl),                           NF
549   Reinterpret a double as an integer with the same bit pattern.
551 | OrdStr,                       D(Int), S(Str),                           NF
553   Convert the first byte in a string to an unsigned integer.
554   Intended as an optimization for ord($str)
556 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    NF
558   Convert the character at position S1 in base string S0 to an unsigned
559   integer.  Raises a notice if the position is out of bounds.
560   Intended as an optimization for ord($str[$idx]).
562 | ChrInt,                      D(StaticStr), S(Int),                      NF
564   Convert the integer S0 to a the one character string with ascii code
565   S0 & 255.
567 | StrictlyIntegerConv,         D(Str|Int), S(Str),                        PRc
569   If S0 is a string representing an integer value (same criteria as array key
570   conversion), return that value as an integer. Otherwise return S0.
572 | ConvPtrToLval,               DLvalOfPtr, S(PtrToCell),                  NF
574   Convert S0 to an equivalent lval.
577 4. Boolean predicates
579 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
581 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
583 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
585 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
587 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
589 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
591 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
593   Perform 64-bit integer comparisons.
595 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
597 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
599 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
601 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
603 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
605 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
607 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
609   Perform comparisons of doubles. Comparisons that are unordered according to
610   IEEE 754 (such as when at least one operand is NaN) result in false.
612 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
614 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
616 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
618 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
620 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
622 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
624 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
626 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
628 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
630   Performs comparison of strings using PHP semantics.
632 | GtStrInt,                    D(Bool), S(Str) S(Int),                    NF
634 | GteStrInt,                   D(Bool), S(Str) S(Int),                    NF
636 | LtStrInt,                    D(Bool), S(Str) S(Int),                    NF
638 | LteStrInt,                   D(Bool), S(Str) S(Int),                    NF
640 | EqStrInt,                    D(Bool), S(Str) S(Int),                    NF
642 | NeqStrInt,                   D(Bool), S(Str) S(Int),                    NF
644 | CmpStrInt,                   D(Int),  S(Str) S(Int),                    NF
646   Performs comparison of strings with integers using PHP semantics.
648 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
650 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
652 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
654 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
656 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
658 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
660 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
662   Performs comparison of booleans.
664 | GtObj,                       D(Bool), S(Obj) S(Obj),                    NF
666 | GteObj,                      D(Bool), S(Obj) S(Obj),                    NF
668 | LtObj,                       D(Bool), S(Obj) S(Obj),                    NF
670 | LteObj,                      D(Bool), S(Obj) S(Obj),                    NF
672 | EqObj,                       D(Bool), S(Obj) S(Obj),                    NF
674 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    NF
676 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
678 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
680 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    NF
682   Perform comparison of objects using PHP semantics. All versions except for
683   SameObj and NSameObj may re-enter the VM and therefore may throw
684   exceptions. SameObj and NSameObj never re-enter or throw.
686 | GtArr,                       D(Bool), S(Arr) S(Arr),                    NF
688 | GteArr,                      D(Bool), S(Arr) S(Arr),                    NF
690 | LtArr,                       D(Bool), S(Arr) S(Arr),                    NF
692 | LteArr,                      D(Bool), S(Arr) S(Arr),                    NF
694 | EqArr,                       D(Bool), S(Arr) S(Arr),                    NF
696 | NeqArr,                      D(Bool), S(Arr) S(Arr),                    NF
698 | SameArr,                     D(Bool), S(Arr) S(Arr),                    NF
700 | NSameArr,                    D(Bool), S(Arr) S(Arr),                    NF
702 | CmpArr,                      D(Int),  S(Arr) S(Arr),                    NF
704   Perform comparison of arrays using PHP semantics. All versions except for
705   SameArr and NSameArr may re-enter the VM and therefore may throw
706   exceptions. SameArr and NSameArr never re-enter or throw.
708 | GtVec,                       D(Bool), S(Vec) S(Vec),                    NF
710 | GteVec,                      D(Bool), S(Vec) S(Vec),                    NF
712 | LtVec,                       D(Bool), S(Vec) S(Vec),                    NF
714 | LteVec,                      D(Bool), S(Vec) S(Vec),                    NF
716 | EqVec,                       D(Bool), S(Vec) S(Vec),                    NF
718 | NeqVec,                      D(Bool), S(Vec) S(Vec),                    NF
720 | SameVec,                     D(Bool), S(Vec) S(Vec),                    NF
722 | NSameVec,                    D(Bool), S(Vec) S(Vec),                    NF
724 | CmpVec,                      D(Int),  S(Vec) S(Vec),                    NF
726   Perform comparison of vecs. All versions except for SameVec and NSameVec may
727   re-enter the VM and therefore may throw exceptions. SameVec and NSameVec
728   never re-enter or throw.
730 | EqDict,                      D(Bool), S(Dict) S(Dict),                  NF
732 | NeqDict,                     D(Bool), S(Dict) S(Dict),                  NF
734 | SameDict,                    D(Bool), S(Dict) S(Dict),                  NF
736 | NSameDict,                   D(Bool), S(Dict) S(Dict),                  NF
738   Perform comparison of dicts. EqDict and NeqDict may re-enter the VM and
739   therefore may throw exceptions. SameDict and NSameDict never re-enter or
740   throw. Relational comparisons for dicts are not supported.
742 | EqKeyset,                    D(Bool), S(Keyset) S(Keyset),              NF
744 | NeqKeyset,                   D(Bool), S(Keyset) S(Keyset),              NF
746 | SameKeyset,                  D(Bool), S(Keyset) S(Keyset),              NF
748 | NSameKeyset,                 D(Bool), S(Keyset) S(Keyset),              NF
750   Perform comparison of keysets. As keysets can only contain ints and strings,
751   comparisons never re-enter or throw. Relational comparisons for keysets are
752   not supported.
754 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
756 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
758 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
760 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
762 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
764 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
766 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
768   Perform comparison of resources using PHP semantics. Resource comparisons
769   never re-enter or throw.
771 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
773   Checks if two Class values are equal.
775 | EqRecDesc,                   D(Bool), S(RecDesc) S(RecDesc),            NF
777   Checks if two record types are equal.
779 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
781   Checks if two Func values are equal.
783 | EqStrPtr,                    D(Bool), S(Str) S(Str),                    NF
785   Checks if two string values represent the same underlying string. That is,
786   that they point at the same underlying storage.
788 | EqArrayDataPtr,              D(Bool), S(ArrLike) S(ArrLike),            LA
790   Checks if the two arguments represent the same underlying ArrayData. That is,
791   that they point at the same underlying storage.
793 | ProfileInstanceCheck, ND, C(StaticStr), NF
795   Profile that S0 has been used as the RHS of an instance check.
797 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
799   Sets D based on whether S0 is a descendant of the class, interface, or trait
800   in S1. (Note that this is always false for a trait). S1 may be null at
801   runtime if the class is not defined.
803 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
805   Fast path for interface checks. Sets D based on whether S0 implements S1, but
806   S1 must be a unique interface. This should only be used in repo-authoritative
807   mode.
809 | InstanceOfIfaceVtable<iface,canOptimize>, D(Bool), S(Cls), NF
811   Faster path for interface checks. Sets D based on whether S0 implements
812   iface, which must be a unique interface with an assigned vtable slot.  In
813   some circumstances, this instruction is ensuring the presence of the
814   vtableVec; in those cases, canOptimize is false to avoid eliminating the
815   guard.
817 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
819   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
820   of cls, where cls must be a unique class that is not an interface or a trait.
822   If strictLikely is true, optimize for the case where S0 is not equal to S1.
824 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
826 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
828   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
829   of the class named by S1, where S1 must have a bit allocated for it in the
830   fast instance check bitvector (see class.h).
832 | InstanceOfRecDesc, D(Bool), S(RecDesc) S(RecDesc), NF
834   Sets D to true if S0 is a descendant of the record in S1, false otherwise.
836 | InterfaceSupportsArr,        D(Bool), S(Str), NF
838 | InterfaceSupportsVec,        D(Bool), S(Str), NF
840 | InterfaceSupportsDict,       D(Bool), S(Str), NF
842 | InterfaceSupportsKeyset,     D(Bool), S(Str), NF
844 | InterfaceSupportsStr,        D(Bool), S(Str), NF
846 | InterfaceSupportsInt,        D(Bool), S(Str), NF
848 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
850   Returns whether t instanceof S0 returns true when t is of the given type.
852 | ResolveTypeStruct<class,suppress,offset,size,isOrAsOp>,
853 |   DDArr, S(StkPtr) S(Cls|Nullptr), NF
855   Applies class/alias resolution on the type structure that is at the stack
856   offset given by S0 and offset. If size > 1, combine the type structures on
857   the stack into the first one's denoted holes. Returns a copy.
858   S1 is the calling class, used to resolve the this typehint.
859   If isOrAsOp is set, raises an error if S0 contains traits, function types or
860   typevars.
861   If there is an error during type structure resolution, this instruction raises
862   an error. If suppress is set, this error is demoted to a warning.
864 | IsTypeStruct, D(Bool), SDArr S(Cell), NF
866   Returns whether S1 matches the type structure of a defined type in S0 and S1
867   is a subtype of S0. The input type structure (S0) must be resolved.
869 | ThrowAsTypeStructException, ND, SDArr S(Cell), T
871   Throws an exception indicating why S1 does not match the type structure of a
872   defined type in S0 or why S1 is not a subtype of S0. The input type structure
873   (S0) must be resolved.
875 | RaiseErrorOnInvalidIsAsExpressionType, DDArr, SDArr, NF
877   Raises an error if the type hint for is/as expression contains an invalid
878   type such as callables, erased type variables and trait type hints.
879   The input type structure (S0) must be resolved.
881 | HasToString, D(Bool), S(Obj), NF
883   Returns whether the object S0 has a toString method.
885 | IsType<T>, D(Bool), S(Cell), NF
887   Sets D to true iff S0 holds a value that is of type T. T must not be a
888   specialized type.
890 | IsNType<T>, D(Bool), S(Cell), NF
892   Sets D to true iff S0 holds a value that is not of type T. T must not be a
893   specialized type.
895 | IsTypeMem<T>, D(Bool), S(MemToCell), NF
897   Sets D to true iff the value referenced by S0 is of type T. T must not be a
898   specialized type.
900   The value in S0 must not be a pointer into the evaluation stack or frame
901   locals.
903 | IsNTypeMem<T>, D(Bool), S(MemToCell), NF
905   Sets D to true iff the value referenced by S0 is not of type T. T must not be
906   a specialized type.
908 | IsWaitHandle, D(Bool), S(Obj), NF
910   Sets D to true iff S0 is a subclass of WaitHandle.
912 | IsCol, D(Bool), S(Obj), NF
914   Sets D to true iff S0 is a collection.
916 5. Branches
918 | JmpZero,                          ND, S(Int,Bool),                     B
920 | JmpNZero,                         ND, S(Int,Bool),                     B
922   Conditionally jump to based on S0.
924 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
926   Jump to the target of a sswitch statement, leaving the region, where the
927   target TCA is S0.
929 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
931   Jump to the target of a switch statement, leaving the region, using table
932   metadata <JmpSwitchData> and index S0, which must be a valid index in the
933   jump table.
935 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
937   Profile a switch statement target.
939 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
941   Tests the implementation-specific surprise flags. If they're true, branches
942   to block B. This is done by comparing an evaluation stack pointer to the RDS
943   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
944   pointing into the eval stack, so S0 should be a StkPtr in that case.
946 | HandleRequestSurprise, ND, NA, NF
948   Generate exceptions based on surprise flags on a per request basis.
949   Make sure CheckSurpriseFlags is true before calling HandleRequestSurprise.
951 | ReturnHook, ND, S(FramePtr) S(Cell), NF
953   Surprise flag hook for function returns.
955 | SuspendHookAwaitEF, ND, S(FramePtr) S(FramePtr) S(Obj), NF
957   Surprise flag hook for suspending eagerly executing async functions. The S0
958   frame was already teleported into S1. Decrefs S2 if it throws an exception.
960 | SuspendHookAwaitEG, ND, S(FramePtr) S(Obj), NF
962   Surprise flag hook for suspending eagerly executing async generators. The S0
963   frame has an associated AG, which is already linked to the newly constructed
964   AGWH in the blocked state. Decrefs S1 if it throws an exception.
966 | SuspendHookAwaitR, ND, S(FramePtr) S(Obj), NF
968   Surprise flag hook for suspending async functions and async generators resumed
969   at Await. The S0 frame has an associated AFWH/AGWH still in the running state,
970   S1 points to the child WH we are going to block on.
972 | SuspendHookCreateCont, ND, S(FramePtr) S(FramePtr) S(Obj), NF
974   Surprise flag hook for suspending generators and async generators during their
975   invocation. The S0 frame was already teleported into S1. Decrefs S2 if it
976   throws an exception.
978 | SuspendHookYield, ND, S(FramePtr), NF
980   Surprise flag hook for suspending generators and async generators at Yield.
982 | Unreachable<AssertReason>, ND, NA, T
984   Indicates an unreachable code path. Any instructions that are post-dominated
985   by an Unreachable may be treated as unreachable by the optimizer, and the
986   behavior of a program that attempts to execute an Unreachable is undefined.
988 | EndBlock<AssertReason>, ND, NA, T
990   Halt execution, without implying anything about the reachability of
991   instructions preceding this. Intended for use in internal tests or other code
992   not meant to be executed.
994 | Jmp, ND, SVar(Top), B|T
996   Unconditional jump to block B. In the second form, the target block must
997   start with a DefLabel with the same number of destinations as Jmp's number of
998   sources. Jmp parallel-copies its sources to the DefLabel destinations.
1000 | DefLabel, DMulti, NA, NF
1002   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
1003   destinations is a no-op, and the predecessor blocks may not necessarily end
1004   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
1005   instruction with the same number of sources. Ordinary branch instructions may
1006   not pass values to a DefLabel.
1008 | Select, DUnion(1,2), S(Bool,Int) S(Top) S(Top), NF
1010   If S0 is true/non-zero, return S1, otherwise return S2.
1013 6. Loads
1015 | LdStk<T,offset>, DParamMayRelax(Cell), S(StkPtr), NF
1017   Loads from S0 at offset (in cells), and puts the value in D as type T.
1019 | LdLoc<T,localId>, DParamMayRelax(Cell), S(FramePtr), NF
1021   Loads local slot localId from the frame S0 and puts the value in D as type T.
1023 | LdLocPseudoMain<T,localId>, DParam(Cell), S(FramePtr), B
1025   Loads local number localId from frame S0 and puts the value in D if the
1026   local's type is a subtype of T. If the local's type is not a subtype of T,
1027   then the load does not happen, and this instruction branches to B. This
1028   instruction is used for loading locals in pseudo-mains, where they can alias
1029   globals.
1031 | LdStkAddr<offset>, D(PtrToStkCell), S(StkPtr), NF
1033   Loads the address of the stack slot given by the pointer in S0 at the given
1034   stack offset (measured in cells).
1036 | LdLocAddr<localId>, D(PtrToFrameCell), S(FramePtr), NF
1038   Loads the address of the local slot localId from the frame S0 into D.
1040 | LdRDSAddr<T,RDSHandle>, DParam(PtrToCell), NA, NF
1042   Load the address of a Cell that lives at the specified RDS handle. The type
1043   param must be a subtype of PtrToCell.
1045 | LdInitRDSAddr<T,RDSHandle>, DParam(PtrToInitCell), NA, B
1047   Load the address of a Cell that lives at the specified RDS handle. Branch if
1048   the value at that address is Uninit. The type param must be a subtype of
1049   PtrToInitCell.
1051 | LdPairElem, D(Cell), S(Obj) S(Int), NF
1053   Load the element at S1 out of the Pair collection at S0.
1055 | LdMem<T>, DParam(Cell), S(MemToCell), NF
1057   Loads from S0 and puts the value in D.
1059 | LdContField<T>, DParam(Cell), S(Obj) C(Int), NF
1061   Loads a property from the object referenced by S0 at the offset given by S1
1062   and puts the value in D. S0 must be a Generator.
1064 | LdClsInitElem<idx>, D(Cell), S(PtrToClsInitCell), NF
1066   Load the cell at index `idx` from the class init vector at S0 into D0.
1068 | LdColVec, D(Vec), S(Obj), NF
1070   Load the vec array backing a collection instance in S0, which must be a
1071   Vector or ImmVector, and that specific object type must be known at compile
1072   time.
1074 | LdColDict, D(Dict), S(Obj), NF
1076   Load the dict array backing a collection instance in S0, which must be a
1077   Map, Set, ImmMap, or ImmSet, and that specific object type must be known at
1078   compile time.
1080 | LdIterBase<T,iterId>, DParam(ArrLike), S(FramePtr), NF
1082   Load the base of the iterator with type `T` at `iterId`. `T` must be a valid,
1083   DataTypeSpecific-or-better type for the iterator's base; for example, it may
1084   be based on an earlier call to CheckIter.
1086 | LdIterPos<T,iterId>, DParam(Int|PtrToElemCell), S(FramePtr), NF
1088 | LdIterEnd<T,iterId>, DParam(Int|PtrToElemCell), S(FramePtr), NF
1090   Load the specified field of the iterator at `iterId`. These ops should only
1091   be generated for iterators known to have a specialized type (via CheckIter).
1092   The type param `T` should be compatible with this type - i.e. `T` should be
1093   either an int or a pointer based on whether it's an index or pointer iter.
1095 | LdFrameThis, DParam(Obj), S(FramePtr), NF
1097   Loads into D the value of m_this from S0.
1099 | LdFrameCls, DParam(Cls), S(FramePtr), NF
1101   Loads into D the value of m_cls from S0.
1103 | LdClsCtor, D(Func), S(Cls) S(FramePtr), NF
1105   Loads into D the constructor of class S0. If the constructor cannot be called
1106   from the context in S1, raise an error.
1108 | LdSmashable, D(Smashable), NA, NF
1110   Loads a smashable value. The initial value is set to (1 << addr) + 1, where
1111   addr is a pointer pointing to the value in TC. The lowest bit is set for
1112   convenience of checking whether the value was already smashed.
1114 | LdSmashableFunc, D(Func), S(Smashable), NF
1116   Loads into D the func pointer stored in the higher 32 bits of S0.
1118 | LdRecDesc, D(RecDesc), S(Record), NF
1120   Load the record type out of the record in S0 and put it in D.
1122 | LdRecDescCached<recName>, D(RecDesc), NA, NF
1124   Loads the record whose name is recName via the RDS. Invokes autoload and may raise an error
1125   if the record is not defined.
1127 | LdRecDescCachedSafe<recName>, D(RecDesc), NA, B
1129   Loads the record whose name is recName out of the RDS. If the record is not
1130   defined, branch to B.
1132 | DefCls, D(Cls), S(Int), NF
1134   Define the class corresponding to PreClass S0 in the current unit.
1136 | DefConst<T>, DParam(Top), NA, NF
1138   Define a constant value of type T. D is presumed to be globally available and
1139   the DefConst instruction will not actually appear in the IR instruction
1140   stream.
1142 | Conjure<T>, DParam(Top), NA, NF
1144   Define a value of type T. This instruction aborts at runtime; it is meant to
1145   be used in tests or code that is known to be unreachable.
1147 | ConjureUse, ND, S(Cell), NF
1149   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
1150   should not appear in reachable code.
1152 | LdCls, D(Cls), S(Str) C(Cls|Nullptr), NF
1154   Loads the class named S0 in the context of the class S1. Invokes autoload and
1155   may raise an error if the class is not defined. The explicit context
1156   parameter allows the compiler to simplify this instruction to a DefConst in
1157   some cases. If S0 is constant, this instruction may be simplified to a
1158   LdClsCached.
1160 | LdClsCached, D(Cls), CStr, NF
1162   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
1163   if the class is not defined.
1165 | LdClsCachedSafe, D(Cls), CStr, B
1167   Loads the class whose name is S0 out of the RDS. If the class is not defined,
1168   branch to B.
1170 | LdClsInitData, D(PtrToClsInitCell), S(Cls), NF
1172   Loads the pointer to the property initializer array for class S0.
1174 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
1176   Lookup the cached-class RDS handle for a given class name. Dereference that
1177   handle and return the associated Class, or null if not present.
1179 | LdCns, DCns, CStr, B
1181   Load the constant named S0, branching to B if isn't present.
1183 | LookupCnsE<T,constName>,  DCns, CStr, PRc
1185   Load a constant via the RDS. Raises a fatal error if it cannot define the
1186   constant.  This should only be executed if LdCns on the same constant has
1187   failed.
1189 | LdClsCns<className,constantName>, D(PtrToCell), NA, B
1191   Load the address of the constant 'constantName' for the class 'className' in
1192   RDS. If not initialized, branch to B.
1194 | LdSubClsCns<constantName,slot>, D(PtrToCell), S(Cls), NF
1196   Load the address of the constant 'constantName' for the class S0. The
1197   constant is known to be in the given slot. If the returned TypedValue is not
1198   UncountedInit, its value should not be used, and a fallback method should be
1199   called.
1201 | LdSubClsCnsClsName<constantName,slot>, D(StaticStr|Nullptr), S(Cls), NF
1203   Loads the name of the class pointed by the constant 'constantName' for the
1204   class S0. The constant is known to be in the given slot. Returns nullptr if
1205   constant is abstract, not type constant or does not point to a class.
1207 | CheckSubClsCns<constantName,slot>, ND, S(Cls), B
1209   Check that the constant 'constantName' lives in the given slot for the class
1210   S0, and branch if not. S0 must have at least slot+1 constants.
1212 | LdClsCnsVecLen, D(Int), S(Cls), NF
1214   Load the size of S0's constant table.
1216 | LdTypeCns, DStaticDArr, S(InitCell), B
1218   Loads the resolved type constant S0 or branches to B if S0 is not resolved or
1219   not a type constant.
1221 | LdClsTypeCns, DStaticDArr, S(Cls) S(Str), NF
1223   Loads type constant S1 of class S0 or raises an error if no such constant
1224   could be found, or if S0::S1 is not a type constant.
1226 | LdClsTypeCnsClsName, D(StaticStr), S(Cls) S(Str), NF
1228   Loads the name of the class pointed by the type constant S1 of class S0 or
1229   raises an error if no such constant could be found, or if S0::S1 is not a
1230   type constant.
1232 | ProfileSubClsCns<constantName,handle>, D(PtrToCell), S(Cls), NF
1234   Load the address of the constant 'constantName' for the class S0, profiling
1235   the observed slots. If the returned TypedValue is not UncountedInit, its
1236   value should not be used, and a fallback method should be called.
1238 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1240   Loads the target cache entry for a forwarding call to clsName::methodName.
1241   If the method does not exist, or the cache hasn't been filled yet, branch to
1242   B.
1244 | LookupClsMethodFCache<clsName,methodName>,
1245 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1246 |    NF
1248   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1249   the Class named by clsName and S1 should be the current vm frame pointer. May
1250   return Nullptr if lookup fails using a subset of the required lookup paths,
1251   indicating that a more complete lookup path should be taken. May throw if the
1252   method does not exist.
1254 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1256   Loads the target cache entry for the method clsName::methodName. If the
1257   method does not exist or the cache hasn't been filled yet, branch to B.
1259 | LdClsMethodCacheCls<clsName,methodName>, D(Cls), NA, NF
1261   Loads the target cache class context entry for a call to clsName::methodName
1262   from the current context. This instruction must only be used when the value
1263   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1264   LookupClsMethodCache returned a non-null value).
1266 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr), S(FramePtr), NF
1268   Lookup a function in the class method targetcache. The class name and method
1269   name are clsName and methodName, respectively. S0 is the current vm frame
1270   pointer. Returns Nullptr if the method cannot be found using a subset of the
1271   required lookup paths, indicating that a more complete lookup path should be
1272   taken. May throw if the method does not exist.
1274 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1276   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1278 | LdFuncVecLen, D(Int), S(Cls), NF
1280   Load the funcVecLen field from S0.
1282 | LdClsMethod, D(Func), S(Cls) C(Int), NF
1284   Load the Func* in slot S1 of the class method table for class S0. (Note that
1285   this vector is located before the class in memory, so the non-negative slots
1286   will map to negative offset loads.)
1288 | LookupClsMethod, D(Func|Nullptr), S(Cls) S(Str) S(Obj|Nullptr) S(Cls|Nullptr),
1289 |                  NF
1291   Lookup a pointer to a class method for a given class S0 and method name S1,
1292   assuming caller's $this is S2 and caller is defined in a class S3. Throws or
1293   fatals if the method does not exist, is not accessible, or is not a static
1294   method. Returns nullptr if it is an instance method defined in S2's class
1295   hierarchy, indicating that this legacy call should be handled by interpreter.
1297 | LdPropAddr<T,index>, DParam(LvalToPropCell), S(Obj), NF
1299   Load the address of the object property at physical index `index`. T must be a
1300   subtype of PtrToPropInitCell.
1302 | LdInitPropAddr<T,index>, DParam(LvalToPropCell), S(Obj), B
1304   Load the address of the object property at physical index `index`. Branch if
1305   the value at that address is Uninit. T must be a subtype of PtrToPropInitCell.
1307 | LdGblAddr, D(LvalToGblCell), S(Str), B
1309   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1310   global is not defined.
1312 | LdGblAddrDef, D(LvalToGblCell), S(Str), NF
1314   Loads a pointer to a global. S0 is the global's name. Defines the global if
1315   it is not already defined.
1317 | LdClsPropAddrOrNull, D(PtrToSPropCell|Nullptr),
1318 |                      S(Cls) S(Str) C(Cls|Nullptr) C(Bool) C(Bool),
1319 |                      NF
1321   Loads a pointer to a static class property. S0 points to the class, S1 is the
1322   property name, and S2 is the class representing the context of the code
1323   accessing the property. If class S0 does not have a visible and accessible
1324   static property named S1, then nullptr is returned. An exception
1325   will be thrown if the property is marked LateInit and its value is
1326   Uninit, unless S3 is true. An exception is also thrown if S4 is true,
1327   and the property is constant.
1329 | LdClsPropAddrOrRaise, D(PtrToSPropCell),
1330 |                       S(Cls) S(Str) C(Cls|Nullptr) C(Bool) C(Bool),
1331 |                       NF
1333   Loads a pointer to a static class property. S0 points to the class, S1 is the
1334   property name, and S2 is the class representing the context of the code
1335   accessing the property. If class S0 does not have a visible and accessible
1336   static property named S1, then nullptr is returned. An exception
1337   will be thrown if the property is marked LateInit and its value is
1338   Uninit, unless S3 is true. An exception is also thrown if S4 is true,
1339   and the property is constant.
1341 | LookupSPropSlot, D(Int), S(Cls) S(Str), NF
1343   Lookup the slot index of the static property with the name S1 on the class
1344   S0, returning -1 if not found.
1346 | LdObjMethodD, D(Func), S(Cls) S(Str), NF
1348   Loads a func pointer pointing to the instance method that would be called
1349   if a method named S1 is invoked on an instance of S0. Raises a fatal if the
1350   class does not have an accessible method with the given name.
1352 | LdObjMethodS<methodName>, D(Func), S(Cls) S(Smashable), NF
1354   Loads a func pointer pointing to the instance method that would be called
1355   if a `methodName` is invoked on an instance of S0. Caches the mapping in
1356   the TC cache (using S1) and target cache. Raises a fatal if the class does
1357   not have an accessible method with the given name.
1359 | LdObjInvoke, D(Func), S(Cls), B
1361   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1362   to block B if it is not present.
1364 | LdObjClass, DLdObjCls, S(Obj), NF
1366   Load the class out of the object in S0 and put it in D.
1368 | LdClsName, D(StaticStr), S(Cls), NF
1370   Load the name of the Class* in S0.
1372 | LdFunc, D(Func|Nullptr), S(Str), NF
1374   Loads the Func whose name is S0, invoking autoloader if it is not defined yet.
1375   Fatals if the named function is not defined, and the autoloader fails to
1376   define it. Returns nullptr if S0 contained '::', indicating that this legacy
1377   call should be handled by interpreter.
1379 | LdFuncCached<funcName>, D(Func), NA, NF
1381   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1382   not defined yet. Fatal if function autoloader fails to define it.
1384 | LookupFuncCached<funcName>, D(Func), NA, NF
1386   Loads the Func whose name is given from %1, invoking autoload if it is not
1387   defined yet. Fatal if the function autoload fails to define it. This
1388   instruction does not assume the loaded function will be called immediately,
1389   so it will raise a resolution failure error instead of a call failure error.
1391 | LdARNumParams, D(Int), S(FramePtr), NF
1393   Loads the number of params from an ActRec. S0 is the address of the ActRec
1395 | LdFuncNumParams, D(Int), S(Func), NF
1397   Returns the value of func->numParams().
1399 | LdFuncName, D(StaticStr), S(Func), NF
1401   Loads the full name of S0.
1403 | LdMethCallerName<isCls>, D(StaticStr), S(Func), NF
1405   Loads the meth_caller cls or func name.
1407 | LdFuncCls, D(Cls|Nullptr), S(Func), NF
1409   Loads the Class* of S0.
1411 | LdStrLen, D(Int), S(Str), NF
1413   Load the length of the string in S0.
1415 | FuncHasAttr<attr>, D(Bool), S(Func), NF
1417   Tests for Func::m_attrs & attr.
1419 | IsClsDynConstructible, D(Bool), S(Cls), NF
1421   Tests for Class::m_attrCopy & AttrDynamicallyConstructible.
1423 | LdFuncRxLevel, D(Int), S(Func), NF
1425   Returns the value of func->rxLevel().
1427 | LdClsFromClsMeth, D(Cls), S(ClsMeth), NF
1429   Load the Class* of the ClsMethDataRef in S0.
1431 | LdFuncFromClsMeth, D(Func), S(ClsMeth), NF
1433   Load the Func* of the ClsMethDataRef in S0.
1435 7. Allocation
1437 | AllocObj, DAllocObj, S(Cls), PRc
1439   Allocates a new object of class S1.
1441 | AllocObjReified, DAllocObj, S(Cls) SVArr, PRc
1443   Allocates a new object of class S1 and sets S2 as the reified generics of this
1444   class. If this class is not reified, this instruction raises an error.
1446 | InitProps<class>, ND, NA, NF
1448   Calls the property initializer function (86pinit) for class.  May throw.
1450 | InitSProps<class>, ND, NA, NF
1452   Calls the static property initializer functions (86sinit and/or 86linit)
1453   for class. May throw.
1455 | CheckRDSInitialized<RDSHandle>, ND, NA, B
1457   Check if the RDS entry at the specified handle is initialized, and branches
1458   if not.
1460 | MarkRDSInitialized<RDSHandle>, ND, NA, NF
1462   Mark the given RDS entry as being initialized.
1464 | PropTypeRedefineCheck, ND, C(Cls) C(Int), NF
1466   Check that the specified property at the slot S1 on S0, which redeclares a
1467   property in the parent, has a declared type equivalent to the parent
1468   declaration.
1470 | DebugBacktrace, DVArr, S(Int), PRc
1472   Obtain stack trace by calling the debug_backtrace() method.
1474 | DebugBacktraceFast, D(Res), NA, PRc
1476   Obtain compact stack trace resource that can be expanded lazily.
1478 | InitThrowableFileAndLine, ND, S(Obj), NF
1480   Initialize Throwable's file name and line number assuming the stack trace
1481   was already initialized and the current vmfp() is a built-in.
1483 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1485   Allocates an instance of class.
1487 | InitObjProps<class>, ND, S(Obj), NF
1489   Initializes properties of object S0.
1491 | ConstructInstance<class>, DAllocObj, NA, PRc
1493   Call the custom instance constructor of an extension class.
1495 | ConstructClosure<class>, DAllocObj, S(Cls|Obj|Nullptr), CRc|PRc
1497   Call the custom instance constructor of a Closure.
1499   Store the context represented by S0 into the newly constructed closure object.
1500   S0 may be a Nullptr when there is no context (i.e. the closure is being used
1501   in a non-method).
1503 | LockObj, ND, S(Obj), NF
1505   Clear the IsBeingConstructed flag on the object.
1507 | NewArray, D(Arr), C(Int), PRc
1509   Allocate a new array with the expected capacity S0.
1511 | NewMixedArray, DArrMixed, C(Int), PRc
1513   Allocate a new array in mixed mode with the expected capacity S0.
1515 | NewDArray, DDArr, C(Int), PRc
1517   Allocate a new dict-like array with the expected capacity S0.
1519 | NewDictArray, D(Dict), C(Int), PRc
1521   Allocate a new dict with the expected capacity S0.
1523 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc
1525   Allocate a new keyset containing N elements off the stack given by S0, at
1526   `offset'. This instruction moves the elements off the stack without
1527   manipulating their reference counts.
1529 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1531   Allocate a new array in the same mode as S0 and with expected capacity S1,
1532   unless S1 == 0, in which case the capacity is set to S0's size.
1534 | AllocPackedArray<size>, DArrPacked, NA, PRc
1536   Allocate a new uninitialized packed array with space for size elements in it.
1537   The array will be initialized with values using either InitPackedLayoutArray
1538   or InitPackedLayoutArrayLoop.
1540 | AllocVArray<size>, DVArr, NA, PRc
1542   Allocate a new uninitialized vec-like array with space for size elements in
1543   it.  The array will be initialized with values using either
1544   InitPackedLayoutArray or InitPackedLayoutArrayLoop.
1546 | AllocVecArray<size>, D(Vec), NA, PRc
1548   Allocate a new uninitialized vector array with space for size elements in it.
1549   The array will be initialized with values using either InitPackedLayoutArray
1550   or InitPackedLayoutArrayLoop.
1552 | InitPackedLayoutArray<index>, ND, S(AK(Packed),Vec) S(Cell), CRc
1554   Store the S1 into the slot at index in array S0. This instruction assumes
1555   that it doesn't have to incref the value being stored. Used to initialize an
1556   array allocated with AllocPackedArray or AllocVecArray.
1558 | InitPackedLayoutArrayLoop<offset,size>, ND, S(AK(Packed),Vec) S(StkPtr), CRc
1560   Move `size' elements from the stack given by S1, at `offset', into the array
1561   S0.  Assumes that the first element on the stack is the last element in the
1562   array.  Used to initialize an array allocated with AllocPackedArray or
1563   AllocVecArray that was too big to use a series of InitPackedLayoutArray
1564   instructions.
1566 | AllocStructArray<keys...>,  DArrMixed,      NA, PRc
1568 | AllocStructDArray<keys...>, DDArr,          NA, PRc
1570 | AllocStructDict<keys...>,   D(Dict), NA, PRc
1572   Allocate a new key/value dict or mixed-layout array, given N string literal
1573   immediates for keys. This op initializes the header and hash table of the
1574   new array-like, but does not its elements; use InitMixedLayoutArray for that.
1576 | InitMixedLayoutArray<index,key>, ND, S(AK(Mixed),Dict) S(Cell), NF
1578   Initialize the element at position `index` in array S0 to have the string
1579   literal `key` as its key and S1 as its value. This instruction assumes that
1580   S1 has already been inc-reffed. Used to initialize an array allocated by
1581   AllocStructArray / AllocStructDArray / AllocStructDict.
1583 | NewRecord<offset,keys...>, D(Record), S(RecDesc) S(StkPtr), PRc|CRc
1585   Allocate a new record, given the type S0 and N immediate keys
1586   and taking N elements off the stack given by S1, at `offset'.
1587   This instruction assumes it can take the values from the stack
1588   without increfing them.
1590 | NewRecordArray<offset,keys...>, DArrRecord, S(RecDesc) S(StkPtr), PRc|CRc
1592   Allocate a new record array, given the type S0 and N immediate keys
1593   and taking N elements off the stack given by S1, at `offset'.
1594   This instruction assumes it can take the values from the stack
1595   without increfing them.
1597 | NewStructArray<offset,keys...>,  DArrMixed,      S(StkPtr), PRc|CRc
1599 | NewStructDArray<offset,keys...>, DDArr,          S(StkPtr), PRc|CRc
1601 | NewStructDict<offset,keys...>,   D(Dict), S(StkPtr), PRc|CRc
1603   Allocate a new key/value dict or mixed-layout array, given N string literal
1604   immediates for keys and N stack elements at `offset` on stack S0 for values.
1605   This op assumes it can take values from the stack without inc-reffing them.
1607 | NewCol<type>, DCol, NA, PRc
1609   Create an empty new collection of `type'. `type' cannot be Pair.
1611 | NewPair<offset>, DCol, S(Cell) S(Cell), PRc|CRc
1613   Allocate a new Pair and fill it with the given cells. Ownership of the cells
1614   is transferred from $1 and $2 to the pair without manipulating the refcounts.
1616 | NewColFromArray<type>, DCol, S(Vec,Dict), PRc|CRc
1618   Create a collection of `type` from a Vec or Dict kind. `type` cannot be
1619   Pair. S0 must be vec kind when `type` is Vector or ImmVector, and must be
1620   dict kind otherwise. Ownership of S0 is transferred from $1 to the
1621   collection, without manipulating the refcount.
1623 | Clone, DofS(0), S(Obj), PRc
1625   Allocate an object by cloning S0.
1627 | NewClsMeth, D(ClsMeth), S(Cls) S(Func), NF
1629   Allocate a new ClsMethDataRef.
1631 | FuncCred, DAllocObj, S(Func), PRc
1633   Allocate a new FunctionCredential
1635 8. Call & Return
1637 | BeginInlining<offset>, ND, S(StkPtr), NF
1639   Marks the start of an inlined function whose stack resides offset cells below
1640   the SP. It has no effect other than to hint to optimization passes that at the
1641   start of the inlined function its stack is dead.
1643 | DefInlineFP<func,callBCOff,retSPOff>,
1644 |   D(FramePtr),
1645 |   S(StkPtr) S(FramePtr) S(Cls|Obj|Nullptr),
1646 |   NF
1648   Defines a frame pointer for an inlined function.
1650   `func' is the function being inlined. `callBCOff' points to the caller's
1651   FCall instruction, `retSPOff' represents what the stack offset should be
1652   after the FCall instruction in the caller.
1654   This instruction is primarily used to represent a frame in the IR in a way
1655   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1656   it is pushed into an unlikely path) it performs callee-side responsibilities
1657   for setting up an activation record (i.e. setting the return ip, m_func and
1658   m_callOff, storing the frame pointer into D).
1660   The caller frame pointer is passed as S1. This is used to keep track of the
1661   call chain of inlined functions for simplification and dead code elimination.
1663   S2 is the context (nullptr, $this or static::class).
1665 | InlineReturn<callerFPOff>, ND, S(FramePtr), NF
1667   Unlinks a frame constructed by DefInlineFP.  `callerFPOff' is the offset of
1668   the caller's frame pointer relative to S0. Every inline region must contain
1669   exactly one InlineReturn or InlineReturnNoFrame. Optimization passes which
1670   attempt to elide DefInlineFP detect "main" blocks within an inlined region as
1671   those which are dominated by BeginInlining and post-dominated by InlineReturn.
1673 | InlineSuspend<callerFPOff>, ND, S(FramePtr), NF
1675   Identical to an InlineReturn, but for use when the frame is being suspended in
1676   a side exit and will be torn down via an InlineReturn in the main trace. The
1677   behavior of InlineSuspend is identical to inline return, but it allows us to
1678   preserve the invariant that an inline region has a single InlineReturn for
1679   every DefInlineFP (while still allowing InlineSuspend in the case of a side
1680   exit).
1682 | InlineReturnNoFrame<InlineFrameStart>, ND, S(StkPtr), NF
1684   Mark the end of an inlined function for which no DefInlineFP was required. The
1685   primary purpose of this instruction is to hint the optimization passes that
1686   after return everything below InlineFrameStart is dead. InlineFrameStart is
1687   the SP-relative offset of the start of the callee frame.
1689 | DefFuncEntryFP<func>,
1690 |   D(FramePtr),
1691 |   S(FramePtr) S(StkPtr) S(Int) S(Int) S(Cls|Obj|Nullptr),
1692 |   NF
1694   Writes a callee's frame and defines a frame pointer.
1696   `func': the function being called
1697   S0: frame pointer of the caller
1698   S1: stack pointer pointing to the space reserved for the callee's frame
1699   S2: call flags (see CallFlags)
1700   S3: number of passed arguments
1701   S4: call context
1703 | CallUnpack<spOffset,numParams,callOff,destroyLocals>,
1704 |   DCall,
1705 |   S(StkPtr) S(FramePtr) S(Func) S(Cls|Obj|Nullptr),
1706 |   CRc|PRc
1708   Invoke function S2 corresponding to the current FPI with numParams arguments,
1709   the last of which is an array of the remaining args. Used for FCall with
1710   unpack. S0+spOffset points to the stack resulting after the ActRec for the
1711   function and numParams arguments have been pushed. S3 is the context (nullptr,
1712   $this or static::class). CallUnpack pops the array off the stack, pushes the
1713   elements of the array as arguments, and invokes the function in the ActRec.
1715 | SyncReturnBC<spOffset,callBCOffset>, ND, S(StkPtr) S(FramePtr), NF
1717   Stores callBCOffset into the frame at spOffset from S0 as the call bytecode
1718   address and the frame S1 as the return frame.
1720 | Call<offset,numParams,callOff,destroyLocals>,
1721 |   DCall,
1722 |   S(StkPtr) S(FramePtr) S(Func) S(Cls|Obj|Nullptr),
1723 |   CRc|PRc
1725   Transfer control to a callee S2, based on the pre-live activation record and
1726   set of args on the stack pointed to by S0 at `offset'. S1 is the current
1727   caller frame pointer. S3 is the context (nullptr, $this or static::class).
1729 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), NF
1731   Execute a call to the native builtin specified by the current function. S0
1732   and S1 should be the current vmfp and vmsp, respectively.
1734 | CallBuiltin, DBuiltin, S(FramePtr) S(StkPtr) SVar(MemToCell,Cell,Nullptr), PRc
1736   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1737   and vmsp, respectively.
1739   The source and destination types correspond to C++ parameter and return types
1740   as follows:
1742     C++ type            HHIR type         Position
1743     -----------------   ---------         --------
1744     bool                Bool              source, destination
1745     int64_t             Int               source, destination
1746     double              Dbl               source, destination
1747     const String&       PtrToStr          source
1748     const Array&        PtrToArr          source
1749     const Object&       PtrToObj          source
1750     const Variant&      PtrToCell         source
1751     Variant&            PtrToCell         source (ref param)
1752     String              {Str|InitNull}    destination
1753     Array               {Arr|InitNull}    destination
1754     Object              {Obj|InitNull}    destination
1755     Variant             {Cell-UninitNull} destination
1757 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1759   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1760   frame pointer is stored in rvmfp, then return to the saved return address in
1761   S1.  The return value is S2, which is passed via the rret_*() registers to
1762   the caller.  The `suspendingResumed' flag indicates when this instruction is
1763   suspending a resumable rather than performing a normal function return.
1765 | AsyncFuncRet<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1767   Return from a resumed async function, assuming no surprise. Ensures that
1768   S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored in rvmfp,
1769   packs return value S2 into registers and calls the `asyncFuncRet` unique
1770   stub. The stub stores the result into the wait handle associated with the
1771   frame pointer, marks it as finished, unblocks its parents and if possible,
1772   directly resumes the first parent (fast path), or a pending fast runnable
1773   ResumableWaitHandle (slower path). Otherwise, it will exit VM and return
1774   control to the asio scheduler (slow path). The stack must contain exactly one
1775   cell containing uninitialized garbage, which will be populated by the stub
1776   either to pass the return value to the resumed function, or to return null
1777   to the scheduler.
1779 | AsyncFuncRetSlow<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1781   Return from a resumed async function, assuming unknown surprise flag state
1782   after the previous surprise was handled by executing "return" event hook.
1783   Calls the `asyncFuncRetSlow` stub, which re-checks the surprise flag and
1784   transfers control to the AsyncFuncRet if it was clear, or performs the slow
1785   path of AsyncFuncRet if it was not, without resuming another function, as
1786   we are not able to call a potential "resume await" event hook from the stub.
1788 | AsyncSwitchFast<spOff>, ND, S(StkPtr) S(FramePtr), T
1790   Switch control to another ResumableWaitHandle. Ensures that S0 + `spOff`
1791   (in cells) is stored in rvmsp and that S1 is stored in rvmfp and calls the
1792   `asyncSwitchCtrl` unique stub, which tries to resume a pending fast runnable
1793   ResumableWaitHandle (fast path) if possible, otherwise it will exit VM and
1794   return control to the asio scheduler (slow path). As with AsyncRetFast, the
1795   stack must contain exactly one cell containing uninitialied garbage.
1797 | LdRetVal<T>, DParam(Cell), S(FramePtr), NF
1799   Load the return value from the already-returned-from ActRec pointed to by S0
1800   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1801   NativeImpl return a TypedValue in the C++ ABI registers.
1803 | DbgTrashRetVal, ND, S(FramePtr), NF
1805   For debugging purposes.  Store kTVTrashJITRetVal to the return value slot on
1806   the activation record pointed to by S0.
1808 | ReleaseVVAndSkip, ND, S(FramePtr), B
1810   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1811   nothing. Otherwise it frees the VarEnv and jumps to block B. This instruction
1812   may not occur in an inlined call.
1814 | GenericRetDecRefs, ND, S(FramePtr), NF
1816   Does decrefs of all the current function's locals, where S0 is a pointer to
1817   the relevant activation record. This instruction may not occur in an inlined
1818   call.
1820 | DbgCheckLocalsDecRefd, ND, S(FramePtr), NF
1822   In debug builds, if LocalsDecRefd flag is set on S0, causes runtime failure by
1823   emitting a trap instruction. Otherwise, this instruction does nothing.
1825 9. Stores
1827 | StClsInitElem<idx>, ND, S(PtrToClsInitCell) S(Cell), NF
1829   Store S1 into the slot at index `idx` in the class init vector at S0.
1831 | StMem, ND, S(MemToCell) S(Cell), NF
1833   Store S1 into the location pointed to by S0.
1835 | StLoc<localId>, ND, S(FramePtr) S(Cell), NF
1837   Store S1 to local number localId on the frame pointed to by S0.
1839 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Cell), NF
1841   Behaves just like StLoc, except the hard requirement that it is only emitted
1842   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1843   intraprocedural analysis to know whether the store is truly dead.
1845 | StLocRange<localIds>, ND, S(FramePtr) S(Cell), NF
1847   Store S1 to the local variables corresponding to localIds, on the frame
1848   pointed to by S0.
1850 | StIterBase<iterId>, ND, S(FramePtr) S(ArrLike,Nullptr), NF
1852   Sets the base of the iterator at `iterId` to the pointer S1. The array must
1853   match the specialized type of the iterator, or be null (for local iterators).
1855 | StIterType<iterId,iterType>, ND, S(FramePtr), NF
1857   Sets the type of the iterator at `iterId` to `iterType`. This type must be a
1858   specialized type. Also sets auxiliary fields (like next helper index).
1860 | StIterPos<iterId>, ND, S(FramePtr) S(Int|PtrToElemCell), NF
1862 | StIterEnd<iterId>, ND, S(FramePtr) S(Int|PtrToElemCell), NF
1864   Store S1 to the given field of the iterator at `iterId`. S1 must be an int if
1865   we're doing index iteration and a pointer if we're doing pointer iteration.
1867 | StStk<offset>, ND, S(StkPtr) S(Cell), NF
1869   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1871 | StOutValue<index>, ND, S(FramePtr) S(Cell), NF
1873   Store S1 in a caller allocated out-value vm stack cell index cells above
1874   S0 on the stack.
1876 | LdOutAddr<index>, D(PtrToOtherCell), S(FramePtr), NF
1878   Load the address of the storage for out parameter `index` provided by the
1879   callee (the address will be a location on the callee stack).
1881 | DbgTrashStk<offset>, ND, S(StkPtr), NF
1883   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
1884   by S0, at a given offset (in cells).
1886 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
1888   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
1889   slots starting at the offset (in cells), and going toward higher memory
1890   addresses.
1892 | DbgTrashMem, ND, S(MemToCell), NF
1894   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
1895   S0.
1897 | RecordReifiedGenericsAndGetTSList, DVArr, SVArr, CRc
1899   Takes a varray of reified generics from the stack and adds them to the reified
1900   generics table and returns the input varray of reified generics, possibly
1901   static
1904 10. Trace exits
1906 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), NF
1908   Sync the given vmfp and vmsp to their in-memory locations.
1910 | ReqBindJmp<bcOff,transFlags>, ND, S(StkPtr) S(FramePtr), T
1912   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
1914 | ReqRetranslate<transFlags>, ND, S(StkPtr) S(FramePtr), T
1916   Emit a jump to a service request that will chain to a retranslation of this
1917   tracelet.
1919   This instruction is used in exit traces for a type prediction that occurs at
1920   the first bytecode offset of a tracelet.
1922 | ReqRetranslateOpt<transId,bcOff>, ND, S(StkPtr) S(FramePtr), T
1924   Emit a service request to retranslate, with a higher optimization gear,
1925   translation transID, which starts at bcOff. This instruction is used in exit
1926   traces that trigger profile-guided optimizations.
1929 11. Refcounting and copies
1931 | Mov, DofS(0), S(Top), P
1933   Defines D as S0. May imply register-to-register moves at code generation
1934   time. Does not imply an incref or any other manipulation of S0.
1936 | IncRef, ND, S(Cell), NF
1938   If S0 is a refcounted type, increment its refcount.
1940 | DecRef<locId>, ND, S(Cell), CRc
1942   Decrease the reference count of S0 by one, and call a destructor for types
1943   that require it if it goes to zero.
1945   The locId is just a hint to the runtime indicating which local variable is
1946   being DecRef'd, if any.
1948 | DecRefNZ<locId>, ND, S(Cell), CRc
1950   Decrease the reference count of S0 by one, do not check if it goes to zero.
1951   This instruction can be used for more efficient code when it is provable that
1952   the reference count cannot go to zero.
1954 | ProfileDecRef<locId>, ND, S(Cell), NF
1956   Update the DecRefProfile for the given input as if it were dec-ref-ed, but do
1957   not actually dec-ref it. We can use this op for e.g. iterator output locals,
1958   because we don't specialize iterators in profiling translations.
1961 12. Misc
1963 | DefFP, D(FramePtr), NA, NF
1965   Creates a temporary D representing the current vm frame pointer.
1967 | DefFrameRelSP<stackOff>, D(StkPtr), S(FramePtr), NF
1969   Creates a temporary D representing the current VM stack pointer as an offset
1970   `stackOff' from the frame pointer S0.
1972   This instruction is used at the beginning of translations of non-resumed
1973   functions to represent the state of the stack on entry.
1975 | DefRegSP<stackOff>, D(StkPtr), NA, NF
1977   Creates a temporary D representing the current VM stack pointer given by
1978   the rvmsp register. The `stackOff' is a logical offset from a stack base,
1979   which is a stack pointer to the empty logical stack within the translation.
1981   This instruction is used at the beginning of translations of prologues and
1982   resumed functions to represent the state of the stack on entry.
1984   In prologues, the stack base represents a stack without any func arguments,
1985   i.e. it is pointing to the empty space reserved for an ActRec.
1987   In resumables, the stack base represents an empty VM stack.
1989 | DefCallFlags, D(Int), NA, NF
1991 | DefCallFunc, D(Func), NA, NF
1993 | DefCallNumArgs, D(Int), NA, NF
1995 | DefCallCtx, DParam(Cls|Obj), NA, NF
1997   Creates a temporary D representing flags, function pointer, number of
1998   arguments, or context passed to the prologue.
2000   May be used only at the beginning of a prologue or a stub used in a prologue
2001   context.
2003 | Count, D(Int), S(Cell), NF
2005   Computes the number of elements in S0. The count of an array is the number of
2006   elements it contains, without recursing into containers in the array.
2007   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
2008   count of 0. The count of objects that implement the Countable interface is
2009   computed by returning the value of their count method. Objects that do not
2010   implement Countable have a count of 1.
2012 | CountArray,      D(Int), S(Arr),    NF
2014 | CountArrayFast,  D(Int), S(Arr),    NF
2016 | CountVec,        D(Int), S(Vec),    NF
2018 | CountDict,       D(Int), S(Dict),   NF
2020 | CountKeyset,     D(Int), S(Keyset), NF
2022 | CountCollection, D(Int), S(Obj),    NF
2024   Computes the number of elements in S0 using the same definition as Count, but
2025   with a restriction on the input type.
2027   CountArray expects any array. CountArrayFast expects an array whose kind is
2028   not kGlobalsKind. CountCollection expects a collection object.
2030 | Nop, ND, NA, NF
2032   Does nothing. It's sometimes useful for the simplifier to insert one of these
2033   in the instruction stream.
2035 | JmpPlaceholder, ND, NA, B
2037   Does nothing if executed. Semantically, this instruction carries a taken edge
2038   to a block of speculatively-generated code during initial IR generation, such
2039   as specialized code for an iterator init or next which we may or may not use.
2040   If it survives irgen, it should be eliminated in the first DCE pass.
2042 13. Runtime helpers
2044 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), NF
2046   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
2047   a class) or implement (if S1 is an interface) S1, this instruction will raise
2048   a recoverable fatal error describing the type mismatch.
2050 | VerifyParamRecDesc, ND, S(RecDesc) S(RecDesc|Nullptr) C(Int) C(Int), NF
2052   Verify parameter type for records. If S0 does not extend S1 (if S1 is a record
2053   type) or does not satisfy the type hint S2 (if S1 is null pointer),
2054   this instruction will raise a recoverable fatal error describing the type
2055   mismatch for parameter S3.
2057 | VerifyParamCallable, ND, S(Cell) C(Int), NF
2059   If S0 is not callable, as defined by the php function is_callable, this
2060   instruction will raise a recoverable fatal error describing the type
2061   mismatch.
2063 | VerifyParamFail, ND, NA, NF
2065   Assumes that parameter specified in extra-data in the current function
2066   has failed a its type check. Depending on the typehint being verified and
2067   a number of runtime options, may coerce the parameter to the correct type i
2068   or raise a recoverable fatal error describing the type mismatch.
2070 | VerifyParamFailHard, ND, NA, T
2072   A terminal version of VerifyParamFail, to be used when the compiler can
2073   statically prove that this failure will result in a fatal error rather than a
2074   type coercion.
2076 | VerifyRetCallable, ND, S(Cell), NF
2078   Verify a return type hint.
2080 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), NF
2082   Verify a return type hint for a class.
2084 | VerifyRetRecDesc, ND, S(RecDesc) S(RecDesc|Nullptr) C(Int) S(Cell), NF
2086   Verify a return type hint for a record.
2088 | VerifyRetFail, ND, S(PtrToCell), NF
2090   Failure to verify a return type hint.
2092 | VerifyRetFailHard, ND, S(PtrToCell), T
2094   Terminal version of VerifyRetFail, to be used when the compiler can prove
2095   that this failure will result in a fatal error.
2097 | VerifyPropCls, ND, S(Cls) S(Int) S(Cls|Nullptr) S(Obj) C(Bool), NF
2099   Verify a property type hint with AnnotType::Object against an object
2100   value. S0 is the class of the object containing the property. S1 is the slot
2101   of the property on the class. S3 is the object which is being set in the
2102   property. If S2 is not nullptr, than the type-hint refers to that Class, and
2103   S3 will be checked to see if its an instance of S2. Otherwise, the type-hint
2104   refers to a type-alias, and the alias will be resolved and checked against
2105   S3. S4 is true if this is a static property, false otherwise.
2107 | VerifyPropRecDesc, ND, S(Cls) S(Int) S(RecDesc|Nullptr) S(Record) C(Bool), NF
2109   Verify a property type hint with AnnotType::Record against a record value. S0
2110   is the class of the object containing the property. S1 is the slot of the
2111   property. S3 is the record being set in the property. If S2 is not nullptr,
2112   it is the type hint and S3 will be checked to see if it's an instance of S2.
2113   Otherwise, the type hint refers to a type-alias and the type-alias will be
2114   resolved and checked against S3. S4 is true if this is a static property,
2115   otherwise false.
2117 | VerifyPropFail, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2119   Failure to verify a property type hint. S0 is the class of the object
2120   containing the property. S1 is the slot of the property on the class. S2 is
2121   the value which was being set in the property. S3 is true if this is a static
2122   property, false otherwise.
2124 | VerifyPropFailHard, ND, S(Cls) S(Int) S(Cell) C(Bool), T
2126   Terminal version of VerifyPropFail, to be used when the compiler can prove
2127   that this failure will result in a fatal error.
2129 | VerifyProp, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2131   Verify that S2 is compatible with the type hint for the property at slot S1
2132   on S0. S3 is true if this is a static property, false otherwise.
2134 | VerifyPropCoerce, D(InitCell), S(Cls) S(Int) S(Cell) C(Bool), PRc|CRc
2136   Verify that S2 is compatible with the type hint for the property at slot S1
2137   on S0. S3 is true if this is a static property, false otherwise. Once support
2138   for coercing class_meth types is removed this ir instruction can also be
2139   removed (T61738946).
2141 | VerifyReifiedLocalType<id>, ND, SDArr, NF
2143   Raises a catchable type hint error if the reified generics of function
2144   parameter id does not match the type structure given on S0.
2146 | VerifyReifiedReturnType, ND, S(Cell) SDArr, NF
2148   Raises a catchable type hint error if the reified generics of S0 does not
2149   match the type structure given on S1.
2151 | RaiseHackArrParamNotice<type,id,isReturn>, ND, S(Arr) S(Func), LA
2153   Raise a HackArrCompatNotice corresponding to a param or return typehint
2154   dvarray mismatch. S0 is the array being passed to the callee S1.
2156 | RaiseHackArrPropNotice<type>, ND, S(Cls) S(Arr) S(Int) C(Bool), LA
2158   Raise a HackArrCompatNotice corresponding to a property typehint dvarray
2159   mismatch. Behaves like RaiseHackArrParamNotice.
2161 | RaiseArraySerializeNotice, ND, C(Int) S(ArrLike), LA
2163   Raise a serialization notice with provenance information from the given vec or
2164   dict, using S0 as the sink kind as defined in the SerializationSite enum
2166 | RaiseClsMethPropConvertNotice<tc,isSProp>, ND, S(Cls) S(Str), NF
2168   Raise a notice that a class_meth was implicitly converted after being stored
2169   into a property with name S1 expecting type tc on class S0. Once support for
2170   coercing class_meth types is removed this ir instruction can also be removed
2171   (T61738946).
2173 | RaiseUninitLoc<localId>, ND, S(Str), NF
2175   Raise a notice for an uninitialized local variable.
2177 | RaiseUndefProp, ND, S(Obj) CStr, NF
2179   Raise a notice for an undefined property named S1 on the class of S0.
2181 | RaiseTooManyArg<func>, ND, S(Arr,Vec), CRc|LA
2183   Raise a too many argument warning because extra arguments stored in S0 were
2184   passed to function func.
2186 | RaiseError, ND, S(Str), T
2188   Raises a fatal error with the text in S0 as its message.
2190 | RaiseWarning, ND, S(Str), NF
2192   Raises a warning with the text in S0 as its message.
2194 | RaiseNotice, ND, S(Str), NF
2196   Raises a notice with the text in S0 as its message.
2198 | ThrowHasThisNeedStatic, ND, S(Func), T
2200   Throws a BadMethodCallException to indicate that func was called on an object
2201   but is a static method.
2203 | ThrowMissingArg<func,argc>, ND, NA, T
2205   Throws a RuntimeExceptionObject to indicate that only argc arguments were
2206   passed to function func.
2208 | ThrowMissingThis, ND, S(Func), T
2210   Throws a BadMethodCallException to indicate that an instance method was called
2211   with null $this.
2213 | ThrowCallReifiedFunctionWithoutGenerics, ND, S(Func), T
2215   Throws a BadMethodCallException to indicate that S0 was called without reified
2216   generics.
2218 | RaiseHackArrCompatNotice, ND, S(Str), NF
2220   Raises a Hack array compat notice with the text in S0 as its message.
2222 | ThrowParamInOutMismatch<paramIndex>, ND, S(Func), T
2224   Throw an exception indicating that the inout-ness of a parameter was
2225   incorrectly annotated at the callsite.
2227 | ThrowParamInOutMismatchRange<firstBit,mask,vals>, ND, S(Func), T
2229   Throw an exception indicating that the inout-ness of at least one parameter
2230   within a given range was incorrectly annotated at the callsite.
2232   See CheckInOuts for meaning of firstBit, mask and vals.
2234 | RaiseForbiddenDynCall, ND, S(Func), NF
2236   Depending on the setting of `ForbidDynamicCallsToFunc`,
2237   `ForbidDynamicCallsToClsMeth` and `ForbidDynamicCallsToInstMeth` runtime
2238   options, either raise a warning or throw an exception indicating that the
2239   func specified in S0 was called dynamically (and should not be).
2240   If `ForbidDynamicCallsWithAttr` is false, warnings and exceptions will not be
2241   raised for functions and methods with `__DynamicallyCallable` attribute.
2243 | RaiseForbiddenDynConstruct, ND, S(Cls), NF
2245   Depending on the setting of the `ForbidDynamicConstructs` runtime option, either
2246   raise a warning or throw an exception indicating that the class specified in
2247   S0 was constructed dynamically (and should not be).
2249 | RaiseRxCallViolation, ND, S(FramePtr) S(Func), NF
2251   Depending on the setting of the `RxEnforceCalls` runtime option, either raise
2252   a warning or throw an exception indicating that the caller specified by S0
2253   was violating reactivity constraints when calling the callee specified by S1.
2255 | RaiseStrToClassNotice, ND, S(Str), NF
2257   Raise a notice if a string is implicitly converted to a class.
2259 | CheckClsReifiedGenericMismatch<cls>, ND, SVArr, NF
2261   Raises a runtime error unless whether each generic in S0 is reified or erased
2262   matches exactly to the expectations of the cls.
2264 | CheckFunReifiedGenericMismatch<func>, ND, SVArr, NF
2266   Raises a runtime error unless whether each generic in S0 is reified or erased
2267   matches exactly to the expectations of the func.
2269 | IsFunReifiedGenericsMatched<func>, D(Bool), S(Int), NF
2271   Load the generics bitmap from call flags given by S0 and check whether the
2272   bitmap proves that the number of given generics and positions of reified vs
2273   erased generics matches the expectations of the callee `func' (which must use
2274   reified generics). If this opcode returned false, further checks implemented
2275   by CheckFunReifiedGenericMismatch are needed.
2277 | InitClsCns<className,constName>, DCns, NA, PRc
2279   Initialize the RDS entry for a constant for a class, invoking autoload if it
2280   is not defined. The initialized value is returned. This instruction may raise
2281   an undefined constant error if autoload cannot define the constant.
2283 | PrintStr,  ND, S(Str),  CRc
2285 | PrintInt,  ND, S(Int),  CRc
2287 | PrintBool, ND, S(Bool), CRc
2289   Print for various types.
2291 | ConcatIntStr, D(Str), S(Int) S(Str), PRc
2293   Concatenate S0 and S1 after converting S0 to String.
2295 | ConcatStrInt, D(Str), S(Str) S(Int), CRc|PRc
2297   Concatenate S0 and S1 after converting S1 to String.
2299 | ConcatStrStr, D(Str), S(Str) S(Str), CRc|PRc
2301   Concatenate S0 and S1.
2303 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), CRc|PRc
2305   Concatenate S0, S1, and S2.
2307 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), CRc|PRc
2309   Concatenate S0, S1, S2, and S3.
2311 | AddNewElem,       D(Arr),    S(Arr) S(Cell),    CRc|PRc
2313 | AddNewElemKeyset, D(Keyset), S(Keyset) S(Cell), CRc|PRc
2315 | AddNewElemVec,    D(Vec),    S(Vec) S(Cell),    CRc|PRc
2317   Add S1 as a new element to the array/keyset/vec S0.  (Note: S1 must actually
2318   be a subtype of InitCell for array invariants, but we can't assert this yet
2319   in the IR because many eval stack slots are not entirely typed wrt initness
2320   right now.)
2322 | ArrayAdd, D(Arr), S(Arr) S(Arr), CRc|PRc
2324   Has the effects of the php + operator on the two source arrays.
2326 | AKExistsArr, D(Bool), S(Arr) S(Int,Str), NF
2328   Has the effects of array_key_exists(S0, S1).
2330 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
2332   Has the effects of array_key_exists(S0, S1).
2334 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
2336   Has the effects of array_key_exists(S0, S1).
2338 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), NF
2340   Has the effects of array_key_exists(S0, S1) on an object S0. This does
2341   collection accesses.
2343 | GetMemoKey, DMemoKey, S(Cell), PRc
2345   Given a cell, produces a string or an int that can be used as a memoize cache
2346   key. Valid values for the input include all basic types, arrays and
2347   collections, and objects that implement IMemoizeParam. Any other type will
2348   cause GetMemoKey to throw. This op can only be used within functions marked
2349   as memoize wrappers.
2351 | GetMemoKeyScalar, DMemoKey, S(Uncounted,Str), PRc
2353   Identical to GetMemoKey but only accepts scalar types and cannot produce
2354   errors.
2356 | ArrayIdx<sizeHint>, DArrElem, S(Arr) S(Int,Str) S(Cell), NF
2358   Checks if S0 contains the key S1, and returns the result if found. Otherwise
2359   S2 is returned. The optimization data `sizeHint` doesn't affect semantics.
2360   (`sizeHint` describes S0; it's one of {Default, SmallStatic}. Default is a
2361   hash lookup. For SmallStatic, we'll do a linear scan for static string keys.)
2363 | DictIdx<sizeHint>, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
2365   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2366   S2 is returned. The optimization data `sizeHint` doesn't affect semantics.
2367   (`sizeHint` describes S0; it's one of {Default, SmallStatic}. Default is a
2368   hash lookup. For SmallStatic, we'll do a linear scan for static string keys.)
2370 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
2372   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2373   S2 is returned.
2375 | MethodExists, D(Bool), S(Cls) S(Str), NF
2377   Checks if the method named S1 exists on class S0.  S0 must be a normal class
2378   that is not abstract.
2380 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
2382   Creates a service request to bind the given target address. Returns a TCA
2383   pointing either to the service request (before the service request is
2384   satisfied) or to the native code for the given target address (once the
2385   service request is satisfied).
2387 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
2389 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
2391 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc
2393   These instructions are used to determine the target of a switch statement
2394   with target range [S1:S1 + S2), when invoked with the value S0. They call
2395   helper functions to check whether S0 is an numeric integer in the range
2396   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
2397   target of the default target, S2 + 1.
2399 | LdSSwitchDestFast, D(TCA), S(Cell), NF
2401 | LdSSwitchDestSlow, D(TCA), S(Cell), NF
2403   Load string switch destinations (two different compilation strategies).
2405 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
2406 |                                               S(StkPtr) S(FramePtr),
2407 |                                               NF
2409   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
2410   cells) and S1 are, respectively, the VM stack and frame pointers before this
2411   instruction. T is only present if the instruction pushes to the stack, in
2412   which case it is the type of the top stack element after the call. `bcOff' is
2413   the bytecode offset. `numPopped' is the number of stack cells consumed by the
2414   instruction, and `numPushed' is the number of stack cells produced by the
2415   instruction.
2417 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
2418 |                                           S(StkPtr) S(FramePtr),
2419 |                                           T
2421   Similar to InterpOne, but for instructions that may modify vmpc. This is
2422   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2423   in the context of the stub, not the InterpOneCF instruction.
2425 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), NF
2427   Returns a bool indicating whether the class, interface, or trait named by S0
2428   exists. Invokes autoload if S1 is true.
2430 | SetOpTV<op>, ND, S(LvalToCell) S(Cell), NF
2432   Performs S0 <op>= S1.
2434 | SetOpTVVerify<op>, ND, S(LvalToCell) S(Cell) S(Cls) S(Int), NF
2436   Similar to SetOpTV, but does a type-hint check of the result (before
2437   assigning to S0) using the type-hint of the property in class S2 at slot S3.
2439 | GetTime, D(Dbl), NA, NF
2441   Returns a double of the current time in seconds.
2443 | GetTimeNs, D(Int), C(Int), NF
2445   Returns the current time of the given clock id specified as clockid_t in
2446   nanoseconds as integer. This will call kernel's clock_gettime_ns() API. Note
2447   that this cannot be used for CLOCK_THREAD_CPUTIME_ID, as HHVM provides
2448   different semantics for that counter.
2450 14. Generators & Closures
2452 | LdClosureCls, DParam(Cls), S(Obj), NF
2454 | LdClosureThis, DParam(Obj), S(Obj), NF
2456   Load the context from the closure object S0 into D, assuming `func' is
2457   S0's closure Func.
2459 | StClosureArg<index>, ND, S(Obj) S(Cell), CRc
2461   Store one of the closure environment arguments (i.e. from the closure's use
2462   clause) from S1 into the closure object S0.
2464 | CreateGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2466   Create a Generator object and suspend the ActRec provided by S0 into its
2467   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2468   resume address to S2 and resume offset to S3.
2470 | CreateAGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2472   Create an AsyncGenerator object and suspend the ActRec provided by S0 into its
2473   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2474   resume address to S2 and resume offset to S3.
2476 | CreateAFWH, DAllocObj,
2477 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2478 |             CRc|PRc
2480   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2481   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2482   the native resume address to S2, resume offset to S3, and mark it blocked on
2483   non-finished child S4.
2485 | CreateAFWHNoVV, DAllocObj,
2486 |                 S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2487 |                 CRc|PRc
2489   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2490   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2491   the native resume address to S2, resume offset to S3, and mark it blocked on
2492   non-finished child S4.  This version of the instruction guarantees that the
2493   VarEnv is unused.
2495 | CreateAGWH, DAllocObj,
2496 |             S(FramePtr) S(TCA,Nullptr) C(Int) S(Obj),
2497 |             CRc|PRc
2499   Create an AsyncGeneratorWaitHandle object and link it to the AsyncGenerator
2500   associated with the ActRec provided by S0.  Set the native resume address
2501   to S1, resume offset to S2, and mark it blocked on non-finished child S3.
2503 | CreateAAWH<local,count>, DAllocObj, S(FramePtr) S(Int), PRc
2505   Create an AwaitAllWaitHandle and add the count elements from frame contiguous
2506   frame locals beginning at local and extending count locals. S1 denotes the
2507   total number of non-completed waithandles. All locals must be subclasses of
2508   WaitHandle.
2510 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2512   Call c_StaticWaitHandle::CreateSucceeded.
2514 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), NF
2516   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2517   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2518   provided by S0.
2520   Injects S1 into the currently running scheduler instance and performs
2521   cross-scheduler and intra-scheduler cycle detection. Throws if the
2522   dependency cannot be established.
2524 | AFWHPushTailFrame, ND, S(Obj) C(Int), B
2526   If S0 is eligible for the tail frame optimization and has any free tail
2527   frame ID slots, pushes S1 as a new tail frame ID. Otherwise, branches to B.
2528   This IR op assumes that S0 is an Awaitable in the blocked state.
2530   S0 is eligible for the optimization if it is an AsyncFunctionWaitHandle,
2531   if this site "owns" it (i.e. if it has a refcount of exactly 2 - this site
2532   and its child's back pointer), and if it has space in its tail-frames list.
2534 | StArResumeAddr<offset>, ND, S(FramePtr) S(TCA), NF
2536   Store the resume address S1 into the Resumable whose ActRec is given by S0,
2537   marking the offset to resume at as `offset'.
2539 | ContEnter<spOffset,callBCOffset>,
2540 |   DGenIter,
2541 |   S(StkPtr) S(FramePtr) S(FramePtr) S(TCA) S(Cell),
2542 |   CRc
2544   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2545   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2546   embedded in the Generator object, S3 is the address to jump to, and S4 is
2547   the value that will be pushed onto the stack to send it to the output of
2548   the yield statement. The `callBCOffset' will be stored to the m_callOff
2549   field of the ActRec in the generator.
2551 | ContPreNext, ND, S(Obj) C(Bool), B
2553   Performs operations needed for the next() method of Generator object S0.
2554   If the generator is already running or finished, or it was not started yet
2555   and the S1 check-started flag is set, the branch B is taken. Otherwise,
2556   the generator is marked as running.
2558 | ContStartedCheck, ND, S(Obj), B
2560   Checks if the Generator object S0 has started, and if not branches to
2561   block B.
2563 | ContValid, D(Bool), S(Obj), NF
2565   Return true if a generator is not done, false otherwise.
2567 | ContStarted, D(Bool), S(Obj), NF
2569   Return true if a generator has been run at least once, i.e. is not in the
2570   Created state, false otherwise.
2572 | ContArIncKey, ND, S(FramePtr), NF
2574   Special-case key update for generator, ActRec of which is S0, which
2575   increments the key of a generator if that generator's key is an Int.
2576   This will cause undefined behavior if the generator's key is not an Int.
2578 | ContArIncIdx, D(Int), S(FramePtr), NF
2580   Increment the internal index in the Generator in S0, and return the new index
2581   value.
2583 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2585   Updates the internal index of generator with S1 if necessary, i.e. if S1
2586   is larger than the index. S0 is the pointer to the embedded ActRec.
2588 | LdContActRec, D(FramePtr), S(Obj), NF
2590   Loads the Generator object's ActRec, given a pointer to the generator
2591   object in S0.
2593 | LdContResumeAddr, D(TCA|Nullptr), S(Obj), NF
2595   Load the resume addr from the Generator in S0.
2597 | StContArState<state>, ND, S(FramePtr), NF
2599   Change the state of the Generator object which has frame pointer S0.
2601 | LdContArValue, DParam(Cell), S(FramePtr), PRc
2603   Loads 'value' from the Generator object ActRec of which is S0.
2605 | StContArValue, ND, S(FramePtr) S(Cell), CRc
2607   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2608   new value.
2610 | LdContArKey, DParam(Cell), S(FramePtr), PRc
2612   Loads 'key' from the Generator object ActRec of which is S0.
2614 | StContArKey, ND, S(FramePtr) S(Cell), CRc
2616   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2617   new value.
2619 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2621   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2622   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2624 | LdWHState, D(Int), S(Obj), NF
2626   Loads the state of the WaitHandle in S0, which is a value from the wait
2627   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2628   not a WaitHandle.
2630 | LdWHResult, DParam(Cell), S(Obj), NF
2632   Loads the result of the WaitHandle in S0. This instruction has undefined
2633   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2635 | LdWHNotDone, D(Int), S(Obj), NF
2637   Returns 1 if S0 is not finished, and 0 if S0 is finished.
2639 | CountWHNotDone<local,count>, D(Int), S(FramePtr), B
2641   Returns the number of unfinished awaitables contained in the contiguous
2642   locals beginning at local and extending count, skipping all nulls. A branch
2643   is taken if a non-Awaitable non-null value is encountered.
2645 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2647   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2648   AsyncFunctionWaitHandle object in S0.
2651 15. Debugging, instrumentation, and profiling
2653 | IncStat, ND, C(Int), NF
2655   Increment stat counter. S0 is the implementation defined stat counter index.
2657 | IncProfCounter<TransID>, ND, NA, NF
2659   Increment the profiling counter associated with translation TransID.
2661 | IncCallCounter, ND, S(FramePtr), NF
2663   Increment the counter associated associated with the last call, namely from
2664   the function containing the previous translation in the call stack into the
2665   current function.
2667 | DbgAssertRefCount<AssertReason>, ND, S(Cell), NF
2669   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2670   its count is implausible then execute a hardware trap instruction.
2672 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2674   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2675   start of each region, to emit some sanity checking code.
2677 | DbgAssertFunc, ND, S(FramePtr) S(Func), NF
2679   Assert that S1 is the current function in Frame S0. If the assertion fails,
2680   execution is aborted via a hardware exception.
2682 | RBTraceEntry, ND, NA, NF
2684 | RBTraceMsg, ND, NA, NF
2686   Ring buffer tracing.
2688 | ZeroErrorLevel, D(Int), NA, NF
2690 | RestoreErrorLevel, ND, S(Int), NF
2692   Helper instructions for fast implementation of the PHP error silencing
2693   operator (@foo()).
2696 16. Iterators
2698 | IterInit<IterData>,   D(Bool), S(ArrLike,Obj) S(FramePtr), CRc
2700 | IterInitK<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), CRc
2702 | LIterInit<IterData>,  D(Bool), S(ArrLike) S(FramePtr),     NF
2704 | LIterInitK<IterData>, D(Bool), S(ArrLike) S(FramePtr),     NF
2706   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2707   the index of the iterator variable, keyId and valId are indices of local
2708   variables.
2710   Initializes the iterator variable whose index is given by iterId.
2711   This instruction creates the appropriate iterator for the array or object that
2712   S0 references, and rewinds the new iterator to its start. S0 points to the
2713   stack frame containing the iterator and local variables with the indices
2714   iterId, keyId and valId.
2716   If the new iterator is at its end (i.e., has no elements to iterate over),
2717   this instruction decrements the refcount of S0 and returns false; otheriwse,
2718   it stores a reference to S0 in the new iterator and returns true. If the
2719   iterator is not at its end, then this instruction stores the iterator's first
2720   value (and key) into the local variable with index valId (and keyId,
2721   respectively).
2723   The IterInit and IterInitK instructions always copy the array element by
2724   value.
2726   The LIter variations only accept arrays and do not take ownership of their
2727   base. Instead the base is provided on each operation on the iterator. This
2728   avoids having to raise the ref-count of the base (in situations where this is
2729   safe).
2731   This instruction has the ConsumesRC property because it either decrements the
2732   reference count of S0 or stores a reference to S0 into the new iterator.
2734 | IterNext<IterData>,   D(Bool), S(FramePtr), NF
2736 | IterNextK<IterData>,  D(Bool), S(FramePtr), NF
2738 | LIterNext<IterData>,  D(Bool), S(ArrLike) S(FramePtr), NF
2740 | LIterNextK<IterData>, D(Bool), S(ArrLike) S(FramePtr), NF
2742   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2743   the index of the iterator variable, keyId and valId are indices of local
2744   variables.  S0 points to the stack frame containing the iterator and local
2745   variables with the indices iterId, keyId and valId.
2747   Advances the iterator variable whose index is given by iterId.
2749   If the iterator has reached the end, this instruction frees the iterator
2750   variable and returns false; otherwise, it returns true. If the iterator has
2751   not reached its end, then this instruction stores the iterator's next value
2752   (and key) into the local variable with index valId (and keyId, respectively).
2754   The IterInit and IterInitK instructions always copy the array element by
2755   value.
2757 | IterFree<iterId>, ND, S(FramePtr), NF
2759   Free the iterator variable with id `iterId` in the stack frame of S0.
2760   For non-local iterators, this instruction will dec-ref the stored base.
2762 | KillIter<iterId>, ND, S(FramePtr), NF
2764   Mark the iterator at `iterId` as no longer containing a meaningful value.
2765   We can use this operation to elide stores for iterator fields that do not
2766   get loaded again. In debug builds, it will write poison values to the fields.
2768 | GetMixedPtrIter,  DPtrIter, S(AK(Mixed),Dict) S(Int), NF
2770 | GetPackedPtrIter, DPtrIter, S(AK(Packed),Vec) S(Int), NF
2772   Returns a pointer to the elm S1 of a {mixed,packed}-layout array S0. S1 does
2773   not need to be a valid array position; for example, it may equal the size of
2774   the array (so that the "elm" returned is the pointer-iteration end for S0).
2776 | AdvanceMixedPtrIter<offset>,  DPtrIter, S(PtrToElemCell), NF
2778 | AdvancePackedPtrIter<offset>, DPtrIter, S(PtrToElemCell), NF
2780   Increments the pointer S0 to the array element with the given layout `offset`
2781   positions forward. `offset` is allowed to be negative.
2783 | LdPtrIterKey<T>, DParam(Int|Str), S(PtrToElemCell), NF
2785 | LdPtrIterVal<T>, DPtrIterVal, S(PtrToElemCell), NF
2787   Loads the key or val from the array element pointed to by S0. S0 must be a
2788   valid elm; that is, it can't point to the end of the array data. LdPtrIterKey
2789   can only be used for mixed elms, but LdPtrIterVal supports mixed and packed.
2791   T must be a valid type for the array's keys - i.e., a subtype of TInt|TStr.
2792   For LdPtrIterKey, T is used to type the result; if it's specific enough, we
2793   skip doing a check on the type of the elm. For LdPtrIterVal, it's only used
2794   to constrain the memory effects of the op.
2796 | EqPtrIter, D(Bool), S(PtrToElemCell) S(PtrToElemCell), NF
2798   Compares two pointer iterators for equality.
2801 17. Member instruction support
2803 | LdMIStateAddr, D(PtrToMISCell), C(Int), NF
2805   Load an MInstrState address. Returns a pointer to offset S0 within the
2806   current MInstrState.
2808 | LdMBase, D(LvalToCell), NA, NF
2810   Load the current value of the member base register.
2812 | StMBase, ND, S(LvalToCell), NF
2814   Store a new value to the member base register. It is illegal for any
2815   instruction other than StMBase or InterpOne (when interpreting a member
2816   instruction) to modify the member base register.
2818 | FinishMemberOp, ND, NA, NF
2820   Mark the end of a member operation. This has no effect at runtime but exists
2821   to provide information for certain optimizations.
2823 All of the remaining opcodes in this section are simple wrappers around helper
2824 functions (specified in S0) to perform the corresponding vector operation. If
2825 S1 is a ConstCls it represents the context class for the operation.
2827 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2828 opcode, which almost always pushes its first stack input or a StaticStr as its
2829 stack result. The combinations of input types that cause SetM to push anything
2830 other than those two values are vanishingly rare in correct PHP programs, so
2831 these three instructions have been optimized for the common cases. SetNewElem
2832 and SetProp have no destination, allowing the compiler to predict that the
2833 SetM's output will be the same as its input (and optimize accordingly). If that
2834 turns out to not be the case at runtime, the instruction will throw an
2835 InvalidSetMException. The exception will hold a Cell containing the value the
2836 SetM should push on the stack instead of its input value. The runtime is
2837 responsible for catching this exception, finishing execution of the SetM
2838 instruction, pushing the value from the exception on the stack, and proceeding
2839 as appropriate (most likely with a side exit to the next bytecode instruction,
2840 since it has pushed an unexpected type onto the stack).
2842 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2843 characters within strings. When given a string base and a valid offset, SetElem
2844 returns a string representation of the newly inserted character. In all other
2845 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2846 exception when it detects invalid input types, or when trying to set a string
2847 offset that would grow the string beyond the maximum supported size.
2849 The input types that will cause the errors described above are listed here:
2851 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2852            Bool<false>.
2853 SetElem has the same base constraint as SetNewElem. In addition, the key must
2854         not be a subtype of {Arr|Obj}.
2855 SetProp will fail if the base is not a subtype of {Obj|Null}.
2857 Any instructions that take a pointer to an MInstrState struct use the various
2858 fields of that struct for holding intermediate values.
2860 | BaseG, D(LvalToMembCell), S(Str), NF
2862   Get a base from global named S0. If it is not a defining BaseG it can also
2863   return the init_null_variant, so for now it returns a PtrToMembCell.
2865 | PropX, D(LvalToMembCell), S(Obj,LvalToCell) S(Cell) S(PtrToMISCell), NF
2867   Lookup intermediate property in S0, with key S1.
2869 | PropQ, D(LvalToMembCell), S(Obj,LvalToCell) S(StaticStr) S(PtrToMISCell), NF
2871   A nullsafe version of PropX, returns null if the base S0 is null.
2873 | PropDX, D(LvalToMembCell), S(Obj,LvalToCell) S(Cell) S(PtrToMISCell), MProp
2875   Like PropX, but used for intermediate element lookups that may modify the
2876   base.
2878 | CGetProp, D(Cell), S(Obj,LvalToCell) S(Cell), PRc
2880   Get property with key S1 from S0.
2882 | CGetPropQ, D(Cell), S(Obj,LvalToCell) S(StaticStr), PRc
2884   A nullsafe version of CGetProp, returns null if the base S0 is null.
2886 | SetProp, ND, S(Obj,LvalToCell) S(Cell) S(Cell), MProp
2888   Set property with key S1 in S0 to S2.
2890 | UnsetProp, ND, S(Obj,LvalToCell) S(Cell), NF
2892   Unset an object property.
2894 | SetOpProp<op>, D(Cell), S(Obj,LvalToCell) S(Cell) S(Cell), MProp|PRc
2896   Set op propery with key S1 in base S0, using S2 as the right hand side.
2898 | IncDecProp<op>, D(Cell), S(Obj,LvalToCell) S(Cell), MProp|PRc
2900   Increment/decrement property with key S1 in base S0.
2902 | IssetProp, D(Bool), S(Obj,LvalToCell) S(Cell), NF
2904   Returns true iff the property with key S1 in base S0 is set.
2906 | ElemX, D(Cell), S(LvalToCell) S(Cell), NF
2908   Get intermediate element with key S1 from base S0. The base will not be
2909   modified and the result will not be inc-ref-ed.
2911 | ProfileMixedArrayAccess, ND, S(Arr) S(Int,Str), NF
2913   Profile access of the element keyed by S1 in S0, tracking sizes and offsets.
2915 | CheckMixedArrayKeys<T>, ND, S(AK(Mixed),Dict), B
2917   Check that the given mixed array is free of tombstones and that all of its
2918   elements' keys match the type T. If any check fails, branch to block B.
2919   Like CheckMixedArrayOffset, this check is allowed to have false negatives -
2920   it may fail even if the array has keys of the given type.
2922 | CheckMixedArrayOffset<pos>, ND, S(AK(Mixed)) S(Int,Str), B
2924   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2925   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2926   fail, branch to B.  This check is allowed to have false negatives, in the
2927   case of int-like strings.
2929 | CheckArrayCOW, ND, S(ArrLike), B|LA
2931   Check that S0 has a refcount of exactly 1; if not, branch to B.
2933 | ProfileDictAccess, ND, S(Dict) S(Int,Str), NF
2935   Profile access of the element keyed by S1 in S0, tracking sizes and offsets.
2937 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
2939   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2940   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2941   fail, branch to B.  This check is allowed to have false negatives.
2943 | ProfileKeysetAccess, ND, S(Keyset) S(Int,Str), NF
2945   Profile access of the element keyed by S1 in S0, tracking sizes and offsets.
2947 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
2949   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2950   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2951   fail, branch to B.  This check is allowed to have false negatives.
2953 | CheckMissingKeyInArrLike, ND, S(ArrLike) S(StaticStr), B
2955   Uses the StrKeyTable to check if S1 is guaranteed to be missing in S0.
2956   If S1 may be present, branches to block B. If we branch here, the key may or
2957   may not be present.
2959 | ElemArrayD, D(LvalToElemInitCell), S(LvalToArr) S(Int,Str), MElem
2961 | ElemArrayU, D(LvalToMembInitCell), S(LvalToArr) S(Int,Str), MElem
2963   Similar to ElemDX and ElemUX, but specialized for when the base S0 is an
2964   array and the key S1 is an int/str.
2966 | ElemMixedArrayK<pos>, D(LvalToElemInitCell), S(AK(Mixed)) S(Int,Str), NF
2968   Returns an lval to the element of MixedArray S0 at the known position S1.
2970 | ElemVecD, D(LvalToElemInitCell), S(LvalToVec) S(Int), MElem
2972 | ElemVecU, D(LvalToMembInitCell), S(LvalToVec) S(Int), MElem
2974   Similar to ElemX, but the base S0 is a vec and the key S1 is an int. ElemVecD
2975   is for Define member instrs and ElemVecU is for Unset. (Other variations can
2976   be implemented without special IR instructions).
2978 | ElemDictD, D(LvalToElemInitCell), S(LvalToDict) S(Int,Str), MElem
2980 | ElemDictU, D(LvalToMembInitCell), S(LvalToDict) S(Int,Str), MElem
2982   Similar to ElemDX and ElemUX, but specialized for when the base S0 is a
2983   dict and the key S1 is an int/str.
2985 | ElemDictK<pos>, D(LvalToElemInitCell), S(Dict) S(Int,Str), NF
2987   Returns an lval to the element of dict S0 at the known position S1.
2989 | ElemKeysetU, D(LvalToMembInitCell), S(LvalToKeyset) S(Int,Str), MElem
2991   Similar to ElemUX, but specialized for when the base S0 is a keyset and the
2992   key S1 is an int/str. Keysets do not support the define syntax.
2994 | ElemKeysetK<pos>, D(LvalToElemInitCell), S(Keyset) S(Int,Str), NF
2996   Returns an lval to the element of keyset S0 at the known position S1.
2998 | ElemDX, D(LvalToMembCell), S(LvalToCell) S(Cell), MElem
3000   Like ElemX, but used for intermediate element lookups that may modify the
3001   base.
3003 | ElemUX, D(LvalToMembCell), S(LvalToCell) S(Cell), MElem
3005   Like ElemX, but used for intermediate element lookups that may modify the
3006   base as part of an unset operation.
3008 | ArrayGet, DArrElem, S(Arr) S(Int,Str), NF
3010   Get element with key S1 from base S0.
3012 | MixedArrayGetK<pos>, DArrElem, S(AK(Mixed)) S(Int,Str), NF
3014   Like ArrayGet, but the element for S1 is at a known position `pos' in S0.
3016 | DictGet, DDictElem, S(Dict) S(Int,Str), NF
3018   Get element with key S1 from base S0, throwing if the element is not present.
3020 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
3022   Get element with key S1 from base S0, returning null if the element is not
3023   present.
3025 | DictGetK<pos>, DDictElem, S(Dict) S(Int,Str), NF
3027   Like DictGet, but the element for S1 is at a known position `pos' in S0.
3029 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), NF
3031   Get element with key S1 from base S0, throwing if the element is not present.
3033 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
3035   Get element with key S1 from base S0, returning null if the element is not
3036   present.
3038 | KeysetGetK<pos>, DKeysetElem, S(Keyset) S(Int,Str), NF
3040   Like KeysetGet, but the element for S1 is at a known position `pos' in S0.
3042 | StringGet, D(StaticStr), S(Str) S(Int), PRc
3044   Get string representing character at position S1 from base string S0.  Raises
3045   a notice if the position is out of bounds.
3047 | MapGet, D(Cell), S(Obj) S(Int,Str), PRc
3049   Get element with key S1 from base S0.
3051 | CGetElem, D(Cell), S(LvalToCell) S(Cell), PRc
3053   Get element with key S1 from S0.
3055 | MemoGetStaticValue<func,T>, DParam(InitCell), NA, B
3057   Get the memo value associated with the static function "func". If the value
3058   is not present, branch. The returned value is not inc-reffed. This op can
3059   only be used inside a memoize wrapper.
3061 | MemoGetStaticCache<func,keys,T>, DParam(InitCell), S(FramePtr), B
3063   Perform a lookup on the memo cache associated with the static function
3064   "func". The keys for the lookup are read from the locals on the frame pointed
3065   to by S0 (which must be ints or strings). If the lookup fails, branch. The
3066   returned value is not inc-reffed. This op can only be used inside a memoize
3067   wrapper.
3069 | MemoGetLSBValue<func,T>, DParam(InitCell), S(Cls), B
3071   Get the memo value associated with the static function "func" and late static
3072   bound class S0. If the value is not present, branch. The returned value is not
3073   inc-reffed. This op can only be used inside a memoize wrapper.
3075 | MemoGetLSBCache<func,keys,T>, DParam(InitCell), S(FramePtr) S(Cls), B
3077   Perform a lookup on the memo cache associated with the static function
3078   "func" and late static bound class S1. The keys for the lookup are read from
3079   the locals on the frame pointed to by S0 (which must be ints or strings). If
3080   the lookup fails, branch. The returned value is not inc-reffed. This op can
3081   only be used inside a memoize wrapper.
3083 | MemoGetInstanceValue<slot,func,T>, DParam(InitCell), S(Obj), B
3085   Get the memo value at the specified memo slot on S0. If the value is not
3086   present, branch. The returned value is not inc-reffed. This op can only be
3087   used inside a memoize wrapper.
3089 | MemoGetInstanceCache<func,keys,T>, DParam(InitCell), S(FramePtr) S(Obj), B
3091   Perform a lookup on the memo cache at the specified memo slot on S1. The keys
3092   for the lookup are read from the locals on the frame pointed to by S0 (which
3093   must be ints or strings). If the lookup fails, branch. The returned value is
3094   not inc-reffed. This op can only be used inside a memoize wrapper.
3096 | MemoSetStaticValue<func>, ND, S(InitCell), NF
3098   Set S0 as the memo value associated with the static function "func". Store
3099   the value, overwriting any previous value, with appropriate ref-count
3100   manipulations. This op can only be used inside a memoize wrapper.
3102 | MemoSetStaticCache<func,keys>, ND, S(FramePtr) S(InitCell), NF
3104   Store S1 in the memo cache associated with the static function "func". The
3105   keys for the lookup are read from the locals on the frame pointed to be S0
3106   (which must be ints or strings). Store the value, overwriting any previous
3107   value, with appropriate ref-count manipulations. This op can only be used
3108   inside a memoize wrapper.
3110 | MemoSetLSBValue<func>, ND, S(InitCell) S(Cls), NF
3112   Set S0 as the memo value associated with the static function "func" and
3113   late static bound class S1. Store the value, overwriting any previous
3114   value, with appropriate ref-count manipulations. This op can only be used
3115   inside a memoize wrapper.
3117 | MemoSetLSBCache<func,keys>, ND, S(FramePtr) S(Cls) S(InitCell), NF
3119   Store S2 in the memo cache associated with the static function "func" and
3120   late static bound class S1. The keys for the lookup are read from the
3121   locals on the frame pointed to be S0 (which must be ints or strings).
3122   Store the value, overwriting any previous value, with appropriate
3123   ref-count manipulations. This op can only be used inside a memoize wrapper.
3125 | MemoSetInstanceValue<slot,func>, ND, S(Obj) S(InitCell), NF
3127   Set S2 as the memo value at the specified memo slot on S1. Store the value,
3128   overwriting any previous value, with appropriate ref-count
3129   manipulations. This op can only be used inside a memoize wrapper.
3131 | MemoSetInstanceCache<slot,func,keys>, ND, S(FramePtr) S(Obj) S(InitCell), NF
3133   Store S2 in the memo cache at the specified memo slot on S1. Store the value,
3134   overwriting any previous value, with appropriate ref-count
3135   manipulations. This op can only be used inside a memoize wrapper.
3137 | InitObjMemoSlots<class>, ND, S(Obj), NF
3139   Initialize the memoization instance slots for object S0 of the given class.
3141 | ArraySet, DArrSet, S(Arr) S(Int,Str) S(Cell), PRc|CRc
3143   Set element with key S1 in S0 to S2. The dest will be a new Array that should
3144   replace S0, which may be further constrained by the type of S0.
3146 | VecSet, D(Vec), S(Vec) S(Int) S(Cell), PRc|CRc
3148   Set element with key S1 in S0 to S2. The dest will be a new Vec that should
3149   replace S0.
3151 | DictSet, D(Dict), S(Dict) S(Int,Str) S(Cell), PRc|CRc
3153   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
3154   replace S0.
3156 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), CRc
3158   Set element with key S1 in S0 to S2.
3160 | VectorSet, ND, S(Obj) S(Int,Str) S(Cell), CRc
3162   Set element with key S1 in S0 to S2.
3164 | SetElem, DSetElem, S(LvalToCell) S(Cell) S(Cell), MElem
3166   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
3167   case, where the logical result of the hhbc SetM is its right hand side. In
3168   the case of string bases, the SetM returns a new string containing the newly
3169   inserted character. So the return value of this instruction is Nullptr unless
3170   SetM needed to return a static string.
3172   Furthermore, in the case of "invalid offsets", SetElem may throw an
3173   InvalidSetMException (see discussion above).
3175 | SetRange, ND, S(LvalToCell) S(Int) S(Cell) S(Int) S(Int), MElem
3177 | SetRangeRev, ND, S(LvalToCell) S(Int) S(Cell) S(Int) S(Int), MElem
3179   Perform a range set or reverse range set operation, with the same arguments
3180   and semantics as the RangeSet bytecode instruction.
3182 | UnsetElem, ND, S(LvalToCell) S(Cell), MElem
3184   Unsets the element at key S1 in the base S0.
3186 | SetOpElem<op>, D(Cell), S(LvalToCell) S(Cell) S(Cell),  MElem|PRc
3188   Set op elem with key S1 in base S0, using S2 as the right hand side.
3190 | IncDecElem, D(Cell), S(LvalToCell) S(Cell), MElem|PRc
3192   Increment/decrement element with key S1 in base S0.
3194 | SetNewElem, ND, S(LvalToCell) S(Cell), MElem
3196   Append the value in S1 to S0.
3198 | SetNewElemArray,  ND, S(LvalToArr) S(Cell),       MElem
3200 | SetNewElemVec,    ND, S(LvalToVec) S(Cell),       MElem
3202 | SetNewElemKeyset, ND, S(LvalToKeyset) S(Int,Str), MElem
3204   Specializations of SetNewElem for pointers to arrays, vecs, and keysets.
3206 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), NF
3208   Returns true iff the element at key S1 in the base S0 is set.
3210 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
3212   Returns true iff the element at key S1 in the base S0 is set.
3214 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
3216   Returns true iff the element at key S1 in the base S0 is set.
3218 | StringIsset, D(Bool), S(Str) S(Int), NF
3220   Returns true iff the string S0 has a character at position S1.
3222 | VectorIsset, D(Bool), S(Obj) S(Int), NF
3224   Returns true iff the element at key S1 in the base S0 is set.
3226 | PairIsset, D(Bool), S(Obj) S(Int), NF
3228   Returns true iff the element at key S1 in the base S0 is set.
3230 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
3232   Returns true iff the element at key S1 in the base S0 is set.
3234 | IssetElem, D(Bool), S(LvalToCell) S(Cell), NF
3236   Returns true iff the element at key S1 in S0 is set.
3238 | CheckRange, D(Bool), S(Int) S(Int), NF
3240   Returns true iff S0 is in the range [0, S1).
3242 | ThrowArrayIndexException<isInOut>, ND, S(Int), T
3244   Throws an out of bounds exception if S0 is an undefined index for an array.
3245   The isInOut option indicates that the access was for an inout parameter.
3247 | ThrowArrayKeyException<isInOut>, ND, S(Str), T
3249   Throws an out of bounds exception if S0 is an undefined key for an array.
3250   The isInOut option indicates that the access was for an inout parameter.
3252 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Cell), T|LA
3254   Throws an OutOfBoundsException corresponding to an access of S0 with the key
3255   S1.
3257 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Cell), T|LA
3259   Throws an InvalidArgumentException corresponding to an access of S0 with the
3260   key S1, which has a type invalid for that array.
3262 | ThrowInvalidOperation, ND, S(Str), T
3264   Throws an InvalidOperationException with a message indicating S0.
3266 | ThrowDivisionByZeroException, ND, NA, T
3268   Throws a DivisionByZeroException.
3270 | ThrowLateInitPropError, ND, S(Cls) S(Str) S(Bool), T
3272   Throws an InvalidOperationException indicating an access of a unset LateInit
3273   property. S0 is the class the property was declared on. S1 is the property
3274   name. S2 is true if its a static property, false otherwise.
3276 | ThrowParameterWrongType<expectedType, func, argNum>, ND, S(Cell), T
3278   Throws a RuntimeException if calling a function with an argument that has the
3279   wrong type
3281 | ProfileArrayKind, ND, S(Arr), NF
3283   Profile the array kind of S0.
3285 | ProfileType, ND, S(Cell), NF
3287   Profile the type of S0.
3289 | ProfileCall<rdsHandle>, ND, S(Func), NF
3291   Profile the call to a function S0.
3293 | ProfileMethod<rdsHandle>, ND, S(Cls) S(Func), NF
3295   Profile the method S1 called with class context S0.
3297 | ProfileProp, ND, C(StaticStr) C(StaticStr), NF
3299   Profile the access to property S(1) with base class S(0).
3301 | CheckPackedArrayDataBounds, ND, S(AK(Packed),Vec) S(Int), B
3303   Checks that the index in S1 is within the bounds of the packed array or
3304   vector array in S0. Branches to B if the index is out of bounds.
3306 | LdPackedArrayDataElemAddr<T>, DParam(LvalToElemCell), S(AK(Packed),Vec) S(Int), NF
3308   Loads the address of the element at index S1 of the packed array or vec array
3309   in S0. This instruction assumes the array actually contains an element at
3310   that offset (IE, the array has the proper length).
3312 | ReservePackedArrayDataNewElem, D(Int), S(AK(Packed),Vec), B
3314   If there is room in the packed or vec array (which is assumed to be mutable),
3315   increments the array size and returns the index of the new last element
3316   (which you must initialize); else jumps to the taken branch.
3318 | LdPackedElem, DArrElem, S(AK(Packed)) S(Int), NF
3320   Loads the element of the packed array in S0 at offset S1. This instruction
3321   assumes that the vec actually contains an element at that offset (IE, the
3322   array has the proper length).
3324 | LdVecElem, DVecElem, S(Vec) S(Int), NF
3326   Loads the element of the vec array in S0 at offset S1. This instruction
3327   assumes that the vec actually contains an element at that offset (IE, the vec
3328   has the proper length).
3330 | LdVectorSize, D(Int), S(Obj), NF
3332   Returns the size of the given Vector collection in S0.
3334 | ColIsEmpty, D(Bool), S(Obj), NF
3336 | ColIsNEmpty, D(Bool), S(Obj), NF
3338   Returns whether a collection instance is empty or not.  S0 must be known to
3339   be an instance of a collection class at compile time.
3342 | VecFirst, DVecFirstElem, S(Vec,AK(Packed)), NF
3344   Returns the first value from the packed or vec array in S0.
3345   If the array is empty, it will return NULL.
3347 | VecLast, DVecLastElem, S(Vec,AK(Packed)), NF
3349   Returns the last value from the packed or vec array in S0.
3350   If the array is empty, it will return NULL.
3352 | DictFirst, DDictFirstElem, S(Dict,AK(Mixed)), NF
3354   Returns the first value from the mixed or dict array in S0.
3355   If the array is empty, it will return NULL.
3357 | DictLast, DDictLastElem, S(Dict,AK(Mixed)), NF
3359   Returns the last value from the mixed or dict array in S0.
3360   If the array is empty, it will return NULL.
3362 | DictFirstKey, DDictFirstKey, S(Dict,AK(Mixed)), NF
3364   Returns the first key from the mixed or dict array in S0.
3365   If the array is empty, it will return NULL.
3367 | DictLastKey, DDictLastKey, S(Dict,AK(Mixed)), NF
3369   Returns the last key from the mixed or dict array in S0.
3370   If the array is empty, it will return NULL.
3372 | KeysetFirst, DKeysetFirstElem, S(Keyset), NF
3374   Returns the first value(key) from the keyset in S0.
3375   If the array is empty, it will return NULL.
3377 | KeysetLast, DKeysetLastElem, S(Keyset), NF
3379   Returns the first value(key) from the keyset in S0.
3380   If the array is empty, it will return NULL.
3382 | SetLegacyVec, D(Vec), S(Vec), CRc|PRc
3384 | SetLegacyDict, D(Dict), S(Dict), CRc|PRc
3386   Enable the legacy bit on the vec/dict in S0, copying it if necessary and
3387   returning the tagged array.
3390 18. Exception/unwinding support
3392 | BeginCatch, ND, NA, NF
3394   Marks the beginning of a catch region. Exact behavior is implementation and
3395   architecture specific.
3397 | EndCatch<spOffset,mode,stublogue>, ND, S(FramePtr) S(StkPtr), T
3399   Marks the end of a catch region and returns control to the unwinder.  The
3400   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
3401   the vm stack pointer, however the stack pointer is not actually adjusted
3402   before this instruction returns control to the unwinder.  The unwinder
3403   instead relies on fixup map information to find the appropriate stack
3404   pointers.  Instead it's part of this instruction to facilitate assertions and
3405   memory effect analysis.
3407   If the `stublogue' flag is set, the native stack pointer is updated to reflect
3408   the state prior to entering the stublogue context.
3410 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
3412   Branches to B if the currently executing catch region should return control
3413   to the unwinder rather than side exiting.  Used to control behavior in catch
3414   traces for the InvalidSetMException and TVCoercionException situations.
3416 | LdUnwinderValue<T>, DParam(Cell), NA, PRc
3418   Loads the value contained by the current unwinder exception.
3420 | EnterTCUnwind<teardown>, ND, S(Obj), CRc|T
3422   Enters tc_unwind_resume by doing a side enter, i.e. skipping itanium ABI.
3423   Stores the ObjectData* in S0 to UnwindRDS' exn field as well as true to
3424   sideEnter field.
3425   If teardown is set, it notifies tc_unwind_resume to also teardown the locals.
3427 19. Function prologues
3429 | EnterPrologue, ND, NA, NF
3431   Enter prologue context, which operates in the same mode as unique stubs.
3432   Makes sure the native stack is properly aligned.
3434 | CheckStackOverflow, ND, S(StkPtr), NF
3436   Check if the stack depth has exceeded its limit.  If it has, jump to the
3437   stack overflow helper stub, which will throw.
3439 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), NF
3441   Test the implementation-specific surprise flags.  If they're nonzero, call
3442   the function enter helper.
3444 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), NF
3446   Test surprise flags and stack overflow at the same time.
3448 | LdARFlags, D(Int), S(FramePtr), NF
3450   Load the flags stored on the ActRec pointed to by the frame
3451   pointer S0. Bits not defined as flags may contain arbitrary garbage.
3453 | LdTVAux<ValidBits>, D(Int), S(Cell), NF
3455   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
3456   specifying which bits are allowed to be set.  The runtime may ignore it.
3458   Note that when we pass TypedValues around in registers, we usually use a byte
3459   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
3460   when we know that S0's m_type and m_aux were both materialized into the same
3461   64-bit register.
3463 /* Local Variables: */
3464 /* fill-column: 79 */
3465 /* End: */
3466 vim:textwidth=80