Avoid dynamic static checks when forwarding context
[hiphop-php.git] / hphp / doc / ir.specification
blob358c92f44e47fba6f4ed86bfaae437a22480fff3
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.
160 Instruction set
161 ---------------
163 1. Checks and Asserts
165 Note: Instructions that check boxed types only check that the operand is boxed,
166 and they ignore the type of the value inside the box (the inner type). The
167 inner type is normally checked when the value within the box is about to be
168 loaded, using a separate CheckRefInner instruction.
170 | CheckType<T>, DRefineS(0), S(Gen,Cls), B|P
172   Check that the type of the src S0 is T, and if so copy it to D, and
173   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
174   this means S0 still /may/ be a subtype of T in block B in some circumstances.
176   Specifically, subtypes of Type::Static may not be checked precisely,
177   depending on the type of the source.  This means the instruction may take the
178   branch in some circumstances even when S0 is a subtype of T, if T has a
179   non-empty intersection with Type::Static.
181   Also note that many types are not supported as the typeParam right now.
183 | CheckNullptr, ND, S(StaticStr,Nullptr), B
185   If S0 is not a null pointer, branch to block B. This is used to check the
186   return value of a native helper that returns a potentially null StringData*.
188 | AssertType, DRefineS(0), S(Gen,Cls,Ctx,FuncMM), P
190   Assert that the type of S0 is T, copying it to D.
192 | CheckTypeMem<T>, ND, S(MemToGen), B
194   If the value pointed to by S0 is not type T, branch to the block B.
196 | CheckVArray, DArrPacked, S(Arr), B|P
198   Check that S0 is a varray, and if so copy it to D, and fallthrough. If S0 is
199   not a varray, branch to block B.
201 | CheckDArray, DArrMixed, S(Arr), B|P
203   Check that S0 is a darray, and if so copy it to D, and fallthrough. If S0 is
204   not a darray, branch to block B.
206 | HintLocInner<T,localId>, ND, S(FramePtr), NF
208   Hint that the inner type of a BoxedCell in localId is likely type T, where T
209   is a subtype of BoxedCell. The type must be guarded on before it is known to
210   be true (via CheckRefInner).
212 | HintStkInner<T,offset>, ND, S(StkPtr), NF
214   Hint that the inner type of the BoxedInitCell on the stack pointed to by S0
215   at offset (in cells) is T. The type must be guarded on before it is known to
216   be true (via CheckRefInner).
218 | HintMBaseInner<T>, ND, NA, NF
220   Hint that the inner type of the BoxedInitCell pointed to by the member base
221   register is T.  The type must be guarded on before it is known to be true
222   (via CheckRefInner).
224 | CheckLoc<T,localId>, ND, S(FramePtr), B
226   Check that type of the given localId on the frame S0 is T; if not, branch to
227   block B.
229 | CheckStk<T,offset>, ND, S(StkPtr), B
231   Check that the type of the cell on the stack pointed to by S0 at offset (in
232   cells) is T; if not, branch to block B.
234 | CheckMBase<T>, ND, S(LvalToGen), B
236   Check that the value pointed to by the member base register S0 has type T; if
237   not, branch to block B.  This is functionally the same as CheckTypeMem.
239 | AssertLoc<T,localId>, ND, S(FramePtr), NF
241   Asserts that type of the supplied local on the frame S0 is T. This is used
242   for local type information, and is similar to CheckLoc except it doesn't
243   imply a runtime check (the assertion must've already been proven to be true)
244   and cannot cause control flow.
246 | AssertStk<T,offset>, ND, S(StkPtr), NF
248   Assert that stack element at `offset' (in cells) from S0 has type T. This is
249   similar to a CheckStk except that it does not imply a runtime check and
250   cannot cause control flow.
252 | AssertMBase<T>, ND, NA, NF
254   Assert that the value pointed to by the member base register has type T.
255   This is similar to a CheckMBase except that it does not imply a runtime check
256   and cannot cause control flow.
258 The following instructions deal with parameter coercion (the standard type
259 conversion for arguments to HNI functions). If parameter coercion fails these
260 functions will throw a TVCoercion exception. They may throw other types of
261 exceptions depending on how coercion is implemented.
263 | CoerceStk<T,offset,fn,argNum>, ND, S(StkPtr), NF
265   Converts the stack slot at offset (in cells) to type T, with the semantics
266   needed for calling a builtin function. May throw a TVCoercionException in the
267   case of failed parameter coercion. The callee is f, and the position of the
268   argument being coerced is argNum.
270 | CoerceMem<T,fn,argNum>, ND, S(PtrToGen), NF
272   Coerces the TypedValue at S0 to type T, with the semantics
273   needed for calling a builtin function. May throw a TVCoercionException in the
274   case of failed parameter coercion. The callee is fn, and the position of the
275   argument being coerced is argNum.
277 | CoerceCellToBool<fn,argNum>, D(Bool), S(Cell), NF
279 | CoerceCellToInt<fn,argNum>,  D(Int), S(Cell), NF
281 | CoerceStrToInt<fn,argNum>,   D(Int), S(Str), NF
283 | CoerceCellToDbl<fn,argNum>,  D(Dbl), S(Cell), NF
285 | CoerceStrToDbl<fn,argNum>,   D(Dbl), S(Str), NF
287   These instructions convert either a Cell or a Str to a primitive type (Bool,
288   Int, Dbl) and return the resulting value. They may throw an exception upon
289   failed type coercion. They are encoded along with callee Func, fn, and the
290   integer position of the argument, argNum, being coerced.
292 | CheckInit, ND, S(Gen), B
294   If S0's type is Uninit, branch to block B.
296 | CheckInitMem, ND, S(MemToGen), B
298   If the value pointed to by S0 has type Uninit, branch to block B.
300 | CheckCold<TransID>, ND, NA, B
302   Check if the counter associated with translation TransID is cold (i.e. within
303   a fixed threshold). If it's not (i.e. such translation has reached the
304   "hotness threshold"), then branch to block B.
306 | CheckRefs<firstBit,mask,vals>, ND, S(Func) S(Int), B
308   Perform reffiness guard checks. Operands:
310     S0 - function pointer for the frame
311     S1 - num params expected in the func
312     firstBit - first bit to check, must be a multiple of 64
313     mask - mask to check (RefDeps::Record::m_mask entries)
314     vals - values to check (RefDeps::Record::m_vals entries)
316   If any of the checks fail, branch to block B.
318 | EndGuards, ND, NA, NF
320   A no-op at runtime, this instruction serves to mark the end of the initial
321   sequence of guards in a trace.
323 | CheckNonNull, DSubtract(0, Nullptr), S(Nullptr,Func,PtrToGen,TCA,Cls,Ctx,Str), B
325   If the value in S0 is Nullptr, branch to block B. If S0 cannot be Nullptr, or
326   always is Nullptr, this check may be optimized away.
328 | AssertNonNull, DSubtract(0, Nullptr), S(Nullptr,StaticStr,Func,ArrLike), P
330   Returns S0, with Nullptr removed from its type. This instruction currently
331   supports a very limited range of types but can be expanded if needed.
333 | AssertARFunc<spOff>, ND, S(StkPtr) S(Func), NF
335   Asserts that the ActRec at offset spOff from S0 contains function S1.
337 | CheckFuncMMNonMagic, D(Func), S(FuncMM), B|P
339   Check that S0 is not a func pointer with magic bit set and if so copy it
340   to D, and fallthrough. If S0 has a magic bit set, branch to block B.
342 | CheckSmashableClass, ND, S(Smashable) S(Cls), B
344   If the lower 32 bits of S0 does not match class pointer S1, branch to block B.
346 2. Arithmetic
348 | AddInt, D(Int), S(Int) S(Int), NF
350 | SubInt, D(Int), S(Int) S(Int), NF
352 | MulInt, D(Int), S(Int) S(Int), NF
354 | AddIntO, D(Int), S(Int) S(Int), B
356 | SubIntO, D(Int), S(Int) S(Int), B
358 | MulIntO, D(Int), S(Int) S(Int), B
360 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
362 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
364 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
366 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
368 | DivInt, D(Int), S(Int) S(Int), NF
370 | Floor, D(Dbl), S(Dbl), NF
372 | Ceil, D(Dbl), S(Dbl), NF
374 | AbsDbl, D(Dbl), S(Dbl), NF
376 | Sqrt, D(Dbl), S(Dbl), NF
378 | AndInt, D(Int), S(Int) S(Int), NF
380 | OrInt, D(Int), S(Int) S(Int), NF
382 | XorInt, D(Int), S(Int) S(Int), NF
384 | Shl, D(Int), S(Int) S(Int), NF
386 | Shr, D(Int), S(Int) S(Int), NF
388 | Lshr, D(Int), S(Int) S(Int), NF
390   Double arithmetic, integer arithmetic, and integer bitwise operations.
391   Performs the operation described by the opcode name on S0 and S1, and puts
392   the result in D.
394   Undefined behavior occurs if Mod is given a divisor of zero, or if the
395   divisor is -1 and the dividend is the minimum representable integer.
397   AbsDbl computes the absolute value of a double-precision value.
399   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
400   or NAN depending on the dividend; and should the result of a division be zero
401   the sign will follow the normal sign rules for division.
403   DivInt will perform integer division of S1 by S0. S0 should not be zero and
404   must divide S1.
406   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
408   Lshr is logical right shift.
410   Floor and Ceil will return an integral value not greater, or not less
411   than their input respectively. Their use requires SSE 4.1, availability
412   should be checked before they are emitted.
414   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
415   branch to block B on integer overflow.
417 | XorBool, D(Bool), S(Bool) S(Bool), NF
419   Logical XOR of the two sources. (Note that && and || do not have
420   corresponding opcodes because they're handled at the bytecode level, to
421   implement short-circuiting.)
423 | Mod, D(Int), S(Int) S(Int), NF
425   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
428 3. Type conversions
430 To array conversions:
432 | ConvBoolToArr,                D(Arr), S(Bool),                         PRc
434 | ConvDblToArr,                 D(Arr), S(Dbl),                          PRc
436 | ConvIntToArr,                 D(Arr), S(Int),                          PRc
438 | ConvObjToArr,                 D(Arr), S(Obj),                   PRc|CRc
440 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
442 | ConvVecToArr,                 D(Arr), S(Vec),                      PRc|CRc
444 | ConvDictToArr,                D(Arr), S(Dict),                  PRc|CRc
446 | ConvShapeToArr,               D(Arr), S(Shape),                 PRc|CRc
448 | ConvKeysetToArr,              D(Arr), S(Keyset),                PRc|CRc
450 | ConvCellToArr,                D(Arr), S(Cell),                  PRc|CRc
453 | ConvArrToNonDVArr,            D(Arr), S(Arr),                      PRc|CRc
456 To vec conversions:
458 | ConvArrToVec,                 D(Vec), S(Arr),                   PRc|CRc
460 | ConvDictToVec,                D(Vec), S(Dict),                     PRc|CRc
462 | ConvShapeToVec,               D(Vec), S(Shape),                    PRc|CRc
464 | ConvKeysetToVec,              D(Vec), S(Keyset),                   PRc|CRc
466 | ConvObjToVec,                 D(Vec), S(Obj),                   PRc|CRc
469 To dict conversions:
471 | ConvArrToDict,                D(Dict), S(Arr),                  PRc|CRc
473 | ConvShapeToDict,              D(Dict), S(Shape),                PRc|CRc
475 | ConvVecToDict,                D(Dict), S(Vec),                     PRc|CRc
477 | ConvKeysetToDict,             D(Dict), S(Keyset),                  PRc|CRc
479 | ConvObjToDict,                D(Dict), S(Obj),                  PRc|CRc
482 To keyset conversions:
484 | ConvArrToKeyset,              D(Keyset), S(Arr),                PRc|CRc
486 | ConvVecToKeyset,              D(Keyset), S(Vec),                PRc|CRc
488 | ConvDictToKeyset,             D(Keyset), S(Dict),               PRc|CRc
490 | ConvShapeToKeyset,            D(Keyset), S(Shape),              PRc|CRc
492 | ConvObjToKeyset,              D(Keyset), S(Obj),                PRc|CRc
495 To varray conversions:
497 | ConvArrToVArr,                DArrPacked, S(Arr),                  PRc|CRc
499 | ConvVecToVArr,                DArrPacked, S(Vec),                  PRc|CRc
501 | ConvDictToVArr,               DArrPacked, S(Dict),                 PRc|CRc
503 | ConvShapeToVArr,              DArrPacked, S(Shape),                PRc|CRc
505 | ConvKeysetToVArr,             DArrPacked, S(Keyset),               PRc|CRc
507 | ConvObjToVArr,                DArrPacked, S(Obj),               PRc|CRc
510 To darray conversion:
512 | ConvArrToDArr,                DArrMixed, S(Arr),                   PRc|CRc
514 | ConvVecToDArr,                DArrMixed, S(Vec),                   PRc|CRc
516 | ConvDictToDArr,               DArrMixed, S(Dict),               PRc|CRc
518 | ConvShapeToDArr,              DArrMixed, S(Shape),              PRc|CRc
520 | ConvKeysetToDArr,             DArrMixed, S(Keyset),             PRc|CRc
522 | ConvObjToDArr,                DArrMixed, S(Obj),                PRc|CRc
525 To bool conversions:
527 | ConvArrToBool,               D(Bool), S(Arr),                           NF
529 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
531 | ConvIntToBool,               D(Bool), S(Int),                           NF
533 | ConvStrToBool,               D(Bool), S(Str),                           NF
535 | ConvObjToBool,               D(Bool), S(Obj),                           NF
537 | ConvCellToBool,              D(Bool), S(Cell),                          NF
540 To double conversions:
542 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
544 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
546 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
548 | ConvObjToDbl,                 D(Dbl), S(Obj),                           NF
550 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
552 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
554 | ConvCellToDbl,                D(Dbl), S(Cell),                          NF
557 To int conversions:
559 | ConvBoolToInt,                D(Int), S(Bool),                          NF
561 | ConvDblToInt,                 D(Int), S(Dbl),                           NF
563 | ConvObjToInt,                 D(Int), S(Obj),                           NF
565 | ConvStrToInt,                 D(Int), S(Str),                           NF
567 | ConvResToInt,                 D(Int), S(Res),                           NF
569 | ConvCellToInt,                D(Int), S(Cell),                          NF
572 To object conversions:
574 | ConvCellToObj, D(Obj), S(Cell), CRc|PRc
577 To string conversions:
579 | ConvDblToStr,                 D(Str), S(Dbl),                          PRc
581 | ConvIntToStr,                 D(Str), S(Int),                          PRc
583 | ConvObjToStr,                 D(Str), S(Obj),                          PRc
585 | ConvResToStr,                 D(Str), S(Res),                          PRc
587 | ConvCellToStr,                D(Str), S(Cell),                         PRc
590   All the above opcodes convert S0 from its current type to the destination
591   type, according to the PHP semantics of such a conversion.
593 | DblAsBits,                    D(Int), S(Dbl),                           NF
595   Reinterpret a double as an integer with the same bit pattern.
597 | ConvClsToCctx, D(Cctx), S(Cls), NF
599   Convert a class to a class context (i.e. the class with a 1 or'd into the low
600   bit).
602 | OrdStr,                       D(Int), S(Str),                           NF
604   Convert the first byte in a string to an unsigned integer.
605   Intended as an optimization for ord($str)
607 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    NF
609   Convert the character at position S1 in base string S0 to an unsigned
610   integer.  Raises a notice if the position is out of bounds.
611   Intended as an optimization for ord($str[$idx]).
613 | ChrInt,                      D(StaticStr), S(Int),                      NF
615   Convert the integer S0 to a the one character string with ascii code
616   S0 & 255.
618 | StrictlyIntegerConv,         D(Str|Int), S(Str),                        PRc
620   If S0 is a string representing an integer value (same criteria as array key
621   conversion), return that value as an integer. Otherwise return S0.
623 | ConvPtrToLval,               DLvalOfPtr, S(PtrToGen),                   NF
625   Convert S0 to an equivalent lval.
628 4. Boolean predicates
630 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
632 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
634 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
636 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
638 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
640 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
642 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
644   Perform 64-bit integer comparisons.
646 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
648 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
650 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
652 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
654 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
656 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
658 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
660   Perform comparisons of doubles. Comparisons that are unordered according to
661   IEEE 754 (such as when at least one operand is NaN) result in false.
663 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
665 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
667 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
669 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
671 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
673 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
675 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
677 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
679 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
681   Performs comparison of strings using PHP semantics.
683 | GtStrInt,                    D(Bool), S(Str) S(Int),                    NF
685 | GteStrInt,                   D(Bool), S(Str) S(Int),                    NF
687 | LtStrInt,                    D(Bool), S(Str) S(Int),                    NF
689 | LteStrInt,                   D(Bool), S(Str) S(Int),                    NF
691 | EqStrInt,                    D(Bool), S(Str) S(Int),                    NF
693 | NeqStrInt,                   D(Bool), S(Str) S(Int),                    NF
695 | CmpStrInt,                   D(Int),  S(Str) S(Int),                    NF
697   Performs comparison of strings with integers using PHP semantics.
699 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
701 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
703 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
705 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
707 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
709 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
711 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
713   Performs comparison of booleans.
715 | GtObj,                       D(Bool), S(Obj) S(Obj),                    NF
717 | GteObj,                      D(Bool), S(Obj) S(Obj),                    NF
719 | LtObj,                       D(Bool), S(Obj) S(Obj),                    NF
721 | LteObj,                      D(Bool), S(Obj) S(Obj),                    NF
723 | EqObj,                       D(Bool), S(Obj) S(Obj),                    NF
725 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    NF
727 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
729 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
731 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    NF
733   Perform comparison of objects using PHP semantics. All versions except for
734   SameObj and NSameObj may re-enter the VM and therefore may throw
735   exceptions. SameObj and NSameObj never re-enter or throw.
737 | GtArr,                       D(Bool), S(Arr) S(Arr),                    NF
739 | GteArr,                      D(Bool), S(Arr) S(Arr),                    NF
741 | LtArr,                       D(Bool), S(Arr) S(Arr),                    NF
743 | LteArr,                      D(Bool), S(Arr) S(Arr),                    NF
745 | EqArr,                       D(Bool), S(Arr) S(Arr),                    NF
747 | NeqArr,                      D(Bool), S(Arr) S(Arr),                    NF
749 | SameArr,                     D(Bool), S(Arr) S(Arr),                    NF
751 | NSameArr,                    D(Bool), S(Arr) S(Arr),                    NF
753 | CmpArr,                      D(Int),  S(Arr) S(Arr),                    NF
755   Perform comparison of arrays using PHP semantics. All versions except for
756   SameArr and NSameArr may re-enter the VM and therefore may throw
757   exceptions. SameArr and NSameArr never re-enter or throw.
759 | GtShape,                     D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
761 | GteShape,                    D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
763 | LtShape,                     D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
765 | LteShape,                    D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
767 | EqShape,                     D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
769 | NeqShape,                    D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
771 | SameShape,                   D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
773 | NSameShape,                  D(Bool), S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
775 | CmpShape,                    D(Int),  S(Shape,Arr,Dict) S(Shape,Arr,Dict), NF
777   Perform comparison of Shapes using PHP semantics. All versions except for
778   SameShape and NSameShape may re-enter the VM and therefore may throw
779   exceptions. SameShape and NSameShape never re-enter or throw.
781 | GtVec,                       D(Bool), S(Vec) S(Vec),                    NF
783 | GteVec,                      D(Bool), S(Vec) S(Vec),                    NF
785 | LtVec,                       D(Bool), S(Vec) S(Vec),                    NF
787 | LteVec,                      D(Bool), S(Vec) S(Vec),                    NF
789 | EqVec,                       D(Bool), S(Vec) S(Vec),                    NF
791 | NeqVec,                      D(Bool), S(Vec) S(Vec),                    NF
793 | SameVec,                     D(Bool), S(Vec) S(Vec),                    NF
795 | NSameVec,                    D(Bool), S(Vec) S(Vec),                    NF
797 | CmpVec,                      D(Int),  S(Vec) S(Vec),                    NF
799   Perform comparison of vecs. All versions except for SameVec and NSameVec may
800   re-enter the VM and therefore may throw exceptions. SameVec and NSameVec
801   never re-enter or throw.
803 | EqDict,                      D(Bool), S(Dict) S(Dict),                  NF
805 | NeqDict,                     D(Bool), S(Dict) S(Dict),                  NF
807 | SameDict,                    D(Bool), S(Dict) S(Dict),                  NF
809 | NSameDict,                   D(Bool), S(Dict) S(Dict),                  NF
811   Perform comparison of dicts. EqDict and NeqDict may re-enter the VM and
812   therefore may throw exceptions. SameDict and NSameDict never re-enter or
813   throw. Relational comparisons for dicts are not supported.
815 | EqKeyset,                    D(Bool), S(Keyset) S(Keyset),              NF
817 | NeqKeyset,                   D(Bool), S(Keyset) S(Keyset),              NF
819 | SameKeyset,                  D(Bool), S(Keyset) S(Keyset),              NF
821 | NSameKeyset,                 D(Bool), S(Keyset) S(Keyset),              NF
823   Perform comparison of keysets. As keysets can only contain ints and strings,
824   comparisons never re-enter or throw. Relational comparisons for keysets are
825   not supported.
827 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
829 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
831 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
833 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
835 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
837 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
839 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
841   Perform comparison of resources using PHP semantics. Resource comparisons
842   never re-enter or throw.
844 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
846   Checks if two Class values are equal.
848 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
850   Checks if two Func values are equal.
852 | EqStrPtr,                    D(Bool), S(Str) S(Str),                    NF
854   Checks if two string values represent the same underlying string. That is,
855   that they point at the same underlying storage.
857 | EqArrayDataPtr,              D(Bool), S(ArrLike) S(ArrLike),            NF
859   Checks if the two arguments represent the same underlying ArrayData. That is,
860   that they point at the same underlying storage.
862 | ProfileInstanceCheck, ND, C(StaticStr), NF
864   Profile that S0 has been used as the RHS of an instance check.
866 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
868   Sets D based on whether S0 is a descendant of the class, interface, or trait
869   in S1. (Note that this is always false for a trait). S1 may be null at
870   runtime if the class is not defined.
872 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
874   Fast path for interface checks. Sets D based on whether S0 implements S1, but
875   S1 must be a unique interface. This should only be used in repo-authoritative
876   mode.
878 | InstanceOfIfaceVtable<iface>, D(Bool), S(Cls), NF
880   Faster path for interface checks. Sets D based on whether S0 implements
881   iface, which must be a unique interface with an assigned vtable slot.
883 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
885   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
886   of cls, where cls must be a unique class that is not an interface or a trait.
888   If strictLikely is true, optimize for the case where S0 is not equal to S1.
890 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
892 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
894   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
895   of the class named by S1, where S1 must have a bit allocated for it in the
896   fast instance check bitvector (see class.h).
898 | InterfaceSupportsArr,        D(Bool), S(Str), NF
900 | InterfaceSupportsVec,        D(Bool), S(Str), NF
902 | InterfaceSupportsDict,       D(Bool), S(Str), NF
904 | InterfaceSupportsKeyset,     D(Bool), S(Str), NF
906 | InterfaceSupportsStr,        D(Bool), S(Str), NF
908 | InterfaceSupportsInt,        D(Bool), S(Str), NF
910 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
912   Returns whether t instanceof S0 returns true when t is of the given type.
914 | ResolveTypeStruct<class,suppress,offset,size,isOrAsOp>,
915 |   DDArr, S(StkPtr) S(Cls|Nullptr), NF
917   Applies class/alias resolution on the type structure that is at the stack
918   offset given by S0 and offset. If size > 1, combine the type structures on
919   the stack into the first one's denoted holes. Returns a copy.
920   S1 is the calling class, used to resolve the this typehint.
921   If isOrAsOp is set, raises an error if S0 contains traits, function types or
922   typevars.
923   If there is an error during type structure resolution, this instruction raises
924   an error. If suppress is set, this error is demoted to a warning.
926 | IsTypeStruct,                        D(Bool), SDArr S(Cell),           NF
928   Returns whether S1 matches the type structure of a defined type in S0 and S1
929   is a subtype of S0. The input type structure (S0) must be resolved.
931 | AsTypeStruct,                        ND, SDArr S(Cell),                NF
933   Throws an exception if S1 does not match the type structure of a defined
934   type in S0 or S1 is not a subtype of S0. The input type structure (S0) must
935   be resolved.
937 | HasToString, D(Bool), S(Obj), NF
939   Returns whether the object S0 has a toString method.
941 | IsType<T>, D(Bool), S(Gen), NF
943   Sets D to true iff S0 holds a value that is of type T. T must not be a
944   specialized type.
946 | IsNType<T>, D(Bool), S(Gen), NF
948   Sets D to true iff S0 holds a value that is not of type T. T must not be a
949   specialized type.
951 | IsTypeMem<T>, D(Bool), S(PtrToGen), NF
953   Sets D to true iff the value referenced by S0 is of type T. T must not be a
954   specialized type.
956   The value in S0 must not be a pointer into the evaluation stack or frame
957   locals.
959 | IsNTypeMem<T>, D(Bool), S(PtrToGen), NF
961   Sets D to true iff the value referenced by S0 is not of type T. T must not be
962   a specialized type.
964 | IsWaitHandle, D(Bool), S(Obj), NF
966   Sets D to true iff S0 is a subclass of WaitHandle.
968 | IsCol, D(Bool), S(Obj), NF
970   Sets D to true iff S0 is a collection.
972 | IsDVArray, D(Bool), S(Arr), NF
974   Sets D to true iff S0 is a darray or varray.
976 5. Branches
978 | JmpZero,                          ND, S(Int,Bool),                     B
980 | JmpNZero,                         ND, S(Int,Bool),                     B
982   Conditionally jump to based on S0.
984 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
986   Jump to the target of a sswitch statement, leaving the region, where the
987   target TCA is S0.
989 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
991   Jump to the target of a switch statement, leaving the region, using table
992   metadata <JmpSwitchData> and index S0, which must be a valid index in the
993   jump table.
995 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
997   Profile a switch statement target.
999 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
1001   Tests the implementation-specific surprise flags. If they're true, branches
1002   to block B. This is done by comparing an evaluation stack pointer to the RDS
1003   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
1004   pointing into the eval stack, so S0 should be a StkPtr in that case.
1006 | HandleRequestSurprise, ND, NA, NF
1008   Generate exceptions based on surprise flags on a per request basis.
1009   Make sure CheckSurpriseFlags is true before calling HandleRequestSurprise.
1011 | ReturnHook, ND, S(FramePtr) S(Gen), NF
1013   Surprise flag hook for function returns.
1015 | SuspendHookAwaitEF, ND, S(FramePtr) S(FramePtr) S(Obj), NF
1017   Surprise flag hook for suspending eagerly executing async functions. The S0
1018   frame was already teleported into S1. Decrefs S2 if it throws an exception.
1020 | SuspendHookAwaitEG, ND, S(FramePtr) S(Obj), NF
1022   Surprise flag hook for suspending eagerly executing async generators. The S0
1023   frame has an associated AG, which is already linked to the newly constructed
1024   AGWH in the blocked state. Decrefs S1 if it throws an exception.
1026 | SuspendHookAwaitR, ND, S(FramePtr) S(Obj), NF
1028   Surprise flag hook for suspending async functions and async generators resumed
1029   at Await. The S0 frame has an associated AFWH/AGWH still in the running state,
1030   S1 points to the child WH we are going to block on.
1032 | SuspendHookCreateCont, ND, S(FramePtr) S(FramePtr) S(Obj), NF
1034   Surprise flag hook for suspending generators and async generators during their
1035   invocation. The S0 frame was already teleported into S1. Decrefs S2 if it
1036   throws an exception.
1038 | SuspendHookYield, ND, S(FramePtr), NF
1040   Surprise flag hook for suspending generators and async generators at Yield.
1042 | Unreachable<AssertReason>, ND, NA, T
1044   Indicates an unreachable code path. Any instructions that are post-dominated
1045   by an Unreachable may be treated as unreachable by the optimizer, and the
1046   behavior of a program that attempts to execute an Unreachable is undefined.
1048 | EndBlock<AssertReason>, ND, NA, T
1050   Halt execution, without implying anything about the reachability of
1051   instructions preceding this. Intended for use in internal tests or other code
1052   not meant to be executed.
1054 | Jmp, ND, SVar(Top), B|T
1056   Unconditional jump to block B. In the second form, the target block must
1057   start with a DefLabel with the same number of destinations as Jmp's number of
1058   sources. Jmp parallel-copies its sources to the DefLabel destinations.
1060 | DefLabel, DMulti, NA, NF
1062   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
1063   destinations is a no-op, and the predecessor blocks may not necessarily end
1064   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
1065   instruction with the same number of sources. Ordinary branch instructions may
1066   not pass values to a DefLabel.
1068 | Select, DUnion(1,2), S(Bool,Int) S(Top) S(Top), NF
1070   If S0 is true/non-zero, return S1, otherwise return S2.
1073 6. Reference manipulation
1075 | Box, D(BoxedInitCell), S(Cell), CRc|PRc
1077   Box S0 and put the resulting BoxedInitCell in D. If S0 is Uninit, then
1078   InitNull will be boxed instead.
1080 | UnboxPtr, DUnboxPtr, S(MemToGen), NF
1082   If S0 points to a cell that is KindOfRef, dereference the pointer in the
1083   TypedValue and return a pointer to the inner-cell in D.
1085 | BoxPtr, DBoxPtr, S(MemToGen), NF
1087   Boxes the TypeValue that S0 points to if it is not boxed. The result D points
1088   to the same TypedValue as S0 but has a more refined type.
1090   S0 may not already point into a RefData (due to VM invariants), although the
1091   IR type system does not enforce it.
1094 7. Loads
1096 | LdStk<T,offset>, DParamMayRelax(Gen), S(StkPtr), NF
1098   Loads from S0 at offset (in cells), and puts the value in D as type T.
1100 | LdLoc<T,localId>, DParamMayRelax(Gen), S(FramePtr), NF
1102   Loads local slot localId from the frame S0 and puts the value in D as type T.
1104 | LdLocPseudoMain<T,localId>, DParam(Gen), S(FramePtr), B
1106   Loads local number localId from frame S0 and puts the value in D if the
1107   local's type is a subtype of T. If the local's type is not a subtype of T,
1108   then the load does not happen, and this instruction branches to B. This
1109   instruction is used for loading locals in pseudo-mains, where they can alias
1110   globals.
1112 | LdClsRefCls<T,slot>, DParamMayRelax(Cls), S(FramePtr), NF
1114   Loads class-ref's cls from slot `slot` in frame S0 and puts the value in D
1115   as type T. T must be a sub-type of TCls.
1117 | LdClsRefTS<slot>, DVArrOrNull, S(FramePtr), NF
1119   Loads class-ref's reified generics from slot `slot` in frame S0 and puts the
1120   value in D.
1122 | LdStkAddr<T,offset>, D(PtrToStkGen), S(StkPtr), NF
1124   Loads the address of the stack slot given by the pointer in S0 at the offset
1125   (in cells). T must be a subtype of PtrToStkGen.
1127 | LdLocAddr<localId>, D(PtrToFrameGen), S(FramePtr), NF
1129   Loads the address of the local slot localId from the frame S0 into D.
1131 | LdRDSAddr<T,RDSHandle>, DParam(PtrToGen), NA, NF
1133   Load the address of a Gen that lives at the specified RDS handle. The type
1134   param must be a subtype of PtrToGen.
1136 | LdInitRDSAddr<T,RDSHandle>, DParam(PtrToInitGen), NA, B
1138   Load the address of a Gen that lives at the specified RDS handle. Branch if
1139   the value at that address is Uninit. The type param must be a subtype of
1140   PtrToInitGen.
1142 | LdVectorBase, D(PtrToMembCell), S(Obj), NF
1144 | LdPairBase, D(PtrToMembCell), S(Obj), NF
1146   Loads the base pointer to an array of Cells from the given collection
1147   instance in S0.
1149 | LdMem<T>, DParam(Gen), S(MemToGen), NF
1151   Loads from S0 and puts the value in D.
1153 | LdContField<T>, DParam(Gen), S(Obj) C(Int), NF
1155   Loads a property from the object referenced by S0 at the offset given by S1
1156   and puts the value in D. S0 must be a Generator.
1158 | LdElem, D(Cell), S(PtrToCell) S(Int), NF
1160   Loads the element at index S1 from the base pointer in S0. The index in S1 is
1161   the number of bytes from the base in S0.
1163 | LdColVec, D(Vec), S(Obj), NF
1165   Load the vec array backing a collection instance in S0, which must be a
1166   Vector or ImmVector, and that specific object type must be known at compile
1167   time.
1169 | LdColDict, D(Dict), S(Obj), NF
1171   Load the dict array backing a collection instance in S0, which must be a
1172   Map, Set, ImmMap, or ImmSet, and that specific object type must be known at
1173   compile time.
1175 | CheckRefInner<T>, ND, S(BoxedCell), B
1177   TODO(#2939547): this should take BoxedInitCell
1179   Check that the inner type of the boxed cell in S0 is T, and if not take the
1180   branch to B.
1182 | LdRef<T>, DParam(Cell), S(BoxedCell), NF
1184   TODO(#2939547): this should take BoxedInitCell
1186   Loads the value held in the box referenced by S0 and puts the value in D. The
1187   inner type of S0 must be a subtype of T (usually ensured with a previous
1188   CheckRefInner).
1190 | LdCtx, DCtx, S(FramePtr), NF
1192   Loads into D the value of the m_this/m_cls field out of the frame pointer S0,
1193   which must be a frame for the function in the LdCtx's marker. The result
1194   could be either an object representing the this pointer or a class context.
1196 | LdCctx, DCtx, S(FramePtr), NF
1198   Loads into D the value of the m_cls field out of the frame pointer S0. The
1199   compiler should generate this only if it can prove that the frame does not
1200   contain a nullptr or $this pointer.
1202 | LdClosure<T>, DParam(Ctx), S(FramePtr), NF
1204   Loads into D the value of the m_this/m_cls field out of the frame pointer S0.
1205   The compiler should generate this only if it can prove that the frame context
1206   is a closure object of type T.  Unlike LdCtx and LdCctx, there are no special
1207   rules about the relative positions of LdClosure and InitCtx instructions.
1209 | CheckCtxThis, ND, S(Ctx), B
1211   Check that the context (m_this or m_cls) in S0 is a non-null $this
1212   pointer. If not, branch to B.
1214 | LdClsCtx, DCtxCls, S(Ctx), NF
1216   Loads into D the class representing the context in S0, which can be either
1217   the this pointer or the context class.
1219 | LdClsCctx, DCtxCls, S(Cctx), NF
1221   Loads into D the class representing the context in S0, which is a context
1222   class.
1224 | LdClsCtor, D(Func), S(Cls) S(FramePtr), NF
1226   Loads into D the constructor of class S0. If the constructor cannot be called
1227   from the context in S1, raise an error.
1229 | LdFuncMFunc, D(Func), S(FuncM), NF
1231   Loads into D the func pointer for the func pointer with magic bit set in S0.
1233 | LdSmashable, D(Smashable), NA, NF
1235   Loads a smashable value. The initial value is set to (1 << addr) + 1, where
1236   addr is a pointer pointing to the value in TC. The lowest bit is set for
1237   convenience of checking whether the value was already smashed.
1239 | LdSmashableFunc, D(Func), S(Smashable), NF
1241   Loads into D the func pointer stored in the higher 32 bits of S0.
1243 | LdRecCached, D(RecType), CStr, NF
1245   Loads the record named S0 via the RDS. Invokes autoload and may raise an error
1246   if the record is not defined.
1248 | DefCls, D(Cls), S(Int), NF
1250   Define the class corresponding to PreClass S0 in the current unit.
1252 | DefConst<T>, DParam(Top), NA, NF
1254   Define a constant value of type T. D is presumed to be globally available and
1255   the DefConst instruction will not actually appear in the IR instruction
1256   stream.
1258 | Conjure<T>, DParam(Top), NA, NF
1260   Define a value of type T. This instruction aborts at runtime; it is meant to
1261   be used in tests or code that is known to be unreachable.
1263 | ConjureUse, ND, S(Gen), NF
1265   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
1266   should not appear in reachable code.
1268 | LdCls, D(Cls), S(Str) C(Cls), NF
1270   Loads the class named S0 in the context of the class S1. Invokes autoload and
1271   may raise an error if the class is not defined. The explicit context
1272   parameter allows the compiler to simplify this instruction to a DefConst in
1273   some cases. If S0 is constant, this instruction may be simplified to a
1274   LdClsCached.
1276 | LdClsCached, D(Cls), CStr, NF
1278   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
1279   if the class is not defined.
1281 | LdClsCachedSafe, D(Cls), CStr, B
1283   Loads the class whose name is S0 out of the RDS. If the class is not defined,
1284   branch to B.
1286 | LdClsInitData, D(PtrToClsInitCell), S(Cls), NF
1288   Loads the pointer to the property initializer array for class S0.
1290 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
1292   Lookup the cached-class RDS handle for a given class name. Dereference that
1293   handle and return the associated Class, or null if not present.
1295 | LdCns, DCns, CStr, B
1297   Load the constant named S0, branching to B if isn't present.
1299 | LookupCnsE<T,constName>,  DCns, CStr, PRc
1301   Load a constant via the RDS. Raises a fatal error if it cannot define the
1302   constant.  This should only be executed if LdCns on the same constant has
1303   failed.
1305 | LdClsCns<className,constantName>, D(PtrToGen), NA, B
1307   Load the address of the constant 'constantName' for the class 'className' in
1308   RDS. If not initialized, branch to B.
1310 | LdSubClsCns<constantName,slot>, D(PtrToGen), S(Cls), NF
1312   Load the address of the constant 'constantName' for the class S0. The
1313   constant is known to be in the given slot. If the returned TypedValue is not
1314   UncountedInit, its value should not be used, and a fallback method should be
1315   called.
1317 | LdSubClsCnsClsName<constantName,slot>, D(StaticStr|Nullptr), S(Cls), NF
1319   Loads the name of the class pointed by the constant 'constantName' for the
1320   class S0. The constant is known to be in the given slot. Returns nullptr if
1321   constant is abstract, not type constant or does not point to a class.
1323 | CheckSubClsCns<constantName,slot>, ND, S(Cls), B
1325   Check that the constant 'constantName' lives in the given slot for the class
1326   S0, and branch if not. S0 must have at least slot+1 constants.
1328 | LdClsCnsVecLen, D(Int), S(Cls), NF
1330   Load the size of S0's constant table.
1332 | LdTypeCns, DStaticDArr, S(InitCell), B
1334   Loads the resolved type constant S0 or branches to B if S0 is not resolved or
1335   not a type constant.
1337 | LdClsTypeCns, DStaticDArr, S(Cls) S(Str), NF
1339   Loads type constant S1 of class S0 or raises an error if no such constant
1340   could be found, or if S0::S1 is not a type constant.
1342 | LdClsTypeCnsClsName, D(StaticStr), S(Cls) S(Str), NF
1344   Loads the name of the class pointed by the type constant S1 of class S0 or
1345   raises an error if no such constant could be found, or if S0::S1 is not a
1346   type constant.
1348 | ProfileSubClsCns<constantName,handle>, D(PtrToGen), S(Cls), NF
1350   Load the address of the constant 'constantName' for the class S0, profiling
1351   the observed slots. If the returned TypedValue is not UncountedInit, its
1352   value should not be used, and a fallback method should be called.
1354 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1356   Loads the target cache entry for a forwarding call to clsName::methodName.
1357   If the method does not exist, or the cache hasn't been filled yet, branch to
1358   B.
1360 | LookupClsMethodFCache<clsName,methodName>,
1361 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1362 |    NF
1364   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1365   the Class named by clsName and S1 should be the current vm frame pointer. May
1366   return Nullptr if lookup fails using a subset of the required lookup paths,
1367   indicating that a more complete lookup path should be taken. May throw if the
1368   method does not exist.
1370 | FwdCtxStaticCall, D(Cctx), S(Ctx), NF
1372   If S0 is an object, this opcode returns S0's class with the low bit set
1373   (i.e., as a Cctx). Otherwise this instruction returns S0.
1375 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1377   Loads the target cache entry for the method clsName::methodName. If the
1378   method does not exist or the cache hasn't been filled yet, branch to B.
1380 | LdClsMethodCacheCls<clsName,methodName>, D(Cctx), NA, NF
1382   Loads the target cache class context entry for a call to clsName::methodName
1383   from the current context. This instruction must only be used when the value
1384   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1385   LookupClsMethodCache returned a non-null value).
1387 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr),
1388 |                                           S(FramePtr),
1389 |                                           NF
1391   Lookup a function in the class method targetcache. The class name and method
1392   name are clsName and methodName, respectively. S0 is the current vm frame
1393   pointer. Returns Nullptr if the method cannot be found using a subset of the
1394   required lookup paths, indicating that a more complete lookup path should be
1395   taken. May throw if the method does not exist.
1397 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1399   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1401 | LdFuncVecLen, D(Int), S(Cls,Cctx), NF
1403   Load the funcVecLen field from S0.
1405 | LdClsMethod, D(Func), S(Cls,Cctx) C(Int), NF
1407   Load a Func* off of the class method table for S0, at offset S1 (in method
1408   slots).
1410 | LookupClsMethod<calleeAROffset,forward,dynamic>,
1411 |   ND,
1412 |   S(Cls) S(Str) S(StkPtr) S(FramePtr),
1413 |   NF
1415   Store a pointer to a class method into an activation record. S0 points to the
1416   class, S1 is the method name, S2 is a stack pointer that has an activation
1417   record to modify at `spToActRecOffset', and S3 is a pointer to the current
1418   frame (used to get the context). `forward` indicates if we should forward the
1419   current context. `dynamic` indicates if the method is called dynamically.
1420   Also perform caller checks (dynamic call, rx). May throw or fatal if method
1421   is not accessible or caller checks have failed.
1423 | LdPropAddr<T,offset>, DParam(LvalToPropGen), S(Obj), NF
1425   Load the address of the object property for S0 + `offset' (in bytes).  T must
1426   be a subtype of PtrToPropGen.
1428 | LdInitPropAddr<T,offset>, DParam(LvalToPropGen), S(Obj), B
1430   Load the address of the object property for S0 + `offset' (in bytes). Branch
1431   if the value at that address is Uninit.  T must be a subtype of
1432   PtrToPropInitGen.
1434 | LdGblAddr, D(PtrToGblGen), S(Str), B
1436   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1437   global is not defined.
1439 | LdGblAddrDef, D(PtrToGblGen), S(Str), NF
1441   Loads a pointer to a global. S0 is the global's name. Defines the global if
1442   it is not already defined.
1444 | LdClsPropAddrOrNull, D(PtrToSPropGen|Nullptr),
1445 |                      S(Cls) S(Str) C(Cls) C(Bool),
1446 |                      NF
1448   Loads a pointer to a static class property. S0 points to the class, S1 is the
1449   property name, and S2 is the class representing the context of the code
1450   accessing the property. If class S0 does not have a visible and accessible
1451   static property named S1, then nullptr is returned. An exception
1452   will be thrown if the property is marked LateInit and its value is
1453   Uninit, unless S3 is true.
1455 | LdClsPropAddrOrRaise, D(PtrToSPropGen), S(Cls) S(Str) C(Cls) C(Bool), NF
1457   Loads a pointer to a static class property. S0 points to the class, S1 is the
1458   property name, and S2 is the class representing the context of the code
1459   accessing the property. If class S0 does not have a visible and accessible
1460   static property named S1, then nullptr is returned. An exception
1461   will be thrown if the property is marked LateInit and its value is
1462   Uninit, unless S3 is true.
1464 | LookupSPropSlot, D(Int), S(Cls) S(Str), NF
1466   Lookup the slot index of the static property with the name S1 on the class
1467   S0, returning -1 if not found.
1469 | LdObjMethod<methodName>, D(FuncMM), S(Cls) S(Smashable), NF
1471   Loads a func pointer, maybe with a magic bit set, pointing to the instance
1472   method that would be called if a `methodName` is invoked on an instance of S0.
1473   Caches the mapping in the TC cache (using S1) and target cache. Raises a fatal
1474   if the class does not have an accessible method with the given name and does
1475   not have a __call method.
1477 | LdObjInvoke, D(Func), S(Cls), B
1479   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1480   to block B if it is not present.
1482 | LdArrFuncCtx<offset>, ND, S(Arr,Vec) S(StkPtr) S(FramePtr), NF
1484   Try to load an array as a function context. This is for use translating
1485   FPushFunc when the callee is an array. This instruction attempts to populate
1486   a partially created ActRec pointed to by S1 + `offset' (in cells). It is also
1487   responsible for performing caller checks (dynamic call, rx).
1489 | LdObjClass, DLdObjCls, S(Obj), NF
1491   Load the class out of the object in S0 and put it in D.
1493 | LdClsName, D(StaticStr), S(Cls), NF
1495   Load the name of the Class* in S0.
1497 | LdFunc<offset>, ND, S(Str) S(StkPtr) S(FramePtr), NF
1499   Resolve the Func whose name is S0. Perform caller checks (dynamic call, rx).
1500   Then store the Func into the partially constructed ActRec pointed to by
1501   S1 + `offset` (in cells). Also populate the m_this/m_cls field if necessary.
1502   Fatal if the named function is not defined, and the autoloader fails to
1503   define it.
1505 | LdFuncCached<funcName>, D(Func), NA, NF
1507   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1508   not defined yet. Fatal if function autoloader fails to define it.
1510 | LookupFuncCached<funcName>, D(Func), NA, NF
1512   Loads the Func whose name is given from %1, invoking autoload if it is not
1513   defined yet. Fatal if the function autoload fails to define it. This
1514   instruction does not assume the loaded function will be called immediately,
1515   so it will raise a resolution failure error instead of a call failure error.
1517 | LdARFuncPtr<offset>, DParam(Func), S(StkPtr), NF
1519   Loads the m_func member of an ActRec. S0 is the base address, with `offset'
1520   cells to the ActRec.
1522 | LdARCtx<T,offset>, DParam(Ctx), S(StkPtr), NF
1524   Loads the m_this/m_cls member of an ActRec. S0 is the base address, with
1525   `offset' cells to the ActRec.
1527 | LdARIsDynamic<offset>, D(Bool), S(StkPtr), NF
1529   Loads the dynamic call flag of a pre-live ActRec. S0 is the base address,
1530   with `offset' cells to the ActRec.
1532 | LdARNumParams, D(Int), S(FramePtr), NF
1534   Loads the number of params from an ActRec. S0 is the address of the ActRec
1536 | LdFuncNumParams, D(Int), S(Func), NF
1538   Returns the value of func->numParams().
1540 | LdFuncName, D(StaticStr), S(Func), NF
1542   Loads the full name of S0.
1544 | LdStrLen, D(Int), S(Str), NF
1546   Load the length of the string in S0.
1548 | FuncSupportsAsyncEagerReturn, D(Bool), S(Func), NF
1550   Tests for Func::m_attrs & AttrSupportsAsyncEagerReturn.
1552 | IsFuncDynCallable, D(Bool), S(Func), NF
1554   Tests for Func::m_attrs & AttrDynamicallyCallable.
1556 | IsClsDynConstructible, D(Bool), S(Cls), NF
1558   Tests for Class::m_attrCopy & AttrDynamicallyConstructible.
1560 | LdFuncRxLevel, D(Int), S(Func), NF
1562   Returns the value of func->rxLevel().
1564 | IsReifiedName, D(Bool), S(Str), NF
1566   Tests whether the name in S0 is name of a reified class or function.
1568 | LdReifiedGeneric, DVArr, S(Str), NF
1570   Loads the reified generics associated with the name at S0. This name can be a
1571   class name or a function name. Raises an error if this name does not have
1572   any associated reified generics.
1574 | LdClsFromClsMeth, D(Cls), S(ClsMeth), NF
1576   Load the Class* of the ClsMethDataRef in S0.
1578 | LdFuncFromClsMeth, D(Func), S(ClsMeth), NF
1580   Load the Func* of the ClsMethDataRef in S0.
1582 8. Allocation
1584 | AllocObj, DAllocObj, S(Cls), PRc
1586   Allocates a new object of class S1.
1588 | AllocObjReified, DAllocObj, S(Cls) SVArr, PRc
1590   Allocates a new object of class S1 and sets S2 as the reified generics of this
1591   class. If this class is not reified, this instruction raises an error.
1593 | InitProps<class>, ND, NA, NF
1595   Calls the property initializer function (86pinit) for class.  May throw.
1597 | InitSProps<class>, ND, NA, NF
1599   Calls the static property initializer functions (86sinit and/or 86linit)
1600   for class. May throw.
1602 | CheckRDSInitialized<RDSHandle>, ND, NA, B
1604   Check if the RDS entry at the specified handle is initialized, and branches
1605   if not.
1607 | MarkRDSInitialized<RDSHandle>, ND, NA, NF
1609   Mark the given RDS entry as being initialized.
1611 | PropTypeRedefineCheck, ND, C(Cls) C(Int), NF
1613   Check that the specified property at the slot S1 on S0, which redeclares a
1614   property in the parent, has a declared type equivalent to the parent
1615   declaration.
1617 | DebugBacktrace, DVArr, S(Int), PRc
1619   Obtain stack trace by calling the debug_backtrace() method.
1621 | DebugBacktraceFast, D(Res), NA, PRc
1623   Obtain compact stack trace resource that can be expanded lazily.
1625 | InitThrowableFileAndLine, ND, S(Obj), NF
1627   Initialize Throwable's file name and line number assuming the stack trace
1628   was already initialized and the current vmfp() is a built-in.
1630 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1632   Allocates an instance of class.
1634 | InitObjProps<class>, ND, S(Obj), NF
1636   Initializes properties of object S0.
1638 | ConstructInstance<class>, DAllocObj, NA, NF
1640   Call the custom instance constructor of an extension class.
1642 | ConstructClosure<class>, DAllocObj, NA, NF
1644   Call the custom instance constructor of a Closure.
1646 | NewArray, D(Arr), C(Int), PRc
1648   Allocate a new array with the expected capacity S0.
1650 | NewMixedArray, DArrMixed, C(Int), PRc
1652   Allocate a new array in mixed mode with the expected capacity S0.
1654 | NewDArray, DArrMixed, C(Int), PRc
1656   Allocate a new dict-like array with the expected capacity S0.
1658 | NewDictArray, D(Dict), C(Int), PRc
1660   Allocate a new dict with the expected capacity S0.
1662 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc
1664   Allocate a new keyset containing N elements off the stack given by S0, at
1665   `offset'. This instruction moves the elements off the stack without
1666   manipulating their reference counts.
1668 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1670   Allocate a new array in the same mode as S0 and with expected capacity S1,
1671   unless S1 == 0, in which case the capacity is set to S0's size.
1673 | AllocPackedArray<size>, DArrPacked, NA, PRc
1675   Allocate a new uninitialized packed array with space for size elements in it.
1676   The array will be initialized with values using either InitPackedLayoutArray
1677   or InitPackedLayoutArrayLoop.
1679 | AllocVArray<size>, DArrPacked, NA, PRc
1681   Allocate a new uninitialized vec-like array with space for size elements in
1682   it.  The array will be initialized with values using either
1683   InitPackedLayoutArray or InitPackedLayoutArrayLoop.
1685 | AllocVecArray<size>, D(Vec), NA, PRc
1687   Allocate a new uninitialized vector array with space for size elements in it.
1688   The array will be initialized with values using either InitPackedLayoutArray
1689   or InitPackedLayoutArrayLoop.
1691 | InitPackedLayoutArray<index>, ND, S(Arr,Vec) S(Cell), NF
1693   Store the S1 into the slot at index in array S0. This instruction assumes
1694   that it doesn't have to incref the value being stored. Used to initialize an
1695   array allocated with AllocPackedArray or AllocVecArray.
1697 | InitPackedLayoutArrayLoop<offset,size>, ND, S(Arr,Vec) S(StkPtr), CRc
1699   Move `size' elements from the stack given by S1, at `offset', into the array
1700   S0.  Assumes that the first element on the stack is the last element in the
1701   array.  Used to initialize an array allocated with AllocPackedArray or
1702   AllocVecArray that was too big to use a series of InitPackedLayoutArray
1703   instructions.
1705 | NewRecord<offset,keys...>, D(Record), S(RecType) S(StkPtr), PRc|CRc
1707   Allocate a new record, given the type S0 and N immediate keys
1708   and taking N elements off the stack given by S1, at `offset'.
1709   This instruction assumes it can take the values from the stack
1710   without increfing them.
1712 | NewStructArray<offset,keys...>, DArrMixed, S(StkPtr), PRc|CRc
1714   Allocate a new key/value array, given N immediate keys and taking N elements
1715   off the stack given by S0, at `offset'. This instruction assumes it can take
1716   the values from the stack without increfing them.
1718 | NewStructDArray<offset,keys...>, DArrMixed, S(StkPtr), PRc|CRc
1720   Allocate a new key/value dict-like array, given N immediate keys and taking N
1721   elements off the stack given by S0, at `offset'. This instruction assumes it
1722   can take the values from the stack without increfing them.
1724 | NewStructDict<offset,keys...>, D(Dict), S(StkPtr), PRc|CRc
1726   Allocate a new key/value dict array, given N immediate keys and taking N
1727   elements off the stack given by S0, at `offset'. This instruction assumes it
1728   can take the values from the stack without increfing them.
1730 | NewCol<type>, DCol, NA, PRc
1732   Create an empty new collection of `type'. `type' cannot be Pair.
1734 | NewPair<offset>, DCol, S(Cell) S(Cell), PRc|CRc
1736   Allocate a new Pair and fill it with the given cells. Ownership of the cells
1737   is transferred from $1 and $2 to the pair without manipulating the refcounts.
1739 | NewColFromArray<type>, DCol, S(Vec|Dict), PRc|CRc
1741   Create a collection of `type` from a Vec or Dict kind. `type` cannot be
1742   Pair. S0 must be vec kind when `type` is Vector or ImmVector, and must be
1743   dict kind otherwise. Ownership of S0 is transferred from $1 to the
1744   collection, without manipulating the refcount.
1746 | Clone, DofS(0), S(Obj), PRc
1748   Allocate an object by cloning S0.
1750 | NewClsMeth, D(ClsMeth), S(Cls) S(Func), NF
1752   Allocate a new ClsMethDataRef.
1754 9. Call & Return
1756 | SpillFrame<offset,numArgs>,
1757 |   ND,
1758 |   S(StkPtr) S(Func,Nullptr) S(Ctx,Cls,Nullptr) S(Str,Nullptr) S(Bool)
1759 |   S(Arr|Vec,Nullptr),
1760 |   NF
1762   Operands:
1764      S0 - caller stack pointer
1765      S1 - callee Func or nullptr
1766      S2 - object (for FPushObjMethod*), class (for FPushClsMethod*), context
1767           (for FPushClsMethodF), or nullptr (for FPushFunc*).
1768      S3 - invoke name for magic dispatch
1769      S4 - whether this is a "dynamic" call
1770      S5 - reified generics type structure list
1772   Defines the fields for an activation record and writes them to the stack
1773   pointed to by S0, at `offset'.
1775 | BeginInlining<offset>, ND, S(StkPtr), NF
1777   Marks the start of an inlined function whose stack resides offset cells below
1778   the SP. It has no effect other than to hint to optimization passes that at the
1779   start of the inlined function its stack is dead.
1781 | DefInlineFP<func,callBCOff,retSPOff>, D(FramePtr),
1782 |                                       S(StkPtr) S(FramePtr),
1783 |                                       NF
1785   Defines a frame pointer for an inlined function.
1787   `func' is the function being inlined. `callBCOff' points to the caller's
1788   FCall instruction, `retSPOff' represents what the stack offset should be
1789   after the FCall instruction in the caller.
1791   This instruction is primarily used to represent a frame in the IR in a way
1792   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1793   it is pushed into an unlikely path) it performs callee-side responsibilities
1794   for setting up an activation record (i.e. setting the return ip and m_callOff,
1795   storing the frame pointer into D).
1797   The caller frame pointer is passed as S1. This is used to keep track of the
1798   call chain of inlined functions for simplification and dead code elimination.
1800 | InlineReturn<callerFPOff>, ND, S(FramePtr), NF
1802   Unlinks a frame constructed by DefInlineFP.  `callerFPOff' is the offset of
1803   the caller's frame pointer relative to S0. Every inline region must contain
1804   exactly one InlineReturn or InlineReturnNoFrame. Optimization passes which
1805   attempt to elide DefInlineFP detect "main" blocks within an inlined region as
1806   those which are dominated by BeginInlining and post-dominated by InlineReturn.
1808 | InlineSuspend<callerFPOff>, ND, S(FramePtr), NF
1810   Identical to an InlineReturn, but for use when the frame is being suspended in
1811   a side exit and will be torn down via an InlineReturn in the main trace. The
1812   behavior of InlineSuspend is identical to inline return, but it allows us to
1813   preserve the invariant that an inline region has a single InlineReturn for
1814   every DefInlineFP (while still allowing InlineSuspend in the case of a side
1815   exit).
1817 | InlineReturnNoFrame<InlineFrameStart>, ND, NA, NF
1819   Mark the end of an inlined function for which no DefInlineFP was required. The
1820   primary purpose of this instruction is to mark the result of a SpillFrame as
1821   dead. InlineFrameStart is the caller FP-relative offset of the start of the
1822   callee frame. Everything below InlineFrameStart is dead.
1824 | CallUnpack<spOffset,numParams,callOff,funcd,destroyLocals>,
1825 |                       DCall,
1826 |                       S(StkPtr) S(FramePtr),
1827 |                       NF
1829   Invoke function corresponding to the current FPI with numParams arguments,
1830   the last of which is an array of the remaining args. Used for FCall with
1831   unpack. S0+spOffset points to the stack resulting after the ActRec for the
1832   function and numParams arguments have been pushed. CallUnpack pops the array
1833   off the stack, pushes the elements of the array as arguments, and invokes the
1834   function in the ActRec.
1836 | SyncReturnBC<spOffset,callBCOffset>, ND, S(StkPtr) S(FramePtr), NF
1838   Stores callBCOffset into the frame at spOffset from S0 as the call bytecode
1839   address and the frame S1 as the return frame.
1841 | Call<offset,numParams,callOff,funcd,destroyLocals>, DCall,
1842 |                                                     S(StkPtr) S(FramePtr),
1843 |                                                     NF
1845   Transfer control to a callee, based on the pre-live activation record and set
1846   of args on the stack pointed to by S0 at `offset'. S1 is the current caller
1847   frame pointer. The `funcd' in the extra data is a Func* for the callee if we
1848   know the callee statically.
1850 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), NF
1852   Execute a call to the native builtin specified by the current function. S0
1853   and S1 should be the current vmfp and vmsp, respectively.
1855 | CallBuiltin, DBuiltin, S(FramePtr) S(StkPtr) SVar(PtrToGen,Gen,Cls,Nullptr), PRc
1857   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1858   and vmsp, respectively.
1860   The source and destination types correspond to C++ parameter and return types
1861   as follows:
1863     C++ type            HHIR type         Position
1864     -----------------   ---------         --------
1865     bool                Bool              source, destination
1866     int64_t             Int               source, destination
1867     double              Dbl               source, destination
1868     const String&       PtrToStr          source
1869     const Array&        PtrToArr          source
1870     const Object&       PtrToObj          source
1871     const Variant&      PtrToGen          source
1872     Variant&            PtrToGen          source (ref param)
1873     String              {Str|InitNull}    destination
1874     Array               {Arr|InitNull}    destination
1875     Object              {Obj|InitNull}    destination
1876     Variant             {Gen-UninitNull}  destination
1878 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Gen), T
1880   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1881   frame pointer is stored in rvmfp, then return to the saved return address in
1882   S1.  The return value is S2, which is passed via the rret_*() registers to
1883   the caller.  The `suspendingResumed' flag indicates when this instruction is
1884   suspending a resumable rather than performing a normal function return.
1886 | AsyncFuncRet<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1888   Return from a resumed async function, assuming no surprise. Ensures that
1889   S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored in rvmfp,
1890   packs return value S2 into registers and calls the `asyncFuncRet` unique
1891   stub. The stub stores the result into the wait handle associated with the
1892   frame pointer, marks it as finished, unblocks its parents and if possible,
1893   directly resumes the first parent (fast path), or a pending fast runnable
1894   ResumableWaitHandle (slower path). Otherwise, it will exit VM and return
1895   control to the asio scheduler (slow path). The stack must contain exactly one
1896   cell containing uninitialized garbage, which will be populated by the stub
1897   either to pass the return value to the resumed function, or to return null
1898   to the scheduler.
1900 | AsyncFuncRetSlow<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1902   Return from a resumed async function, assuming unknown surprise flag state
1903   after the previous surprise was handled by executing "return" event hook.
1904   Calls the `asyncFuncRetSlow` stub, which re-checks the surprise flag and
1905   transfers control to the AsyncFuncRet if it was clear, or performs the slow
1906   path of AsyncFuncRet if it was not, without resuming another function, as
1907   we are not able to call a potential "resume await" event hook from the stub.
1909 | AsyncSwitchFast<spOff>, ND, S(StkPtr) S(FramePtr), T
1911   Switch control to another ResumableWaitHandle. Ensures that S0 + `spOff`
1912   (in cells) is stored in rvmsp and that S1 is stored in rvmfp and calls the
1913   `asyncSwitchCtrl` unique stub, which tries to resume a pending fast runnable
1914   ResumableWaitHandle (fast path) if possible, otherwise it will exit VM and
1915   return control to the asio scheduler (slow path). As with AsyncRetFast, the
1916   stack must contain exactly one cell containing uninitialied garbage.
1918 | LdRetVal<T>, DParam(Gen), S(FramePtr), NF
1920   Load the return value from the already-returned-from ActRec pointed to by S0
1921   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1922   NativeImpl return a TypedValue in the C++ ABI registers.
1924 | DbgTrashRetVal, ND, S(FramePtr), NF
1926   For debugging purposes.  Store kTVTrashJITRetVal to the return value slot on
1927   the activation record pointed to by S0.
1929 | ReleaseVVAndSkip, ND, S(FramePtr), B
1931   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1932   nothing. If it is an ExtraArgs, deallocates the ExtraArgs structure.
1933   Otherwise it frees the VarEnv and jumps to block B. This instruction may not
1934   occur in an inlined call.
1936 | GenericRetDecRefs, ND, S(FramePtr), NF
1938   Does decrefs of all the current function's locals, where S0 is a pointer to
1939   the relevant activation record. This instruction may not occur in an inlined
1940   call.
1943 10. Stores
1945 | StMem, ND, S(MemToGen) S(Gen), NF
1947   Store S1 into the location pointed to by S0.
1949 | StElem, ND, S(PtrToCell) S(Int) S(Cell), NF
1951   Store S2 into the location given by the index S1 from base pointer S0. The
1952   index in S1 is the number of bytes from the base in S0.
1954 | StLoc<localId>, ND, S(FramePtr) S(Gen), NF
1956   Store S1 to local number localId on the frame pointed to by S0.
1958 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Gen), NF
1960   Behaves just like StLoc, except the hard requirement that it is only emitted
1961   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1962   intraprocedural analysis to know whether the store is truly dead.
1964 | StLocRange<localIds>, ND, S(FramePtr) S(Gen), NF
1966   Store S1 to the local variables corresponding to localIds, on the frame
1967   pointed to by S0.
1969 | StClsRefCls<slot>, ND, S(FramePtr) S(Cls), NF
1971   Store S1 to class-ref's cls slot `slot` on the frame pointed to by S0.
1973 | StClsRefTS<slot>, ND, S(FramePtr) SVArr, NF
1975   Store S1 to class-ref's reified generic slot `slot` on the frame pointed to
1976   by S0.
1978 | StRef, ND, S(BoxedCell) S(Cell), NF
1980   Store the value in S1 into the RefData pointed to by S0. Stores the
1981   RefData::m_type also.
1983 | StStk<offset>, ND, S(StkPtr) S(Gen), NF
1985   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1987 | StOutValue<index>, ND, S(FramePtr) S(Gen), NF
1989   Store S1 in a caller allocated out-value vm stack cell index cells above
1990   S0 on the stack.
1992 | DbgTrashStk<offset>, ND, S(StkPtr), NF
1994   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
1995   by S0, at a given offset (in cells).
1997 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
1999   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
2000   slots starting at the offset (in cells), and going toward higher memory
2001   addresses.
2003 | DbgTrashMem, ND, S(MemToGen), NF
2005   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
2006   S0.
2008 | RecordReifiedGenericsAndGetName, D(StaticStr), SVArr, CRc
2010   Takes a varray of reified generics from the stack, adds them to the reified
2011   generics table and returns mangled name used as the key
2013 | RecordReifiedGenericsAndGetTSList, DVArr, SVArr, CRc
2015   Takes a varray of reified generics from the stack and adds them to the reified
2016   generics table and returns the input varray of reified generics, possibly
2017   static
2019 | MangleReifiedName, D(StaticStr), S(StaticStr) S(StaticStr), NF
2021   Mangles the name from S0 with the mangled type structure string from S1
2024 11. Trace exits
2026 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), NF
2028   Sync the given vmfp and vmsp to their in-memory locations.
2030 | ReqBindJmp<bcOff,transFlags>, ND, S(StkPtr) S(FramePtr), T
2032   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
2034 | ReqRetranslate<transFlags>, ND, S(StkPtr) S(FramePtr), T
2036   Emit a jump to a service request that will chain to a retranslation of this
2037   tracelet.
2039   This instruction is used in exit traces for a type prediction that occurs at
2040   the first bytecode offset of a tracelet.
2042 | ReqRetranslateOpt<transId,bcOff>, ND, S(StkPtr) S(FramePtr), T
2044   Emit a service request to retranslate, with a higher optimization gear,
2045   translation transID, which starts at bcOff. This instruction is used in exit
2046   traces that trigger profile-guided optimizations.
2049 12. Refcounting and copies
2051 | Mov, DofS(0), S(Top), P
2053   Defines D as S0. May imply register-to-register moves at code generation
2054   time. Does not imply an incref or any other manipulation of S0.
2056 | IncRef, ND, S(Gen,Ctx), NF
2058   If S0 is a refcounted type, increment its refcount.
2060 | DecRef<locId>, ND, S(Gen,Ctx), CRc
2062   Decrease the reference count of S0 by one, and call a destructor for types
2063   that require it if it goes to zero.
2065   Note that although DecRef takes a Gen, we don't allow it to use information
2066   about the inner types of a BoxedCell. This is because we don't guard on the
2067   inner types of a BoxedCell except when doing LdRef. For any S0 that is a
2068   strict subtype of BoxedCell, the DecRef must just decref it as if it were a
2069   BoxedCell.
2071   The locId is just a hint to the runtime indicating which local variable is
2072   being DecRef'd, if any.
2074 | DecRefNZ, ND, S(Gen,Ctx), CRc
2076   Decrease the reference count of S0 by one, do not check if it goes to zero.
2077   This instruction can be used for more efficient code when it is provable that
2078   the reference count cannot go to zero.
2081 13. Misc
2083 | DefFP, D(FramePtr), NA, NF
2085   Creates a temporary D representing the current vm frame pointer.
2087 | DefSP<stackOff>, D(StkPtr), S(FramePtr), NF
2089   Creates a temporary D representing the current vm stack pointer. S0 is a
2090   pointer to the current frame. The 'stackOff' is the logical offset between S0
2091   and the stack pointer, but in the case of generators this is not the
2092   physical offset at runtime.
2094   This instruction is used at the beginning of tracelets to represent the state
2095   of the stack on entry and does not emit code.
2097 | FuncGuard<func,prologueAddrPtr>, ND, NA, NF
2099   Emits a function guard for func, and arranges to write the address of the
2100   following instruction to prologueAddrPtr.
2102 | Count, D(Int), S(Cell), NF
2104   Computes the number of elements in S0. The count of an array is the number of
2105   elements it contains, without recursing into containers in the array.
2106   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
2107   count of 0. The count of objects that implement the Countable interface is
2108   computed by returning the value of their count method. Objects that do not
2109   implement Countable have a count of 1.
2111 | CountArray,      D(Int), S(Arr),    NF
2113 | CountArrayFast,  D(Int), S(Arr),    NF
2115 | CountVec,        D(Int), S(Vec),    NF
2117 | CountDict,       D(Int), S(Dict),   NF
2119 | CountShape,      D(Int), S(Shape),  NF
2121 | CountKeyset,     D(Int), S(Keyset), NF
2123 | CountCollection, D(Int), S(Obj),    NF
2125   Computes the number of elements in S0 using the same definition as Count, but
2126   with a restriction on the input type.
2128   CountArray expects any array. CountArrayFast expects an array whose kind is
2129   not kGlobalsKind. CountCollection expects a collection object.
2131 | Nop, ND, NA, NF
2133   Does nothing. It's sometimes useful for the simplifier to insert one of these
2134   in the instruction stream.
2136 | ExitPlaceholder, ND, NA, B
2138   Does nothing if executed. Semantically, this instruction carries a taken edge
2139   to a block that was a pure side-exit during initial IR generation.  This
2140   allows later passes to test conditions and create new exits from the region
2141   at this point in the program.
2143 14. Runtime helpers
2145 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), NF
2147   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
2148   a class) or implement (if S1 is an interface) S1, this instruction will raise
2149   a recoverable fatal error describing the type mismatch.
2151 | VerifyParamCallable, ND, S(Gen) C(Int), NF
2153   If S0 is not callable, as defined by the php function is_callable, this
2154   instruction will raise a recoverable fatal error describing the type
2155   mismatch.
2157 | VerifyParamFail, ND, C(Int), NF
2159   Assumes that parameter number S0 in the current function has failed a its
2160   type check. Depending on the typehint being verified and a number of runtime
2161   options, may coerce the parameter to the correct type or raise a recoverable
2162   fatal error describing the type mismatch.
2164 | VerifyParamFailHard, ND, C(Int), T
2166   A terminal version of VerifyParamFail, to be used when the compiler can
2167   statically prove that this failure will result in a fatal error rather than a
2168   type coercion.
2170 | VerifyRetCallable, ND, S(Gen), NF
2172   Verify a return type hint.
2174 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), NF
2176   Verify a return type hint.
2178 | VerifyRetFail, ND, S(PtrToGen), NF
2180   Failure to verify a return type hint.
2182 | VerifyRetFailHard, ND, S(PtrToGen), T
2184   Terminal version of VerifyRetFail, to be used when the compiler can prove
2185   that this failure will result in a fatal error.
2187 | VerifyPropCls, ND, S(Cls) S(Int) S(Cls|Nullptr) S(Obj) C(Bool), NF
2189   Verify a property type hint with AnnotType::Object against an object
2190   value. S0 is the class of the object containing the property. S1 is the slot
2191   of the property on the class. S3 is the object which is being set in the
2192   property. If S2 is not nullptr, than the type-hint refers to that Class, and
2193   S3 will be checked to see if its an instance of S2. Otherwise, the type-hint
2194   refers to a type-alias, and the alias will be resolved and checked against
2195   S3. S4 is true if this is a static property, false otherwise.
2197 | VerifyPropFail, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2199   Failure to verify a property type hint. S0 is the class of the object
2200   containing the property. S1 is the slot of the property on the class. S2 is
2201   the value which was being set in the property. S3 is true if this is a static
2202   property, false otherwise.
2204 | VerifyPropFailHard, ND, S(Cls) S(Int) S(Cell) C(Bool), T
2206   Terminal version of VerifyPropFail, to be used when the compiler can prove
2207   that this failure will result in a fatal error.
2209 | VerifyProp, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2211   Verify that S2 is compatible with the type hint for the property at slot S1
2212   on S0. S3 is true if this is a static property, false otherwise.
2214 | VerifyReifiedLocalType<id>, ND, SDArr, NF
2216   Raises a catchable type hint error if the reified generics of function
2217   parameter id does not match the type structure given on S0.
2219 | VerifyReifiedReturnType, ND, S(Cell) SDArr, NF
2221   Raises a catchable type hint error if the reified generics of S0 does not
2222   match the type structure given on S1.
2224 | RaiseHackArrParamNotice<type,id,isReturn>, ND, S(Arr) S(Func), NF
2226   Raise a HackArrCompatNotice corresponding to a parameter or return type-hint
2227   d/varray mismatch. S0 is the array being passed in. S1 is the function being
2228   called.
2230 | RaiseHackArrPropNotice<type>, ND, S(Cls) S(Arr) S(Int) C(Bool), NF
2232   Raise a HackArrCompatNotice corresponding to a property type-hint d/varray
2233   mismatch.
2235 | RaiseUninitLoc<localId>, ND, S(Str), NF
2237   Raise a notice for an uninitialized local variable.
2239 | RaiseUndefProp, ND, S(Obj) CStr, NF
2241   Raise a notice for an undefined property named S1 on the class of S0.
2243 | RaiseMissingArg<func,argc>, ND, NA, NF
2245   Raise a missing argument warning because only argc arguments were passed to
2246   function func.
2248 | RaiseTooManyArg<func,argc>, ND, NA, NF
2250   Raise a too many argument warning because argc arguments were passed to
2251   function func.
2253 | RaiseError, ND, S(Str), T
2255   Raises a fatal error with the text in S0 as its message.
2257 | RaiseWarning, ND, S(Str), NF
2259   Raises a warning with the text in S0 as its message.
2261 | RaiseNotice, ND, S(Str), NF
2263   Raises a notice with the text in S0 as its message.
2265 | RaiseArrayIndexNotice<isInOut>, ND, S(Int), NF
2267   Raises a notice that S0 is an undefined index for an array. The isInOut option
2268   indicates that the access was for an inout parameter.
2270 | RaiseArrayKeyNotice<isInOut>, ND, S(StaticStr), NF
2272   Raises a notice that S0 is an undefined key for an array. The isInOut option
2273   indicates that the access was for an inout parameter.
2275 | RaiseMissingThis, ND, S(Func), NF
2277   Raises an appropriate notice or fatal to indicate that Func was
2278   called with null $this. In most cases its a notice, but for
2279   builtins and special class methods its a fatal.
2281 | ThrowHasThisNeedStatic, ND, S(Func), T
2283   Throws a BadMethodCallException to indicate that func was called on an object
2284   but is a static method.
2286 | FatalMissingThis, ND, S(Func), T
2288   Similar to RaiseMissingThis, but for cases where we know it will fatal.
2290 | RaiseHackArrCompatNotice, ND, S(Str), NF
2292   Raises a Hack array compat notice with the text in S0 as its message.
2294 | ThrowParamRefMismatch<paramIndex>, ND, S(Func), T
2296   Throw an exception indicating that the reffiness of a parameter was
2297   incorrectly annotated at the callsite.
2299 | ThrowParamRefMismatchRange<firstBit,mask,vals>, ND, S(Func), T
2301   Throw an exception indicating that the reffiness of at least one parameter
2302   within a given range was incorrectly annotated at the callsite.
2304   See CheckRefs for meaning of firstBit, mask and vals.
2306 | RaiseForbiddenDynCall, ND, S(Func), NF
2308   Depending on the setting of the `ForbidDynamicCalls` runtime option, either
2309   raise a warning or throw an exception indicating that the func specified in
2310   S0 was called dynamically (and should not be).
2312 | RaiseForbiddenDynConstruct, ND, S(Cls), NF
2314   Depending on the setting of the `ForbidDynamicCalls` runtime option, either
2315   raise a warning or throw an exception indicating that the class specified in
2316   S0 was constructed dynamically (and should not be).
2318 | RaiseRxCallViolation, ND, S(FramePtr) S(Func), NF
2320   Depending on the setting of the `RxEnforceCalls` runtime option, either raise
2321   a warning or throw an exception indicating that the caller specified by S0
2322   was violating reactivity constraints when calling the callee specified by S1.
2324 | RaiseStrToClassNotice, ND, S(Str), NF
2326   Raise a notice if a string is implicitly converted to a class.
2328 | CheckClsReifiedGenericMismatch<cls>, ND, SVArr, NF
2330   Raises a runtime error unless whether each generic in S0 is reified or erased
2331   matches exactly to the expectations of the cls.
2333 | CheckFunReifiedGenericMismatch<func>, ND, SVArr, NF
2335   Raises a runtime error unless whether each generic in S0 is reified or erased
2336   matches exactly to the expectations of the func.
2338 | IsFunReifiedGenericsMatched<func>, D(Bool), S(FramePtr), NF
2340   Load the value of m_reifiedGenerics on the ActRec pointed to by the frame
2341   pointer S0 and does the fast path for checking whether the number of generics
2342   and whether erased versus reified parity match.
2343   If the function has soft generics or the number of generics is greater than
2344   ReifiedGenericsPtr::kMaxTagSize, returns false.
2346 | InitClsCns<className,constName>, DCns, NA, PRc
2348   Initialize the RDS entry for a constant for a class, invoking autoload if it
2349   is not defined. The initialized value is returned. This instruction may raise
2350   an undefined constant error if autoload cannot define the constant.
2352 | PrintStr,  ND, S(Str),  CRc
2354 | PrintInt,  ND, S(Int),  CRc
2356 | PrintBool, ND, S(Bool), CRc
2358   Print for various types.
2360 | ConcatIntStr, D(Str), S(Int) S(Str), PRc
2362   Concatenate S0 and S1 after converting S0 to String.
2364 | ConcatStrInt, D(Str), S(Str) S(Int), CRc|PRc
2366   Concatenate S0 and S1 after converting S1 to String.
2368 | ConcatStrStr, D(Str), S(Str) S(Str), CRc|PRc
2370   Concatenate S0 and S1.
2372 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), CRc|PRc
2374   Concatenate S0, S1, and S2.
2376 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), CRc|PRc
2378   Concatenate S0, S1, S2, and S3.
2380 | AddElemStrKey, D(Arr), S(Arr) S(Str) S(Cell), CRc|PRc
2382   Add S2 to the array S0 for the key S1, and return the resulting array.
2384 | AddElemIntKey, D(Arr), S(Arr) S(Int) S(Cell), CRc|PRc
2386   Add S2 to the array S0 for the key S1, and return the resulting array.
2388 | AddNewElem, D(Arr), S(Arr) S(Cell), CRc|PRc
2390 | AddNewElemKeyset, D(Keyset), S(Keyset) S(Cell), CRc|PRc
2392 | AddNewElemVec, D(Vec), S(Vec) S(Cell), CRc|PRc
2394   Add S1 as a new element to the array/keyset/vec S0.  (Note: S1 must actually
2395   be a subtype of InitCell for array invariants, but we can't assert this yet
2396   in the IR because many eval stack slots are not entirely typed wrt initness
2397   right now.)
2399 | DictAddElemStrKey, D(Dict), S(Dict) S(Str) S(Cell), CRc|PRc
2401   Add S2 to the dict S0 for the key S1, and return the resulting dict.
2403 | DictAddElemIntKey, D(Dict), S(Dict) S(Int) S(Cell), CRc|PRc
2405   Add S2 to the dict S0 for the key S1, and return the resulting dict.
2407 | ArrayAdd, D(Arr), S(Arr) S(Arr), CRc|PRc
2409   Has the effects of the php + operator on the two source arrays.
2411 | AKExistsArr, D(Bool), S(Arr) S(Int,Str), NF
2413   Has the effects of array_key_exists(S0, S1).
2415 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
2417   Has the effects of array_key_exists(S0, S1).
2419 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
2421   Has the effects of array_key_exists(S0, S1).
2423 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), NF
2425   Has the effects of array_key_exists(S0, S1) on an object S0. This either does
2426   collection accesses, or uses the ArrayAccess API.
2428 | GetMemoKey, DMemoKey, S(Cell), PRc
2430   Given a cell, produces a string or an int that can be used as a memoize cache
2431   key. Valid values for the input include all basic types, arrays and
2432   collections, and objects that implement IMemoizeParam. Any other type will
2433   cause GetMemoKey to throw. This op can only be used within functions marked
2434   as memoize wrappers.
2436 | GetMemoKeyScalar, DMemoKey, S(Uncounted,Str), PRc
2438   Identical to GetMemoKey but only accepts scalar types and cannot produce
2439   errors.
2441 | ArrayIdx, DArrElem, S(Arr) S(Int,Str) S(Cell), NF
2443   Checks if S0 contains the key S1, and returns the result if found. Otherwise
2444   S2 is returned.
2446 | DictIdx, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
2448   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2449   S2 is returned.
2451 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
2453   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2454   S2 is returned.
2456 | MethodExists, D(Bool), S(Cls) S(Str), NF
2458   Checks if the method named S1 exists on class S0.  S0 must be a normal class
2459   that is not abstract.
2461 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
2463   Creates a service request to bind the given target address. Returns a TCA
2464   pointing either to the service request (before the service request is
2465   satisfied) or to the native code for the given target address (once the
2466   service request is satisfied).
2468 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
2470 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
2472 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc
2474   These instructions are used to determine the target of a switch statement
2475   with target range [S1:S1 + S2), when invoked with the value S0. They call
2476   helper functions to check whether S0 is an numeric integer in the range
2477   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
2478   target of the default target, S2 + 1.
2480 | LdSSwitchDestFast, D(TCA), S(Gen), NF
2482 | LdSSwitchDestSlow, D(TCA), S(Gen), NF
2484   Load string switch destinations (two different compilation strategies).
2486 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
2487 |                                               S(StkPtr) S(FramePtr),
2488 |                                               NF
2490   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
2491   cells) and S1 are, respectively, the VM stack and frame pointers before this
2492   instruction. T is only present if the instruction pushes to the stack, in
2493   which case it is the type of the top stack element after the call. `bcOff' is
2494   the bytecode offset. `numPopped' is the number of stack cells consumed by the
2495   instruction, and `numPushed' is the number of stack cells produced by the
2496   instruction.
2498 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
2499 |                                           S(StkPtr) S(FramePtr),
2500 |                                           T
2502   Similar to InterpOne, but for instructions that may modify vmpc. This is
2503   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2504   in the context of the stub, not the InterpOneCF instruction.
2506 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), NF
2508   Returns a bool indicating whether the class, interface, or trait named by S0
2509   exists. Invokes autoload if S1 is true.
2511 | SetOpCell<op>, ND, S(LvalToCell) S(Cell), NF
2513   Performs S0 <op>= S1.
2515 | SetOpCellVerify<op>, ND, S(LvalToCell) S(Cell) S(Cls) S(Int), NF
2517   Similar to SetOpCell, but does a type-hint check of the result (before
2518   assigning to S0) using the type-hint of the property in class S2 at slot S3.
2520 | GetTime, D(Dbl), NA, NF
2522   Returns a double of the current time in seconds.
2524 | GetTimeNs, D(Int), C(Int), NF
2526   Returns the current time of the given clock id specified as clockid_t in
2527   nanoseconds as integer. This will call kernel's clock_gettime_ns() API. Note
2528   that this cannot be used for CLOCK_THREAD_CPUTIME_ID, as HHVM provides
2529   different semantics for that counter.
2531 | KillClsRefCls<slot>, ND, S(FramePtr), NF
2533   Mark the class-ref's cls slot `slot` in frame S0 as no longer containing a
2534   meaningful value. This is used to aid in memory analysis. In debugging
2535   builds, it may overwrite the slot with a poison value.
2537 | KillClsRefTS<slot>, ND, S(FramePtr), NF
2539   Mark the class-ref's reified generic slot `slot` in frame S0 as no longer
2540   containing a meaningful value. This is used to aid in memory analysis.
2541   In debugging builds, it may overwrite the slot with a poison value.
2543 15. Generators & Closures
2545 | LdClosureCtx, DCtx, S(Obj), NF
2547   Load the context from the closure object S0 into D.
2548   May only be used in S0's closure Func.
2550 | StClosureCtx, ND, S(Obj) S(Ctx,Nullptr), CRc
2552   Store the context represented by S1 into the closure object S0. S1 may be a
2553   Nullptr when there is no context (i.e. the closure is being used in a
2554   non-method).
2556 | StClosureArg<offsetBytes>, ND, S(Obj) S(Cell), CRc
2558   Store one of the closure environment arguments (i.e. from the closure's use
2559   clause) from S1 into the closure object S0.
2561 | CreateGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2563   Create a Generator object and suspend the ActRec provided by S0 into its
2564   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2565   resume address to S2 and resume offset to S3.
2567 | CreateAGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2569   Create an AsyncGenerator object and suspend the ActRec provided by S0 into its
2570   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2571   resume address to S2 and resume offset to S3.
2573 | CreateAFWH, DAllocObj,
2574 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2575 |             CRc|PRc
2577   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2578   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2579   the native resume address to S2, resume offset to S3, and mark it blocked on
2580   non-finished child S4.
2582 | CreateAFWHNoVV, DAllocObj,
2583 |                 S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2584 |                 CRc|PRc
2586   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2587   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2588   the native resume address to S2, resume offset to S3, and mark it blocked on
2589   non-finished child S4.  This version of the instruction guarantees that the
2590   VarEnv is unused.
2592 | CreateAGWH, DAllocObj,
2593 |             S(FramePtr) S(TCA,Nullptr) C(Int) S(Obj),
2594 |             CRc|PRc
2596   Create an AsyncGeneratorWaitHandle object and link it to the AsyncGenerator
2597   associated with the ActRec provided by S0.  Set the native resume address
2598   to S1, resume offset to S2, and mark it blocked on non-finished child S3.
2600 | CreateAAWH<local,count>, DAllocObj, S(FramePtr) S(Int), PRc
2602   Create an AwaitAllWaitHandle and add the count elements from frame contiguous
2603   frame locals beginning at local and extending count locals. S1 denotes the
2604   total number of non-completed waithandles. All locals must be subclasses of
2605   WaitHandle.
2607 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2609   Call c_StaticWaitHandle::CreateSucceeded.
2611 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), NF
2613   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2614   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2615   provided by S0.
2617   Injects S1 into the currently running scheduler instance and performs
2618   cross-scheduler and intra-scheduler cycle detection. Throws if the
2619   dependency cannot be established.
2621 | StArResumeAddr<offset>, ND, S(FramePtr) S(TCA), NF
2623   Store the resume address S1 into the Resumable whose ActRec is given by S0,
2624   marking the offset to resume at as `offset'.
2626 | ContEnter<spOffset,callBCOffset>, DGenIter,
2627 |                                   S(StkPtr) S(FramePtr) S(FramePtr) S(TCA),
2628 |                                   NF
2630   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2631   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2632   embedded in the Generator object, and S3 is the address to jump to. The
2633   `callBCOffset' will be stored to the m_callOff field of the ActRec in
2634   the generator.
2636 | ContPreNext, ND, S(Obj) C(Bool), B
2638   Performs operations needed for the next() method of Generator object S0.
2639   If the generator is already running or finished, or it was not started yet
2640   and the S1 check-started flag is set, the branch B is taken. Otherwise,
2641   the generator is marked as running.
2643 | ContStartedCheck, ND, S(Obj), B
2645   Checks if the Generator object S0 has started, and if not branches to
2646   block B.
2648 | ContValid, D(Bool), S(Obj), NF
2650   Return true if a generator is not done, false otherwise.
2652 | ContStarted, D(Bool), S(Obj), NF
2654   Return true if a generator has been run at least once, i.e. is not in the
2655   Created state, false otherwise.
2657 | ContArIncKey, ND, S(FramePtr), NF
2659   Special-case key update for generator, ActRec of which is S0, which
2660   increments the key of a generator if that generator's key is an Int.
2661   This will cause undefined behavior if the generator's key is not an Int.
2663 | ContArIncIdx, D(Int), S(FramePtr), NF
2665   Increment the internal index in the Generator in S0, and return the new index
2666   value.
2668 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2670   Updates the internal index of generator with S1 if necessary, i.e. if S1
2671   is larger than the index. S0 is the pointer to the embedded ActRec.
2673 | LdContActRec, D(FramePtr), S(Obj), NF
2675   Loads the Generator object's ActRec, given a pointer to the generator
2676   object in S0.
2678 | LdContResumeAddr, D(TCA|Nullptr), S(Obj), NF
2680   Load the resume addr from the Generator in S0.
2682 | StContArState<state>, ND, S(FramePtr), NF
2684   Change the state of the Generator object which has frame pointer S0.
2686 | LdContArValue, DParam(Cell), S(FramePtr), PRc
2688   Loads 'value' from the Generator object ActRec of which is S0.
2690 | StContArValue, ND, S(FramePtr) S(Cell), CRc
2692   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2693   new value.
2695 | LdContArKey, DParam(Cell), S(FramePtr), PRc
2697   Loads 'key' from the Generator object ActRec of which is S0.
2699 | StContArKey, ND, S(FramePtr) S(Gen), CRc
2701   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2702   new value.
2704 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2706   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2707   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2709 | LdWHState, D(Int), S(Obj), NF
2711   Loads the state of the WaitHandle in S0, which is a value from the wait
2712   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2713   not a WaitHandle.
2715 | LdWHResult, DParam(Gen), S(Obj), NF
2717   Loads the result of the WaitHandle in S0. This instruction has undefined
2718   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2720 | LdWHNotDone, D(Int), S(Obj), NF
2722   Returns 1 if S0 is not finished, and 0 if S0 is finished.
2724 | CountWHNotDone<local,count>, D(Int), S(FramePtr), B
2726   Returns the number of unfinished awaitables contained in the contiguous
2727   locals beginning at local and extending count, skipping all nulls. A branch
2728   is taken if a non-Awaitable non-null value is encountered.
2730 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2732   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2733   AsyncFunctionWaitHandle object in S0.
2736 16. Debugging, instrumentation, and profiling
2738 | IncStat, ND, C(Int), NF
2740   Increment stat counter. S0 is the implementation defined stat counter index.
2742 | IncProfCounter<TransID>, ND, NA, NF
2744   Increment the profiling counter associated with translation TransID.
2746 | DbgAssertRefCount<AssertReason>, ND, S(Gen,TCtx), NF
2748   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2749   its count is implausible then execute a hardware trap instruction.
2751 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2753   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2754   start of each region, to emit some sanity checking code.
2756 | DbgAssertARFunc<offset>, ND, S(StkPtr) S(Func), NF
2758   Assert that S1 is the function in the ActRec given by s0+offset. If the
2759   assertion fails, execution is aborted via a hardware exception.
2761 | DbgAssertFunc, ND, S(FramePtr) S(Func), NF
2763   Assert that S1 is the current function in Frame S0. If the assertion fails,
2764   execution is aborted via a hardware exception.
2766 | RBTraceEntry, ND, NA, NF
2768 | RBTraceMsg, ND, NA, NF
2770   Ring buffer tracing.
2772 | ZeroErrorLevel, D(Int), NA, NF
2774 | RestoreErrorLevel, ND, S(Int), NF
2776   Helper instructions for fast implementation of the PHP error silencing
2777   operator (@foo()).
2780 17. Iterators
2782 | IterInit<IterData>,   D(Bool), S(ArrLike,Obj) S(FramePtr), CRc
2784 | IterInitK<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), CRc
2786 | LIterInit<IterData>,  D(Bool), S(ArrLike) S(FramePtr), NF
2788 | LIterInitK<IterData>, D(Bool), S(ArrLike) S(FramePtr), NF
2790   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2791   the index of the iterator variable, keyId and valId are indices of local
2792   variables.
2794   Initializes the iterator variable whose index is given by iterId.
2795   This instruction creates the appropriate iterator for the array or object that
2796   S0 references, and rewinds the new iterator to its start. S0 points to the
2797   stack frame containing the iterator and local variables with the indices
2798   iterId, keyId and valId.
2800   If the new iterator is at its end (i.e., has no elements to iterate over),
2801   this instruction decrements the refcount of S0 and returns false; otheriwse,
2802   it stores a reference to S0 in the new iterator and returns true. If the
2803   iterator is not at its end, then this instruction stores the iterator's first
2804   value (and key) into the local variable with index valId (and keyId,
2805   respectively).
2807   The IterInit and IterInitK instructions always copy the array element by
2808   value.
2810   The LIter variations only accept arrays and do not take ownership of their
2811   base. Instead the base is provided on each operation on the iterator. This
2812   avoids having to raise the ref-count of the base (in situations where this is
2813   safe).
2815   This instruction has the ConsumesRC property because it either decrements the
2816   reference count of S0 or stores a reference to S0 into the new iterator.
2818 | IterNext<IterData>,   D(Bool), S(FramePtr), NF
2820 | IterNextK<IterData>,  D(Bool), S(FramePtr), NF
2822 | LIterNext<IterData>,  D(Bool), S(ArrLike) S(FramePtr), NF
2824 | LIterNextK<IterData>, D(Bool), S(ArrLike) S(FramePtr), NF
2826   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2827   the index of the iterator variable, keyId and valId are indices of local
2828   variables.  S0 points to the stack frame containing the iterator and local
2829   variables with the indices iterId, keyId and valId.
2831   Advances the iterator variable whose index is given by iterId.
2833   If the iterator has reached the end, this instruction frees the iterator
2834   variable and returns false; otherwise, it returns true. If the iterator has
2835   not reached its end, then this instruction stores the iterator's next value
2836   (and key) into the local variable with index valId (and keyId, respectively).
2838   The IterInit and IterInitK instructions always copy the array element by
2839   value.
2841 | IterFree,  ND, S(FramePtr), NF
2843   Free the iterator variable whose index is given by S1 in the stack frame
2844   pointed to by S0.
2847 18. Member instruction support
2849 | LdMIStateAddr, D(PtrToMISGen), C(Int), NF
2851   Load an MInstrState address. Returns a pointer to offset S0 within the
2852   current MInstrState.
2854 | LdMBase, DParam(LvalToGen), NA, NF
2856   Load the current value of the member base register.
2858 | StMBase, ND, S(LvalToGen), NF
2860   Store a new value to the member base register. It is illegal for any
2861   instruction other than StMBase or InterpOne (when interpreting a member
2862   instruction) to modify the member base register.
2864 | LdMIPropStateAddr, D(MIPropSPtr), NA, NF
2866   Load an address to the current MInstrPropState.
2868 | StMIPropState, ND, S(Cls|Nullptr) S(Int) C(Bool), NF
2870   Write to the current MInstrPropState.
2872 | FinishMemberOp, ND, NA, NF
2874   Mark the end of a member operation. This has no effect at runtime but exists
2875   to provide information for certain optimizations.
2877 All of the remaining opcodes in this section are simple wrappers around helper
2878 functions (specified in S0) to perform the corresponding vector operation. If
2879 S1 is a ConstCls it represents the context class for the operation.
2881 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2882 opcode, which almost always pushes its first stack input or a StaticStr as its
2883 stack result. The combinations of input types that cause SetM to push anything
2884 other than those two values are vanishingly rare in correct PHP programs, so
2885 these three instructions have been optimized for the common cases. SetNewElem
2886 and SetProp have no destination, allowing the compiler to predict that the
2887 SetM's output will be the same as its input (and optimize accordingly). If that
2888 turns out to not be the case at runtime, the instruction will throw an
2889 InvalidSetMException. The exception will hold a Cell containing the value the
2890 SetM should push on the stack instead of its input value. The runtime is
2891 responsible for catching this exception, finishing execution of the SetM
2892 instruction, pushing the value from the exception on the stack, and proceeding
2893 as appropriate (most likely with a side exit to the next bytecode instruction,
2894 since it has pushed an unexpected type onto the stack).
2896 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2897 characters within strings. When given a string base and a valid offset, SetElem
2898 returns a string representation of the newly inserted character. In all other
2899 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2900 exception when it detects invalid input types, or when trying to set a string
2901 offset that would grow the string beyond the maximum supported size.
2903 The input types that will cause the errors described above are listed here:
2905 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2906            Bool<false>.
2907 SetElem has the same base constraint as SetNewElem. In addition, the key must
2908         not be a subtype of {Arr|Obj}.
2909 SetProp will fail if the base is not a subtype of {Obj|Null}.
2911 Any instructions that take a pointer to an MInstrState struct use the various
2912 fields of that struct for holding intermediate values.
2914 | BaseG, D(LvalToRMembCell), S(Str), NF
2916   Get a base from global named S0.
2918   NB: BaseG returns either a PtrToGblGen, OR a pointer to a ref that is rooted
2919   in a GblGen.  (I.e. the unbox happens in the C++ helper that this instruction
2920   calls.)  If it is not a defining BaseG it can also return the
2921   init_null_variant, so for now it returns a PtrToRMembCell.
2923 | PropX, D(LvalToMembGen), S(Obj,LvalToGen) S(Cell) S(PtrToMISGen), NF
2925   Lookup intermediate property in S0, with key S1.
2927 | PropQ, D(LvalToMembGen), S(Obj,LvalToGen) S(StaticStr) S(PtrToMISGen), NF
2929   A nullsafe version of PropX, returns null if the base S0 is null.
2931 | PropDX, D(LvalToMembGen), S(Obj,LvalToGen) S(Cell) S(PtrToMISGen) S(MIPropSPtr,Nullptr), MProp
2933   Like PropX, but used for intermediate element lookups that may modify the
2934   base.
2936 | CGetProp, D(Cell), S(Obj,LvalToGen) S(Cell), PRc
2938   Get property with key S1 from S0.
2940 | CGetPropQ, D(Cell), S(Obj,LvalToGen) S(StaticStr), PRc
2942   A nullsafe version of CGetProp, returns null if the base S0 is null.
2944 | VGetProp, D(BoxedInitCell), S(Obj,LvalToGen) S(Cell) S(MIPropSPtr,Nullptr), MProp|PRc
2946   Get property with key S1 from base S0 as a reference.
2948 | SetProp, ND, S(Obj,LvalToGen) S(Cell) S(Cell) S(MIPropSPtr,Nullptr), MProp
2950   Set property with key S1 in S0 to S2.
2952 | UnsetProp, ND, S(Obj,LvalToGen) S(Cell), NF
2954   Unset an object property.
2956 | SetOpProp<op>, D(Cell),
2957 |                S(Obj,LvalToGen) S(Cell) S(Cell) S(MIPropSPtr,Nullptr),
2958 |                MProp|PRc
2960   Set op propery with key S1 in base S0, using S2 as the right hand side.
2962 | IncDecProp<op>, D(Cell),
2963 |                 S(Obj,LvalToGen) S(Cell) S(MIPropSPtr,Nullptr),
2964 |                 MProp|PRc
2966   Increment/decrement property with key S1 in base S0.
2968 | EmptyProp, D(Bool), S(Obj,LvalToGen) S(Cell), NF
2970   Returns true iff the property with key S1 in base S0 is empty.
2972 | IssetProp, D(Bool), S(Obj,LvalToGen) S(Cell), NF
2974   Returns true iff the property with key S1 in base S0 is set.
2976 | ElemX, D(LvalToMembGen), S(LvalToGen) S(Cell) S(PtrToMISGen), NF
2978   Get intermediate element with key S1 from base S0. The base will not be
2979   modified.
2981 | ProfileMixedArrayOffset, ND, S(Arr) S(Int,Str), NF
2983   Profile the offset of the element keyed by S1 in S0.
2985 | CheckMixedArrayOffset<pos>, ND, S(AK(Mixed)) S(Int,Str), B
2987   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2988   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2989   fail, branch to B.  This check is allowed to have false negatives, in the
2990   case of int-like strings.
2992 | CheckArrayCOW, ND, S(ArrLike), B
2994   Check that S0 has a refcount of exactly 1; if not, branch to B.
2996 | ProfileDictOffset, ND, S(Dict) S(Int,Str), NF
2998   Profile the offset of the element keyed by S1 in S0.
3000 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
3002   Check that `pos' is within the usage bounds of S0 (including tombstones), and
3003   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
3004   fail, branch to B.  This check is allowed to have false negatives.
3006 | ProfileKeysetOffset, ND, S(Keyset) S(Int,Str), NF
3008   Profile the offset of the element keyed by S1 in S0.
3010 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
3012   Check that `pos' is within the usage bounds of S0 (including tombstones), and
3013   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
3014   fail, branch to B.  This check is allowed to have false negatives.
3016 | ElemArrayX<M>, D(LvalToMembGen), S(Arr) S(Int,Str), NF
3018 | ElemArrayD<T>, D(LvalToElemGen), S(LvalToGen) S(Int,Str), MElem
3020 | ElemArrayU<T>, D(LvalToMembGen), S(LvalToGen) S(Int,Str), MElem
3022   Similar to ElemX, but the base S0 is an array and the key S1 is an int/str.
3023   ElemArrayD is for Define member instrs, ElemArrayU is for Unset, and
3024   ElemArrayX is for InOut, Warn, and None instrs (where the mode is M).
3026   ElemArray{D,U} both take a LvalToGen for the base operand, but expect it to be
3027   a LvalToArr or LvalToBoxedArr.  T is the type of the base array.
3029 | ElemMixedArrayK<pos>, D(LvalToElemGen), S(AK(Mixed)) S(Int,Str), NF
3031   Like ElemArray, but the element for S1 is at a known position `pos' in S0.
3033 | ElemVecD<T>, D(LvalToElemCell), S(LvalToGen) S(Int), MElem
3035 | ElemVecU<T>, D(LvalToMembCell), S(LvalToGen) S(Int), MElem
3037   Similar to ElemX, but the base S0 is a vec and the key S1 is an int. ElemVecD
3038   is for Define member instrs and ElemVecU is for Unset. (Other variations can
3039   be implemented without special IR instructions).
3041   ElemVec{D,U} both take a LvalToGen for the base operand, but expect it to be a
3042   LvalToVec or LvalToBoxedVec. T is the type of the base vec.
3044 | ElemDictX<M>, D(LvalToMembCell), S(Dict) S(Int,Str), NF
3046 | ElemDictD<T>, D(LvalToElemCell), S(LvalToGen) S(Int,Str), MElem
3048 | ElemDictU<T>, D(LvalToMembCell), S(LvalToGen) S(Int,Str), MElem
3050   Similar to ElemX, but the base S0 is a dict and the key S1 is an int/str.
3051   ElemDictD is for Define member instrs, ElemDictU is for Unset, and
3052   ElemDictX is for InOut, Warn, and None instrs (where the mode is M).
3054   ElemDict{D,U} both take a LvalToGen for the base operand, but expect it to be
3055   a LvalToDict or LvalToBoxedDict.  T is the type of the base array.
3057 | ElemDictK<pos>, D(LvalToElemCell), S(Dict) S(Int,Str), NF
3059   Like ElemDict, but the element for S1 is at a known position `pos' in S0.
3061 | ElemKeysetX<M>, D(LvalToMembCell), S(Keyset) S(Int,Str), NF
3063 | ElemKeysetU<T>, D(LvalToMembCell), S(LvalToGen) S(Int,Str), MElem
3065   Similar to ElemX, but the base S0 is a keyset and the key S1 is an int/str.
3066   ElemKeysetU is for Unset instrs and ElemKeysetX is for InOut, Warn and None
3067   instrs (where the mode is M).
3069   ElemKeysetU both take a LvalToGen for the base operand, but expect it to be
3070   a LvalToKeyset or LvalToBoxedKeyset.  T is the type of the base array.
3072 | ElemKeysetK<pos>, D(LvalToElemCell), S(Keyset) S(Int,Str), NF
3074   Like ElemKeyset, but the element for S1 is at a known position `pos' in S0.
3076 | ElemDX, D(LvalToMembGen), S(LvalToGen) S(Cell) S(PtrToMISGen) S(MIPropSPtr,Nullptr), MElem
3078   Like ElemX, but used for intermediate element lookups that may modify the
3079   base.
3081 | ElemUX, D(LvalToMembGen), S(LvalToGen) S(Cell) S(PtrToMISGen), MElem
3083   Like ElemX, but used for intermediate element lookups that may modify the
3084   base as part of an unset operation.
3086 | ArrayGet, DArrElem, S(Arr) S(Int,Str), NF
3088   Get element with key S1 from base S0.
3090 | MixedArrayGetK<pos>, DArrElem, S(AK(Mixed)) S(Int,Str), NF
3092   Like ArrayGet, but the element for S1 is at a known position `pos' in S0.
3094 | DictGet, DDictElem, S(Dict) S(Int,Str), NF
3096   Get element with key S1 from base S0, throwing if the element is not present.
3098 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
3100   Get element with key S1 from base S0, returning null if the element is not
3101   present.
3103 | DictGetK<pos>, DDictElem, S(Dict) S(Int,Str), NF
3105   Like DictGet, but the element for S1 is at a known position `pos' in S0.
3107 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), NF
3109   Get element with key S1 from base S0, throwing if the element is not present.
3111 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
3113   Get element with key S1 from base S0, returning null if the element is not
3114   present.
3116 | KeysetGetK<pos>, DKeysetElem, S(Keyset) S(Int,Str), NF
3118   Like KeysetGet, but the element for S1 is at a known position `pos' in S0.
3120 | StringGet, D(StaticStr), S(Str) S(Int), PRc
3122   Get string representing character at position S1 from base string S0.  Raises
3123   a notice if the position is out of bounds.
3125 | MapGet, D(Cell), S(Obj) S(Int,Str), PRc
3127   Get element with key S1 from base S0.
3129 | CGetElem, D(Cell), S(LvalToGen) S(Cell), PRc
3131   Get element with key S1 from S0.
3133 | MemoGetStaticValue<func,T>, DParam(InitCell), NA, B
3135   Get the memo value associated with the static function "func". If the value
3136   is not present, branch. The returned value is not inc-reffed. This op can
3137   only be used inside a memoize wrapper.
3139 | MemoGetStaticCache<func,keys,T>, DParam(InitCell), S(FramePtr,StkPtr), B
3141   Perform a lookup on the memo cache associated with the static function
3142   "func". The keys for the lookup are read from the locals on the frame pointed
3143   to by S0 (which must be ints or strings). If the lookup fails, branch. The
3144   returned value is not inc-reffed. This op can only be used inside a memoize
3145   wrapper.
3147 | MemoGetLSBValue<func,T>, DParam(InitCell), S(Cls), B
3149   Get the memo value associated with the static function "func" and late static
3150   bound class S0. If the value is not present, branch. The returned value is not
3151   inc-reffed. This op can only be used inside a memoize wrapper.
3153 | MemoGetLSBCache<func,keys,T>, DParam(InitCell), S(FramePtr,StkPtr) S(Cls), B
3155   Perform a lookup on the memo cache associated with the static function
3156   "func" and late static bound class S1. The keys for the lookup are read from
3157   the locals on the frame pointed to by S0 (which must be ints or strings). If
3158   the lookup fails, branch. The returned value is not inc-reffed. This op can
3159   only be used inside a memoize wrapper.
3161 | MemoGetInstanceValue<slot,func,T>, DParam(InitCell), S(Obj), B
3163   Get the memo value at the specified memo slot on S0. If the value is not
3164   present, branch. The returned value is not inc-reffed. This op can only be
3165   used inside a memoize wrapper.
3167 | MemoGetInstanceCache<func,keys,T>, DParam(InitCell), S(FramePtr,StkPtr) S(Obj), B
3169   Perform a lookup on the memo cache at the specified memo slot on S1. The keys
3170   for the lookup are read from the locals on the frame pointed to by S0 (which
3171   must be ints or strings). If the lookup fails, branch. The returned value is
3172   not inc-reffed. This op can only be used inside a memoize wrapper.
3174 | MemoSetStaticValue<func>, ND, S(InitCell), NF
3176   Set S0 as the memo value associated with the static function "func". Store
3177   the value, overwriting any previous value, with appropriate ref-count
3178   manipulations. This op can only be used inside a memoize wrapper.
3180 | MemoSetStaticCache<func,keys>, ND, S(FramePtr,StkPtr) S(InitCell), NF
3182   Store S1 in the memo cache associated with the static function "func". The
3183   keys for the lookup are read from the locals on the frame pointed to be S0
3184   (which must be ints or strings). Store the value, overwriting any previous
3185   value, with appropriate ref-count manipulations. This op can only be used
3186   inside a memoize wrapper.
3188 | MemoSetLSBValue<func>, ND, S(InitCell) S(Cls), NF
3190   Set S0 as the memo value associated with the static function "func" and
3191   late static bound class S1. Store the value, overwriting any previous
3192   value, with appropriate ref-count manipulations. This op can only be used
3193   inside a memoize wrapper.
3195 | MemoSetLSBCache<func,keys>, ND, S(FramePtr,StkPtr) S(Cls) S(InitCell), NF
3197   Store S2 in the memo cache associated with the static function "func" and
3198   late static bound class S1. The keys for the lookup are read from the
3199   locals on the frame pointed to be S0 (which must be ints or strings).
3200   Store the value, overwriting any previous value, with appropriate
3201   ref-count manipulations. This op can only be used inside a memoize wrapper.
3203 | MemoSetInstanceValue<slot,func>, ND, S(Obj) S(InitCell), NF
3205   Set S2 as the memo value at the specified memo slot on S1. Store the value,
3206   overwriting any previous value, with appropriate ref-count
3207   manipulations. This op can only be used inside a memoize wrapper.
3209 | MemoSetInstanceCache<slot,func,keys>, ND, S(FramePtr,StkPtr) S(Obj) S(InitCell), NF
3211   Store S2 in the memo cache at the specified memo slot on S1. Store the value,
3212   overwriting any previous value, with appropriate ref-count
3213   manipulations. This op can only be used inside a memoize wrapper.
3215 | InitObjMemoSlots<class>, ND, S(Obj), NF
3217   Initialize the memoization instance slots for object S0 of the given class.
3219 | ArraySet, D(Arr), S(Arr) S(Int,Str) S(Cell), PRc|CRc
3221   Set element with key S1 in S0 to S2. The dest will be a new Array that should
3222   replace S0.
3224 | ArraySetRef, ND, S(Arr) S(Int,Str) S(Cell) S(BoxedCell), CRc
3226   Like ArraySet, but for binding operations on the array. S3 must point to a
3227   RefData with an array type when this instruction is executed, and it must be
3228   the same array that is in S0.
3230 | VecSet, D(Vec), S(Vec) S(Int) S(Cell), PRc|CRc
3232   Set element with key S1 in S0 to S2. The dest will be a new Vec that should
3233   replace S0.
3235 | VecSetRef, ND, S(Vec) S(Int) S(Cell) S(BoxedCell), CRc
3237   Like VecSet, but for binding operations on the vec. S3 must point to a
3238   RefData with a vec type when this instruction is executed, and it must be the
3239   same vec that is in S0.
3241 | DictSet, D(Dict), S(Dict) S(Int,Str) S(Cell), PRc|CRc
3243   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
3244   replace S0.
3246 | DictSetRef, ND, S(Dict) S(Int,Str) S(Cell) S(BoxedCell), CRc
3248   Like DictSet, but for binding operations on the dict. S3 must point to a
3249   RefData with a vec type when this instruction is executed, and it must be the
3250   same dict that is in S0.
3252 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), NF
3254   Set element with key S1 in S0 to S2.
3256 | VectorSet, ND, S(Obj) S(Int,Str) S(Cell), NF
3258   Set element with key S1 in S0 to S2.
3260 | SetElem, DSetElem, S(LvalToGen) S(Cell) S(Cell) S(MIPropSPtr,Nullptr), MElem
3262   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
3263   case, where the logical result of the hhbc SetM is its right hand side. In
3264   the case of string bases, the SetM returns a new string containing the newly
3265   inserted character. So the return value of this instruction is Nullptr unless
3266   SetM needed to return a static string.
3268   Furthermore, in the case of "invalid offsets", SetElem may throw an
3269   InvalidSetMException (see discussion above).
3271 | SetRange, ND, S(LvalToGen) S(Int) S(Cell) S(Int) S(Int), MElem
3273 | SetRangeRev, ND, S(LvalToGen) S(Int) S(Cell) S(Int) S(Int), MElem
3275   Perform a range set or reverse range set operation, with the same arguments
3276   and semantics as the RangeSet bytecode instruction.
3278 | UnsetElem, ND, S(LvalToGen) S(Cell), MElem
3280   Unsets the element at key S1 in the base S0.
3282 | SetOpElem<op>, D(Cell),
3283 |                S(LvalToGen) S(Cell) S(Cell) S(MIPropSPtr,Nullptr),
3284 |                MElem|PRc
3286   Set op elem with key S1 in base S0, using S2 as the right hand side.
3288 | IncDecElem, D(Cell), S(LvalToGen) S(Cell) S(MIPropSPtr,Nullptr), MElem|PRc
3290   Increment/decrement element with key S1 in base S0.
3292 | SetNewElem, ND, S(LvalToGen) S(Cell) S(MIPropSPtr,Nullptr), MElem
3294   Append the value in S1 to S0.
3296 | SetNewElemArray, ND, S(LvalToGen) S(Cell), MElem
3298   Append the value in S1 to S0, where S0 must be a pointer to a array.
3300 | SetNewElemVec, ND, S(LvalToGen) S(Cell), MElem
3302   Append the value in S1 to S0, where S0 must be a pointer to a vec.
3304 | SetNewElemKeyset, ND, S(LvalToGen) S(Int,Str), MElem
3306   Append the value in S1 to S0, where S0 must be a pointer to a keyset.
3308 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), NF
3310   Returns true iff the element at key S1 in the base S0 is set.
3312 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
3314   Returns true iff the element at key S1 in the base S0 is set.
3316 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
3318   Returns true iff the element at key S1 in the base S0 is set.
3320 | StringIsset, D(Bool), S(Str) S(Int), NF
3322   Returns true iff the string S0 has a character at position S1.
3324 | VectorIsset, D(Bool), S(Obj) S(Int), NF
3326   Returns true iff the element at key S1 in the base S0 is set.
3328 | PairIsset, D(Bool), S(Obj) S(Int), NF
3330   Returns true iff the element at key S1 in the base S0 is set.
3332 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
3334   Returns true iff the element at key S1 in the base S0 is set.
3336 | IssetElem, D(Bool), S(LvalToGen) S(Cell), NF
3338   Returns true iff the element at key S1 in S0 is set.
3340 | EmptyElem, D(Bool), S(LvalToGen) S(Cell), NF
3342   Returns true iff the element at key S1 in S0 is set and not equal (as defined
3343   by the hhbc Eq instruction) to false.
3345 | DictEmptyElem, D(Bool), S(Dict) S(Int,Str), NF
3347   Like EmptyElem, but specialized for dicts.
3349 | KeysetEmptyElem, D(Bool), S(Keyset) S(Int,Str), NF
3351   Like EmptyElem, but specialized for dicts.
3353 | CheckRange, D(Bool), S(Int) S(Int), NF
3355   Returns true iff S0 is in the range [0, S1).
3357 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Gen), T
3359   Throws an OutOfBoundsException corresponding to an access of S0 with the key
3360   S1.
3362 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Gen), T
3364   Throws an InvalidArgumentException corresponding to an access of S0 with the
3365   key S1, which has a type invalid for that array.
3367 | ThrowInvalidOperation, ND, S(Str), T
3369   Throws an InvalidOperationException with a message indicating S0.
3371 | ThrowArithmeticError, ND, S(Str), T
3373   Throws an ArithmeticError with a message indicating S0.
3375 | ThrowDivisionByZeroError, ND, S(Str), T
3377   Throws a DivisionByZeroError with a message indicating S0.
3379 | ThrowDivisionByZeroException, ND, NA, T
3381   Throws a DivisionByZeroException.
3383 | ThrowLateInitPropError, ND, S(Cls) S(Str) S(Bool), T
3385   Throws an InvalidOperationException indicating an access of a unset LateInit
3386   property. S0 is the class the property was declared on. S1 is the property
3387   name. S2 is true if its a static property, false otherwise.
3389 | ProfileArrayKind, ND, S(Arr), NF
3391   Profile the array kind of S0.
3393 | ProfileType, ND, S(Gen), NF
3395   Profile the type of S0.
3397 | ProfileMethod<rdsHandle,spOff>, ND, S(StkPtr) S(Cls,Nullptr), NF
3399   Profile the Func in the ActRec that was just pushed onto the stack.
3401 | ProfileFunc<rdsHandle,spOff>, ND, S(StkPtr), NF
3403   Profile the Func in the ActRec that was just pushed onto the stack.
3405 | CheckPackedArrayDataBounds, ND, S(AK(Packed),Vec) S(Int), B
3407   Checks that the index in S1 is within the bounds of the packed array or
3408   vector array in S0. Branches to B if the index is out of bounds.
3410 | LdPackedArrayDataElemAddr<T>, DParam(LvalToElemGen), S(AK(Packed),Vec) S(Int), NF
3412   Loads the address of the element at index S1 of the packed array or vec array
3413   in S0. This instruction assumes the array actually contains an element at
3414   that offset (IE, the array has the proper length).
3416 | ReservePackedArrayDataNewElem, D(Int), S(AK(Packed),Vec), B
3418   If there is room in the packed or vec array (which is assumed to be mutable),
3419   increments the array size and returns the index of the new last element
3420   (which you must initialize); else jumps to the taken branch.
3422 | LdPackedElem, DArrElem, S(AK(Packed)) S(Int), NF
3424   Loads the element of the packed array in S0 at offset S1. This instruction
3425   assumes that the vec actually contains an element at that offset (IE, the
3426   array has the proper length).
3428 | LdVecElem, DVecElem, S(Vec) S(Int), NF
3430   Loads the element of the vec array in S0 at offset S1. This instruction
3431   assumes that the vec actually contains an element at that offset (IE, the vec
3432   has the proper length).
3434 | LdVectorSize, D(Int), S(Obj), NF
3436   Returns the size of the given Vector collection in S0.
3438 | ColIsEmpty, D(Bool), S(Obj), NF
3440 | ColIsNEmpty, D(Bool), S(Obj), NF
3442   Returns whether a collection instance is empty or not.  S0 must be known to
3443   be an instance of a collection class at compile time.
3446 | VecFirst, DVecFirstElem, S(Vec,AK(Packed)), NF
3448   Returns the first value from the packed or vec array in S0.
3449   If the array is empty, it will return NULL.
3451 | VecLast, DVecLastElem, S(Vec,AK(Packed)), NF
3453   Returns the last value from the packed or vec array in S0.
3454   If the array is empty, it will return NULL.
3456 | DictFirst, DDictFirstElem, S(Dict,AK(Mixed)), NF
3458   Returns the first value from the mixed or dict array in S0.
3459   If the array is empty, it will return NULL.
3461 | DictLast, DDictLastElem, S(Dict,AK(Mixed)), NF
3463   Returns the last value from the mixed or dict array in S0.
3464   If the array is empty, it will return NULL.
3466 | DictFirstKey, DDictFirstKey, S(Dict,AK(Mixed)), NF
3468   Returns the first key from the mixed or dict array in S0.
3469   If the array is empty, it will return NULL.
3471 | DictLastKey, DDictLastKey, S(Dict,AK(Mixed)), NF
3473   Returns the last key from the mixed or dict array in S0.
3474   If the array is empty, it will return NULL.
3476 | KeysetFirst, DKeysetFirstElem, S(Keyset), NF
3478   Returns the first value(key) from the keyset in S0.
3479   If the array is empty, it will return NULL.
3481 | KeysetLast, DKeysetLastElem, S(Keyset), NF
3483   Returns the first value(key) from the keyset in S0.
3484   If the array is empty, it will return NULL.
3487 19. Exception/unwinding support
3489 | BeginCatch, ND, NA, NF
3491   Marks the beginning of a catch region. Exact behavior is implementation and
3492   architecture specific.
3494 | EndCatch<spOffset>, ND, S(FramePtr) S(StkPtr), T
3496   Marks the end of a catch region and returns control to the unwinder.  The
3497   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
3498   the vm stack pointer, however the stack pointer is not actually adjusted
3499   before this instruction returns control to the unwinder.  The unwinder
3500   instead relies on fixup map information to find the appropriate stack
3501   pointers.  Instead it's part of this instruction to facilitate assertions and
3502   memory effect analysis.
3504 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
3506   Branches to B if the currently executing catch region should return control
3507   to the unwinder rather than side exiting.  Used to control behavior in catch
3508   traces for the InvalidSetMException and TVCoercionException situations.
3510 | LdUnwinderValue<T>, DParam(Cell), NA, PRc
3512   Loads the value contained by the current unwinder exception.
3515 20. Function prologues
3517 | EnterFrame, ND, S(FramePtr), NF
3519   Stash the return address of the call in m_savedRip.
3521 | CheckStackOverflow, ND, S(FramePtr), NF
3523   Check if the stack depth has exceeded its limit.  If it has, jump to the
3524   stack overflow helper stub, which will throw.
3526 | InitExtraArgs<func,argc>, ND, S(FramePtr), NF
3528   Set up the ExtraArgs struct on the live ActRec.  If extra args are present
3529   and need to be discarded, they will be decref'd and may re-enter to run
3530   destructors.
3532 | InitCtx, ND, S(FramePtr) S(Ctx,Nullptr), CRc
3534   Store S1 to the m_this/m_cls field in the frame pointer S0.
3536   If InitCtx appears in an IR unit, it must dominate all occurrences of LdCtx
3537   and LdCctx with the same FramePtr.
3539 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), NF
3541   Test the implementation-specific surprise flags.  If they're nonzero, call
3542   the function enter helper.
3544 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), NF
3546   Test surprise flags and stack overflow at the same time.
3548 | CheckARMagicFlag, ND, S(FramePtr), B
3550   If the MagicDispatch flags on the ActRec pointed to by the frame pointer S0
3551   are not set, branch to block B.
3553 | LdARNumArgsAndFlags, D(Int), S(FramePtr), NF
3555   Load the value of m_numArgsAndFlags on the ActRec pointed to by the frame
3556   pointer S0.
3558 | StARNumArgsAndFlags, ND, S(FramePtr) S(Int), NF
3560   Store S1 to m_numArgsAndFlags on the ActRec pointed to by the frame pointer
3561   S0.
3563 | LdARInvName, D(Str), S(FramePtr), NF
3565   Load the value of m_invName off the ActRec pointed to by the frame pointer S0.
3566   The compiler should generate this only if it knows that m_invName is a
3567   StringData* (rather than, e.g., a VarEnv*).
3569 | StARInvName, ND, S(FramePtr) S(Str,Nullptr), CRc
3571   Store S1 to m_invName on the ActRec pointed to by the frame pointer S0.
3573 | PackMagicArgs, DVArr, S(FramePtr), PRc
3575   Call PackedArray::MakeVArray() with the value of numArgs() on the ActRec
3576   pointed to by the frame pointer S0 as the first argument, and the pointer to
3577   the first parameter in the frame as the second argument.
3579 | LdTVAux<ValidBits>, D(Int), S(Gen), NF
3581   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
3582   specifying which bits are allowed to be set.  The runtime may ignore it.
3584   Note that when we pass TypedValues around in registers, we usually use a byte
3585   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
3586   when we know that S0's m_type and m_aux were both materialized into the same
3587   64-bit register.
3589 | LdARReifiedGenerics, DVArr, S(FramePtr), NF
3591   Load the value of m_reifiedGenerics on the ActRec pointed to by the frame
3592   pointer S0.
3594 | KillARReifiedGenerics, ND, S(FramePtr), NF
3596   Mark the ActRec's m_reifiedGenerics pointer in frame S0 as no longer
3597   containing a meaningful value. This can used to aid in memory analysis.
3598   In debugging builds, it may overwrite the pointer with a poison value.
3600 /* Local Variables: */
3601 /* fill-column: 79 */
3602 /* End: */
3603 vim:textwidth=80