Differentiate consumesReference and movesReference
[hiphop-php.git] / hphp / doc / ir.specification
blob53b230ef59a451b76e06bb9a80b5db269f81bebb
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 Er (MayRaiseError)
125   The instruction may raise an error, and must have an edge to a catch block.
127 PRc (ProducesRC)
129   The instruction produces a value with an unconsumed reference that must be
130   consumed, either by DecRefing it or storing it somewhere in memory.
132 CRc (ConsumesRC)
134   The instruction consumes a reference to one or more of its sources, either by
135   decreasing its refcount or storing the reference to memory.
137 T (Terminal)
139   The instruction has no next instruction; it either jumps, returns, or throws.
141 B (Branch)
143   The instruction has a (sometimes optional) taken edge. Instructions that are
144   conditional branches (i.e. a Branch that is not Terminal) will also have a
145   next edge.
147 P (Passthrough)
149   The value of the instruction's dest is the same as one of its inputs; it
150   differs only in the type of the variable, or some other property that doesn't
151   affect the value of the variable itself.
153 MProp (MInstrProp)
155   The instruction may affect the type and/or value of its base operand,
156   operating on object properties.
158 MElem (MInstrElem)
160   The instruction may affect the type and/or value of its base operand,
161   operating on array elements.
164 Instruction set
165 ---------------
167 1. Checks and Asserts
169 Note: Instructions that check boxed types only check that the operand is boxed,
170 and they ignore the type of the value inside the box (the inner type). The
171 inner type is normally checked when the value within the box is about to be
172 loaded, using a separate CheckRefInner instruction.
174 | CheckType<T>, DRefineS(0), S(Gen,Cls), B|P
176   Check that the type of the src S0 is T, and if so copy it to D, and
177   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
178   this means S0 still /may/ be a subtype of T in block B in some circumstances.
180   Specifically, subtypes of Type::Static may not be checked precisely,
181   depending on the type of the source.  This means the instruction may take the
182   branch in some circumstances even when S0 is a subtype of T, if T has a
183   non-empty intersection with Type::Static.
185   Also note that many types are not supported as the typeParam right now.
187 | CheckNullptr, ND, S(CountedStr,Nullptr), B|CRc
189   If S0 is not a null pointer, branch to block B. This is used to check the
190   return value of a native helper that returns a potentially null StringData*.
192 | AssertType, DRefineS(0), S(Gen,Cls,Ctx), P
194   Assert that the type of S0 is T, copying it to D.
196 | CheckTypeMem<T>, ND, S(PtrToGen), B
198   If the value pointed to by S0 is not type T, branch to the block B.
200 | CheckVArray, DArrPacked, S(Arr), B|P
202   Check that S0 is a varray, and if so copy it to D, and fallthrough. If S0 is
203   not a varray, branch to block B.
205 | CheckDArray, DArrMixed, S(Arr), B|P
207   Check that S0 is a darray, and if so copy it to D, and fallthrough. If S0 is
208   not a darray, branch to block B.
210 | HintLocInner<T,localId>, ND, S(FramePtr), NF
212   Hint that the inner type of a BoxedCell in localId is likely type T, where T
213   is a subtype of BoxedCell. The type must be guarded on before it is known to
214   be true (via CheckRefInner).
216 | HintStkInner<T,offset>, ND, S(StkPtr), NF
218   Hint that the inner type of the BoxedInitCell on the stack pointed to by S0
219   at offset (in cells) is T. The type must be guarded on before it is known to
220   be true (via CheckRefInner).
222 | HintMBaseInner<T>, ND, NA, NF
224   Hint that the inner type of the BoxedInitCell pointed to by the member base
225   register is T.  The type must be guarded on before it is known to be true
226   (via CheckRefInner).
228 | CheckLoc<T,localId>, ND, S(FramePtr), B
230   Check that type of the given localId on the frame S0 is T; if not, branch to
231   block B.
233 | CheckStk<T,offset>, ND, S(StkPtr), B
235   Check that the type of the cell on the stack pointed to by S0 at offset (in
236   cells) is T; if not, branch to block B.
238 | CheckMBase<T>, ND, S(PtrToGen), B
240   Check that the value pointed to by the member base register S0 has type T; if
241   not, branch to block B.  This is functionally the same as CheckTypeMem.
243 | AssertLoc<T,localId>, ND, S(FramePtr), NF
245   Asserts that type of the supplied local on the frame S0 is T. This is used
246   for local type information, and is similar to CheckLoc except it doesn't
247   imply a runtime check (the assertion must've already been proven to be true)
248   and cannot cause control flow.
250 | AssertStk<T,offset>, ND, S(StkPtr), NF
252   Assert that stack element at `offset' (in cells) from S0 has type T. This is
253   similar to a CheckStk except that it does not imply a runtime check and
254   cannot cause control flow.
256 | AssertMBase<T>, ND, NA, NF
258   Assert that the value pointed to by the member base register has type T.
259   This is similar to a CheckMBase except that it does not imply a runtime check
260   and cannot cause control flow.
262 | CastStk<T,offset>, ND, S(StkPtr), Er
264   Cast the stack element at `offset' (in cells) from S0 to type T.
266 | CastMem<T>, ND, S(PtrToGen), Er
268   Cast the TypedValue at S0 to type T.
270 The following instructions deal with parameter coercion (the standard type
271 conversion for arguments to HNI functions). If parameter coercion fails these
272 functions will throw a TVCoercion exception. They may throw other types of
273 exceptions depending on how coercion is implemented.
275 | CoerceStk<T,offset,fn,argNum>, ND, S(StkPtr), Er
277   Converts the stack slot at offset (in cells) to type T, with the semantics
278   needed for calling a builtin function. May throw a TVCoercionException in the
279   case of failed parameter coercion. The callee is f, and the position of the
280   argument being coerced is argNum.
282 | CoerceMem<T,fn,argNum>, ND, S(PtrToGen), Er
284   Coerces the TypedValue at S0 to type T, with the semantics
285   needed for calling a builtin function. May throw a TVCoercionException in the
286   case of failed parameter coercion. The callee is fn, and the position of the
287   argument being coerced is argNum.
289 | CoerceCellToBool<fn,argNum>, D(Bool), S(Cell), Er
291 | CoerceCellToInt<fn,argNum>,  D(Int), S(Cell), Er
293 | CoerceStrToInt<fn,argNum>,   D(Int), S(Str), Er
295 | CoerceCellToDbl<fn,argNum>,  D(Dbl), S(Cell), Er
297 | CoerceStrToDbl<fn,argNum>,   D(Dbl), S(Str), Er
299   These instructions convert either a Cell or a Str to a primitive type (Bool,
300   Int, Dbl) and return the resulting value. They may throw an exception upon
301   failed type coercion. They are encoded along with callee Func, fn, and the
302   integer position of the argument, argNum, being coerced.
304 | CheckInit, ND, S(Gen), B
306   If S0's type is Uninit, branch to block B.
308 | CheckInitMem, ND, S(PtrToGen), B
310   If the value pointed to by S0 has type Uninit, branch to block B.
312 | CheckCold<TransID>, ND, NA, B
314   Check if the counter associated with translation TransID is cold (i.e. within
315   a fixed threshold). If it's not (i.e. such translation has reached the
316   "hotness threshold"), then branch to block B.
318 | CheckRefs<firstBit,mask,vals>, ND, S(Func) S(Int), B
320   Perform reffiness guard checks. Operands:
322     S0 - function pointer for the frame
323     S1 - num params expected in the func
324     firstBit - first bit to check, must be a multiple of 64
325     mask - mask to check (RefDeps::Record::m_mask entries)
326     vals - values to check (RefDeps::Record::m_vals entries)
328   If any of the checks fail, branch to block B.
330 | EndGuards, ND, NA, NF
332   A no-op at runtime, this instruction serves to mark the end of the initial
333   sequence of guards in a trace.
335 | CheckNonNull, DSubtract(0, Nullptr), S(Nullptr,Func,PtrToGen,TCA,Cls,Ctx,Str), B
337   If the value in S0 is Nullptr, branch to block B. If S0 cannot be Nullptr, or
338   always is Nullptr, this check may be optimized away.
340 | AssertNonNull, DSubtract(0, Nullptr), S(Nullptr,CountedStr,Func), P
342   Returns S0, with Nullptr removed from its type. This instruction currently
343   supports a very limited range of types but can be expanded if needed.
345 2. Arithmetic
347 | AddInt, D(Int), S(Int) S(Int), NF
349 | SubInt, D(Int), S(Int) S(Int), NF
351 | MulInt, D(Int), S(Int) S(Int), NF
353 | AddIntO, D(Int), S(Int) S(Int), B
355 | SubIntO, D(Int), S(Int) S(Int), B
357 | MulIntO, D(Int), S(Int) S(Int), B
359 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
361 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
363 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
365 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
367 | DivInt, D(Int), S(Int) S(Int), NF
369 | Floor, D(Dbl), S(Dbl), NF
371 | Ceil, D(Dbl), S(Dbl), NF
373 | AbsDbl, D(Dbl), S(Dbl), NF
375 | Sqrt, D(Dbl), S(Dbl), NF
377 | AndInt, D(Int), S(Int) S(Int), NF
379 | OrInt, D(Int), S(Int) S(Int), NF
381 | XorInt, D(Int), S(Int) S(Int), NF
383 | Shl, D(Int), S(Int) S(Int), NF
385 | Shr, D(Int), S(Int) S(Int), NF
387   Double arithmetic, integer arithmetic, and integer bitwise operations.
388   Performs the operation described by the opcode name on S0 and S1, and puts
389   the result in D.
391   Undefined behavior occurs if Mod is given a divisor of zero, or if the
392   divisor is -1 and the dividend is the minimum representable integer.
394   AbsDbl computes the absolute value of a double-precision value.
396   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
397   or NAN depending on the dividend; and should the result of a division be zero
398   the sign will follow the normal sign rules for division.
400   DivInt will perform integer division of S1 by S0. S0 should not be zero and
401   must divide S1.
403   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
405   Floor and Ceil will return an integral value not greater, or not less
406   than their input respectively. Their use requires SSE 4.1, availability
407   should be checked before they are emitted.
409   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
410   branch to block B on integer overflow.
412 | XorBool, D(Bool), S(Bool) S(Bool), NF
414   Logical XOR of the two sources. (Note that && and || do not have
415   corresponding opcodes because they're handled at the bytecode level, to
416   implement short-circuiting.)
418 | Mod, D(Int), S(Int) S(Int), NF
420   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
423 3. Type conversions
425 To array conversions:
427 | ConvBoolToArr,                D(Arr), S(Bool),                         PRc
429 | ConvDblToArr,                 D(Arr), S(Dbl),                          PRc
431 | ConvIntToArr,                 D(Arr), S(Int),                          PRc
433 | ConvObjToArr,                 D(Arr), S(Obj),                   Er|PRc|CRc
435 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
437 | ConvVecToArr,                 D(Arr), S(Vec),                      PRc|CRc
439 | ConvDictToArr,                D(Arr), S(Dict),                     PRc|CRc
441 | ConvKeysetToArr,              D(Arr), S(Keyset),                   PRc|CRc
443 | ConvCellToArr,                D(Arr), S(Cell),                  Er|PRc|CRc
446 | ConvArrToNonDVArr,            D(Arr), S(Arr),                      PRc|CRc
449 To vec conversions:
451 | ConvArrToVec,                 D(Vec), S(Arr),                   Er|PRc|CRc
453 | ConvDictToVec,                D(Vec), S(Dict),                     PRc|CRc
455 | ConvKeysetToVec,              D(Vec), S(Keyset),                   PRc|CRc
457 | ConvObjToVec,                 D(Vec), S(Obj),                   Er|PRc|CRc
460 To dict conversions:
462 | ConvArrToDict,                D(Dict), S(Arr),                  Er|PRc|CRc
464 | ConvVecToDict,                D(Dict), S(Vec),                     PRc|CRc
466 | ConvKeysetToDict,             D(Dict), S(Keyset),                  PRc|CRc
468 | ConvObjToDict,                D(Dict), S(Obj),                  Er|PRc|CRc
471 To keyset conversions:
473 | ConvArrToKeyset,              D(Keyset), S(Arr),                Er|PRc|CRc
475 | ConvVecToKeyset,              D(Keyset), S(Vec),                Er|PRc|CRc
477 | ConvDictToKeyset,             D(Keyset), S(Dict),               Er|PRc|CRc
479 | ConvObjToKeyset,              D(Keyset), S(Obj),                Er|PRc|CRc
482 To varray conversions:
484 | ConvArrToVArr,                DArrPacked, S(Arr),                  PRc|CRc
486 | ConvVecToVArr,                DArrPacked, S(Vec),                  PRc|CRc
488 | ConvDictToVArr,               DArrPacked, S(Dict),                 PRc|CRc
490 | ConvKeysetToVArr,             DArrPacked, S(Keyset),               PRc|CRc
492 | ConvObjToVArr,                DArrPacked, S(Obj),               Er|PRc|CRc
495 To darray conversion:
497 | ConvArrToDArr,                DArrMixed, S(Arr),                   PRc|CRc
499 | ConvVecToDArr,                DArrMixed, S(Vec),                   PRc|CRc
501 | ConvDictToDArr,               DArrMixed, S(Dict),                  PRc|CRc
503 | ConvKeysetToDArr,             DArrMixed, S(Keyset),                PRc|CRc
505 | ConvObjToDArr,                DArrMixed, S(Obj),                Er|PRc|CRc
508 To bool conversions:
510 | ConvArrToBool,               D(Bool), S(Arr),                           NF
512 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
514 | ConvIntToBool,               D(Bool), S(Int),                           NF
516 | ConvStrToBool,               D(Bool), S(Str),                           NF
518 | ConvObjToBool,               D(Bool), S(Obj),                           NF
520 | ConvCellToBool,              D(Bool), S(Cell),                          NF
523 To double conversions:
525 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
527 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
529 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
531 | ConvObjToDbl,                 D(Dbl), S(Obj),                           Er
533 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
535 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
537 | ConvCellToDbl,                D(Dbl), S(Cell),                          Er
540 To int conversions:
542 | ConvBoolToInt,                D(Int), S(Bool),                          NF
544 | ConvDblToInt,                 D(Int), S(Dbl),                           NF
546 | ConvObjToInt,                 D(Int), S(Obj),                           Er
548 | ConvStrToInt,                 D(Int), S(Str),                           NF
550 | ConvResToInt,                 D(Int), S(Res),                           NF
552 | ConvCellToInt,                D(Int), S(Cell),                          Er
555 To object conversions:
557 | ConvCellToObj, D(Obj), S(Cell), Er|CRc|PRc
560 To string conversions:
562 | ConvDblToStr,                 D(Str), S(Dbl),                          PRc
564 | ConvIntToStr,                 D(Str), S(Int),                          PRc
566 | ConvObjToStr,                 D(Str), S(Obj),                       PRc|Er
568 | ConvResToStr,                 D(Str), S(Res),                       PRc|Er
570 | ConvCellToStr,                D(Str), S(Cell),                      PRc|Er
573   All the above opcodes convert S0 from its current type to the destination
574   type, according to the PHP semantics of such a conversion.
576 | ConvClsToCctx, D(Cctx), S(Cls), NF
578   Convert a class to a class context (i.e. the class with a 1 or'd into the low
579   bit).
581 | OrdStr,                       D(Int), S(Str),                           NF
583   Convert the first byte in a string to an unsigned integer.
584   Intended as an optimization for ord($str)
586 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    Er
588   Convert the character at position S1 in base string S0 to an unsigned
589   integer.  Raises a notice if the position is out of bounds.
590   Intended as an optimization for ord($str[$idx]).
592 | ChrInt,                      D(StaticStr), S(Int),                      NF
594   Convert the integer S0 to a the one character string with ascii code
595   S0 & 255.
597 | StrictlyIntegerConv,         D(Str|Int), S(Str),                        PRc
599   If S0 is a string representing an integer value (same criteria as array key
600   conversion), return that value as an integer. Otherwise return S0.
603 4. Boolean predicates
605 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
607 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
609 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
611 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
613 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
615 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
617 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
619   Perform 64-bit integer comparisons.
621 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
623 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
625 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
627 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
629 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
631 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
633 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
635   Perform comparisons of doubles. Comparisons that are unordered according to
636   IEEE 754 (such as when at least one operand is NaN) result in false.
638 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
640 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
642 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
644 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
646 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
648 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
650 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
652 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
654 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
656   Performs comparison of strings using PHP semantics.
658 | GtStrInt,                    D(Bool), S(Str) S(Int),                    NF
660 | GteStrInt,                   D(Bool), S(Str) S(Int),                    NF
662 | LtStrInt,                    D(Bool), S(Str) S(Int),                    NF
664 | LteStrInt,                   D(Bool), S(Str) S(Int),                    NF
666 | EqStrInt,                    D(Bool), S(Str) S(Int),                    NF
668 | NeqStrInt,                   D(Bool), S(Str) S(Int),                    NF
670 | CmpStrInt,                   D(Int),  S(Str) S(Int),                    NF
672   Performs comparison of strings with integers using PHP semantics.
674 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
676 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
678 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
680 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
682 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
684 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
686 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
688   Performs comparison of booleans.
690 | GtObj,                       D(Bool), S(Obj) S(Obj),                    Er
692 | GteObj,                      D(Bool), S(Obj) S(Obj),                    Er
694 | LtObj,                       D(Bool), S(Obj) S(Obj),                    Er
696 | LteObj,                      D(Bool), S(Obj) S(Obj),                    Er
698 | EqObj,                       D(Bool), S(Obj) S(Obj),                    Er
700 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    Er
702 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
704 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
706 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    Er
708   Perform comparison of objects using PHP semantics. All versions except for
709   SameObj and NSameObj may re-enter the VM and therefore may throw
710   exceptions. SameObj and NSameObj never re-enter or throw.
712 | GtArr,                       D(Bool), S(Arr) S(Arr),                    Er
714 | GteArr,                      D(Bool), S(Arr) S(Arr),                    Er
716 | LtArr,                       D(Bool), S(Arr) S(Arr),                    Er
718 | LteArr,                      D(Bool), S(Arr) S(Arr),                    Er
720 | EqArr,                       D(Bool), S(Arr) S(Arr),                    Er
722 | NeqArr,                      D(Bool), S(Arr) S(Arr),                    Er
724 | SameArr,                     D(Bool), S(Arr) S(Arr),                    Er
726 | NSameArr,                    D(Bool), S(Arr) S(Arr),                    Er
728 | CmpArr,                      D(Int),  S(Arr) S(Arr),                    Er
730   Perform comparison of arrays using PHP semantics. All versions except for
731   SameArr and NSameArr may re-enter the VM and therefore may throw
732   exceptions. SameArr and NSameArr never re-enter or throw.
734 | GtVec,                       D(Bool), S(Vec) S(Vec),                    Er
736 | GteVec,                      D(Bool), S(Vec) S(Vec),                    Er
738 | LtVec,                       D(Bool), S(Vec) S(Vec),                    Er
740 | LteVec,                      D(Bool), S(Vec) S(Vec),                    Er
742 | EqVec,                       D(Bool), S(Vec) S(Vec),                    Er
744 | NeqVec,                      D(Bool), S(Vec) S(Vec),                    Er
746 | SameVec,                     D(Bool), S(Vec) S(Vec),                    NF
748 | NSameVec,                    D(Bool), S(Vec) S(Vec),                    NF
750 | CmpVec,                      D(Int),  S(Vec) S(Vec),                    Er
752   Perform comparison of vecs. All versions except for SameVec and NSameVec may
753   re-enter the VM and therefore may throw exceptions. SameVec and NSameVec
754   never re-enter or throw.
756 | EqDict,                      D(Bool), S(Dict) S(Dict),                  Er
758 | NeqDict,                     D(Bool), S(Dict) S(Dict),                  Er
760 | SameDict,                    D(Bool), S(Dict) S(Dict),                  NF
762 | NSameDict,                   D(Bool), S(Dict) S(Dict),                  NF
764   Perform comparison of dicts. EqDict and NeqDict may re-enter the VM and
765   therefore may throw exceptions. SameDict and NSameDict never re-enter or
766   throw. Relational comparisons for dicts are not supported.
768 | EqKeyset,                    D(Bool), S(Keyset) S(Keyset),              NF
770 | NeqKeyset,                   D(Bool), S(Keyset) S(Keyset),              NF
772 | SameKeyset,                  D(Bool), S(Keyset) S(Keyset),              NF
774 | NSameKeyset,                 D(Bool), S(Keyset) S(Keyset),              NF
776   Perform comparison of keysets. As keysets can only contain ints and strings,
777   comparisons never re-enter or throw. Relational comparisons for keysets are
778   not supported.
780 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
782 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
784 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
786 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
788 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
790 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
792 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
794   Perform comparison of resources using PHP semantics. Resource comparisons
795   never re-enter or throw.
797 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
799   Checks if two Class values are equal.
801 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
803   Checks if two Func values are equal.
805 | EqStrPtr,                    D(Bool), S(Str) S(Str),                    NF
807   Checks if two string values represent the same underlying string. That is,
808   that they point at the same underlying storage.
810 | EqArrayDataPtr,              D(Bool), S(ArrLike) S(ArrLike),            NF
812   Checks if the two arguments represent the same underlying ArrayData. That is,
813   that they point at the same underlying storage.
815 | ProfileInstanceCheck, ND, C(StaticStr), NF
817   Profile that S0 has been used as the RHS of an instance check.
819 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
821   Sets D based on whether S0 is a descendant of the class, interface, or trait
822   in S1. (Note that this is always false for a trait). S1 may be null at
823   runtime if the class is not defined.
825 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
827   Fast path for interface checks. Sets D based on whether S0 implements S1, but
828   S1 must be a unique interface. This should only be used in repo-authoritative
829   mode.
831 | InstanceOfIfaceVtable<iface>, D(Bool), S(Cls), NF
833   Faster path for interface checks. Sets D based on whether S0 implements
834   iface, which must be a unique interface with an assigned vtable slot.
836 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
838   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
839   of cls, where cls must be a unique class that is not an interface or a trait.
841   If strictLikely is true, optimize for the case where S0 is not equal to S1.
843 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
845 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
847   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
848   of the class named by S1, where S1 must have a bit allocated for it in the
849   fast instance check bitvector (see class.h).
851 | InterfaceSupportsArr,        D(Bool), S(Str), NF
853 | InterfaceSupportsVec,        D(Bool), S(Str), NF
855 | InterfaceSupportsDict,       D(Bool), S(Str), NF
857 | InterfaceSupportsKeyset,     D(Bool), S(Str), NF
859 | InterfaceSupportsStr,        D(Bool), S(Str), NF
861 | InterfaceSupportsInt,        D(Bool), S(Str), NF
863 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
865   Returns whether t instanceof S0 returns true when t is of the given type.
867 | HasToString, D(Bool), S(Obj), NF
869   Returns whether the object S0 has a toString method.
871 | IsType<T>, D(Bool), S(Cell), NF
873   Sets D to true iff S0 holds a value that is of type T. T must not be a
874   specialized type.
876 | IsNType<T>, D(Bool), S(Cell), NF
878   Sets D to true iff S0 holds a value that is not of type T. T must not be a
879   specialized type.
881 | IsTypeMem<T>, D(Bool), S(PtrToGen), NF
883   Sets D to true iff the value referenced by S0 is of type T. T must not be a
884   specialized type.
886   The value in S0 must not be a pointer into the evaluation stack or frame
887   locals.
889 | IsNTypeMem<T>, D(Bool), S(PtrToGen), NF
891   Sets D to true iff the value referenced by S0 is not of type T. T must not be
892   a specialized type.
894 | IsScalarType, D(Bool), S(Cell), NF
896   Returns true if S0 is of type Int, Bool, Dbl or Str. Returns false otherwise.
898 | IsWaitHandle, D(Bool), S(Obj), NF
900   Sets D to true iff S0 is a subclass of WaitHandle.
902 | IsCol, D(Bool), S(Obj), NF
904   Sets D to true iff S0 is a collection.
906 | IsDVArray, D(Bool), S(Arr), NF
908   Sets D to true iff S0 is a darray or varray.
910 5. Branches
912 | JmpZero,                          ND, S(Int,Bool),                     B
914 | JmpNZero,                         ND, S(Int,Bool),                     B
916   Conditionally jump to based on S0.
918 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
920   Jump to the target of a sswitch statement, leaving the region, where the
921   target TCA is S0.
923 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
925   Jump to the target of a switch statement, leaving the region, using table
926   metadata <JmpSwitchData> and index S0, which must be a valid index in the
927   jump table.
929 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
931   Profile a switch statement target.
933 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
935   Tests the implementation-specific surprise flags. If they're true, branches
936   to block B. This is done by comparing an evaluation stack pointer to the RDS
937   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
938   pointing into the eval stack, so S0 should be a StkPtr in that case.
940 | ReturnHook, ND, S(FramePtr) S(Gen), Er
942   Surprise flag hook for function returns.
944 | SuspendHookAwaitEF, ND, S(FramePtr) S(FramePtr) S(Obj), Er
946   Surprise flag hook for suspending eagerly executing async functions. The S0
947   frame was already teleported into S1. Decrefs S2 if it throws an exception.
949 | SuspendHookAwaitEG, ND, S(FramePtr) S(Obj), Er
951   Surprise flag hook for suspending eagerly executing async generators. The S0
952   frame has an associated AG, which is already linked to the newly constructed
953   AGWH in the blocked state. Decrefs S1 if it throws an exception.
955 | SuspendHookAwaitR, ND, S(FramePtr) S(Obj), Er
957   Surprise flag hook for suspending async functions and async generators resumed
958   at Await. The S0 frame has an associated AFWH/AGWH still in the running state,
959   S1 points to the child WH we are going to block on.
961 | SuspendHookCreateCont, ND, S(FramePtr) S(FramePtr) S(Obj), Er
963   Surprise flag hook for suspending generators and async generators during their
964   invocation. The S0 frame was already teleported into S1. Decrefs S2 if it
965   throws an exception.
967 | SuspendHookYield, ND, S(FramePtr), Er
969   Surprise flag hook for suspending generators and async generators at Yield.
971 | Unreachable<AssertReason>, ND, NA, T
973   Indicates an unreachable code path. Any instructions that are post-dominated
974   by an Unreachable may be treated as unreachable by the optimizer, and the
975   behavior of a program that attempts to execute an Unreachable is undefined.
977 | EndBlock<AssertReason>, ND, NA, T
979   Halt execution, without implying anything about the reachability of
980   instructions preceding this. Intended for use in internal tests or other code
981   not meant to be executed.
983 | Jmp, ND, SVar(Top), B|T
985   Unconditional jump to block B. In the second form, the target block must
986   start with a DefLabel with the same number of destinations as Jmp's number of
987   sources. Jmp parallel-copies its sources to the DefLabel destinations.
989 | DefLabel, DMulti, NA, NF
991   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
992   destinations is a no-op, and the predecessor blocks may not necessarily end
993   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
994   instruction with the same number of sources. Ordinary branch instructions may
995   not pass values to a DefLabel.
997 | Select, DUnion(1,2), S(Bool,Int) S(Top) S(Top), NF
999   If S0 is true/non-zero, return S1, otherwise return S2.
1002 6. Reference manipulation
1004 | Box, D(BoxedInitCell), S(Cell), CRc|PRc
1006   Box S0 and put the resulting BoxedInitCell in D. If S0 is Uninit, then
1007   InitNull will be boxed instead.
1009 | UnboxPtr, DUnboxPtr, S(PtrToGen), NF
1011   If S0 points to a cell that is KindOfRef, dereference the pointer in the
1012   TypedValue and return a pointer to the inner-cell in D.
1014 | BoxPtr, DBoxPtr, S(PtrToGen), NF
1016   Boxes the TypeValue that S0 points to if it is not boxed. The result D points
1017   to the same TypedValue as S0 but has a more refined type.
1019   S0 may not already point into a RefData (due to VM invariants), although the
1020   IR type system does not enforce it.
1023 7. Loads
1025 | LdStk<T,offset>, DParamMayRelax(Gen), S(StkPtr), NF
1027   Loads from S0 at offset (in cells), and puts the value in D as type T.
1029 | LdLoc<T,localId>, DParamMayRelax(Gen), S(FramePtr), NF
1031   Loads local slot localId from the frame S0 and puts the value in D as type T.
1033 | LdLocPseudoMain<T,localId>, DParam(Gen), S(FramePtr), B
1035   Loads local number localId from frame S0 and puts the value in D if the
1036   local's type is a subtype of T. If the local's type is not a subtype of T,
1037   then the load does not happen, and this instruction branches to B. This
1038   instruction is used for loading locals in pseudo-mains, where they can alias
1039   globals.
1041 | LdClsRef<T,slot>, DParamMayRelax(Cls), S(FramePtr), NF
1043   Loads class-ref from slot `slot` in frame S0 and puts the value in D as type
1044   T. T must be a sub-type of TCls.
1046 | LdStkAddr<T,offset>, D(PtrToStkGen), S(StkPtr), NF
1048   Loads the address of the stack slot given by the pointer in S0 at the offset
1049   (in cells). T must be a subtype of PtrToStkGen.
1051 | LdLocAddr<localId>, D(PtrToFrameGen), S(FramePtr), NF
1053   Loads the address of the local slot localId from the frame S0 into D.
1055 | LdRDSAddr<T,RDSHandle>, DParam(PtrToGen), NA, NF
1057   Load the address of a Gen that lives at the specified RDS handle. The type
1058   param must be a subtype of PtrToGen.
1060 | LdVectorBase, D(PtrToMembCell), S(Obj), NF
1062 | LdPairBase, D(PtrToMembCell), S(Obj), NF
1064   Loads the base pointer to an array of Cells from the given collection
1065   instance in S0.
1067 | LdMem<T>, DParam(Gen), S(PtrToGen), NF
1069   Loads from S0 and puts the value in D.
1071 | LdContField<T>, DParam(Gen), S(Obj) C(Int), NF
1073   Loads a property from the object referenced by S0 at the offset given by S1
1074   and puts the value in D. S0 must be a Generator.
1076 | LdElem, D(Cell), S(PtrToCell) S(Int), NF
1078   Loads the element at index S1 from the base pointer in S0. The index in S1 is
1079   the number of bytes from the base in S0.
1081 | LdColVec, D(Vec), S(Obj), NF
1083   Load the vec array backing a collection instance in S0, which must be a
1084   Vector or ImmVector, and that specific object type must be known at compile
1085   time.
1087 | LdColDict, D(Dict), S(Obj), NF
1089   Load the dict array backing a collection instance in S0, which must be a
1090   Map, Set, ImmMap, or ImmSet, and that specific object type must be known at
1091   compile time.
1093 | CheckRefInner<T>, ND, S(BoxedCell), B
1095   TODO(#2939547): this should take BoxedInitCell
1097   Check that the inner type of the boxed cell in S0 is T, and if not take the
1098   branch to B.
1100 | LdRef<T>, DParam(Cell), S(BoxedCell), NF
1102   TODO(#2939547): this should take BoxedInitCell
1104   Loads the value held in the box referenced by S0 and puts the value in D. The
1105   inner type of S0 must be a subtype of T (usually ensured with a previous
1106   CheckRefInner).
1108 | LdCtx, DCtx, S(FramePtr), NF
1110   Loads into D the value of the m_this/m_cls field out of the frame pointer S0,
1111   which must be a frame for the function in the LdCtx's marker. The result
1112   could be either an object representing the this pointer or a class context.
1114 | LdCctx, DCtx, S(FramePtr), NF
1116   Loads into D the value of the m_cls field out of the frame pointer S0. The
1117   compiler should generate this only if it can prove that the frame does not
1118   contain a nullptr or $this pointer.
1120 | LdClosure<T>, DParam(Ctx), S(FramePtr), NF
1122   Loads into D the value of the m_this/m_cls field out of the frame pointer S0.
1123   The compiler should generate this only if it can prove that the frame context
1124   is a closure object of type T.  Unlike LdCtx and LdCctx, there are no special
1125   rules about the relative positions of LdClosure and InitCtx instructions.
1127 | CheckCtxThis, ND, S(Ctx), B
1129   Check that the context (m_this or m_cls) in S0 is a non-null $this
1130   pointer. If not, branch to B.
1132 | LdClsCtx, DCtxCls, S(Ctx), NF
1134   Loads into D the class representing the current context. Extracts the class
1135   from S0, which can be either the this pointer or the context class.
1137 | LdClsCctx, DCtxCls, S(Cctx), NF
1139   Loads into D the class representing the current context. Extracts the class
1140   from the S0, which is a context class.
1142 | LdClsCtor, D(Func), S(Cls) S(FramePtr), Er
1144   Loads into D the constructor of class S0. If the constructor cannot be called
1145   from the context in S1, raise an error.
1147 | DefCls, D(Cls), S(Int), Er
1149   Define the class corresponding to PreClass S0 in the current unit.
1151 | DefConst<T>, DParam(Top), NA, NF
1153   Define a constant value of type T. D is presumed to be globally available and
1154   the DefConst instruction will not actually appear in the IR instruction
1155   stream.
1157 | Conjure<T>, DParam(Top), NA, NF
1159   Define a value of type T. This instruction aborts at runtime; it is meant to
1160   be used in tests or code that is known to be unreachable.
1162 | ConjureUse, ND, S(Gen), NF
1164   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
1165   should not appear in reachable code.
1167 | LdCls, D(Cls), S(Str) C(Cls), Er
1169   Loads the class named S0 in the context of the class S1. Invokes autoload and
1170   may raise an error if the class is not defined. The explicit context
1171   parameter allows the compiler to simplify this instruction to a DefConst in
1172   some cases. If S0 is constant, this instruction may be simplified to a
1173   LdClsCached.
1175 | LdClsCached, D(Cls), CStr, Er
1177   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
1178   if the class is not defined.
1180 | LdClsCachedSafe, D(Cls), CStr, B
1182   Loads the class whose name is S0 out of the RDS. If the class is not defined,
1183   branch to B.
1185 | LdClsInitData, D(PtrToClsInitCell), S(Cls), NF
1187   Loads the pointer to the property initializer array for class S0.
1189 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
1191   Lookup the cached-class RDS handle for a given class name. Dereference that
1192   handle and return the associated Class, or null if not present.
1194 | LdCns, DCns, CStr, B
1196   Load the constant named S0, branching to B if isn't present.
1198 | LookupCns<T,constName>,   DCns, CStr, Er|PRc
1200 | LookupCnsE<T,constName>,  DCns, CStr, Er|PRc
1202   Load a constant via the RDS. Raises an undefined constant notice if the
1203   constant cannot be defined.  The E variant will instead throw a fatal error if
1204   it cannot define the constant.  These should only be executed if LdCns on the
1205   same constant has failed.
1207 | LookupCnsU<T,constName,fallbackName>, DCns, CStr CStr, Er|PRc
1209   Load an unqualified constant via the RDS, first by trying constName, then by
1210   trying fallbackName.  Raises a notice if neither can be found.  Should only
1211   be executed if LdCns on the same constant has failed.
1213 | LdClsCns<className,constantName>, D(PtrToGen), NA, B
1215   Load the address of the constant 'constantName' for the class 'className' in
1216   RDS. If not initialized, branch to B.
1218 | LdSubClsCns<constantName,slot>, D(PtrToGen), S(Cls), NF
1220   Load the address of the constant 'constantName' for the class S0. The
1221   constant is known to be in the given slot. If the returned TypedValue is not
1222   UncountedInit, its value should not be used, and a fallback method should be
1223   called.
1225 | CheckSubClsCns<constantName,slot>, ND, S(Cls), B
1227   Check that the constant 'constantName' lives in the given slot for the class
1228   S0, and branch if not. S0 must have at least slot+1 constants.
1230 | LdClsCnsVecLen, D(Int), S(Cls), NF
1232   Load the size of S0's constant table.
1234 | ProfileSubClsCns<constantName,handle>, D(PtrToGen), S(Cls), NF
1236   Load the address of the constant 'constantName' for the class S0, profiling
1237   the observed slots. If the returned TypedValue is not UncountedInit, its
1238   value should not be used, and a fallback method should be called.
1240 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1242   Loads the target cache entry for a forwarding call to clsName::methodName.
1243   If the method does not exist, or the cache hasn't been filled yet, branch to
1244   B.
1246 | LookupClsMethodFCache<clsName,methodName>,
1247 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1248 |    Er
1250   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1251   the Class named by clsName and S1 should be the current vm frame pointer. May
1252   return Nullptr if lookup fails using a subset of the required lookup paths,
1253   indicating that a more complete lookup path should be taken. May throw if the
1254   method does not exist.
1256 | CheckFuncStatic, ND, S(Func), B
1258   Tests to see if Func::m_attrs & AttrStatic, and if so branch to B.
1259   This instruction is intended to be used in forwarding calls, where we know
1260   that Func is not a closure.
1262 | FwdCtxStaticCall, D(Cctx), S(Ctx), NF
1264   If S0 is an object, this opcode returns S0's class with the low bit set
1265   (i.e., as a Cctx). Otherwise this instruction returns S0.
1267 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1269   Loads the target cache entry for the method clsName::methodName. If the
1270   method does not exist or the cache hasn't been filled yet, branch to B.
1272 | LdClsMethodCacheCls<clsName,methodName>, D(Cctx), NA, NF
1274   Loads the target cache class context entry for a call to clsName::methodName
1275   from the current context. This instruction must only be used when the value
1276   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1277   LookupClsMethodCache returned a non-null value).
1279 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr),
1280 |                                           S(FramePtr),
1281 |                                           Er
1283   Lookup a function in the class method targetcache. The class name and method
1284   name are clsName and methodName, respectively. S0 is the current vm frame
1285   pointer. Returns Nullptr if the method cannot be found using a subset of the
1286   required lookup paths, indicating that a more complete lookup path should be
1287   taken. May throw if the method does not exist.
1289 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1291   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1293 | LdFuncVecLen, D(Int), S(Cls,Cctx), NF
1295   Load the funcVecLen field from S0.
1297 | LdClsMethod, D(Func), S(Cls,Cctx) C(Int), NF
1299   Load a Func* off of the class method table for S0, at offset S1 (in method
1300   slots).
1302 | LookupClsMethod<calleeAROffset,forward>,
1303 |   ND,
1304 |   S(Cls) S(Str) S(StkPtr) S(FramePtr),
1305 |   Er
1307   Store a pointer to a class method into an activation record. S0 points to the
1308   class, S1 is the method name, S2 is a stack pointer that has an activation
1309   record to modify at `spToActRecOffset', and S3 is a pointer to the current
1310   frame (used to get the context). `forward` indicates if we should forward the
1311   current context. May throw or fatal if method is not accessible.
1313 | LdPropAddr<T,offset>, DParamPtr(Prop), S(Obj), NF
1315   Load the address of the object property for S0 + `offset' (in bytes).  T must
1316   be a subtype of PtrToPropGen.
1318 | LdGblAddr, D(PtrToGblGen), S(Str), B
1320   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1321   global is not defined.
1323 | LdGblAddrDef, D(PtrToGblGen), S(Str), NF
1325   Loads a pointer to a global. S0 is the global's name. Defines the global if
1326   it is not already defined.
1328 | LdClsPropAddrOrNull, D(PtrToSPropGen|Nullptr),
1329 |                      S(Cls) S(Str) C(Cls),
1330 |                      Er
1332   Loads a pointer to a static class property. S0 points to the class, S1 is the
1333   property name, and S2 is the class representing the context of the code
1334   accessing the property. If class S0 does not have a visible and accessible
1335   static property named S1, then nullptr is returned.
1337 | LdClsPropAddrOrRaise, D(PtrToSPropGen), S(Cls) S(Str) C(Cls), Er
1339   Loads a pointer to a static class property. S0 points to the class, S1 is the
1340   property name, and S2 is the class representing the context of the code
1341   accessing the property. If class S0 does not have a visible and accessible
1342   static property named S1, throw a fatal error.
1344 | LdObjMethod<offset,methodName,fatal>, ND, S(Cls) S(StkPtr), Er
1346   Stores a pointer to an object's method into an activation record. S0 points
1347   to the object's class, S1 has the pre-live activation record at `offset'.
1348   Caches the mapping in the target cache. If `fatal' is true, raises a fatal if
1349   the class does not have an accessible method with the given name and does not
1350   have a __call method; otherwise (if `fatal' is false), raises a warning and
1351   puts func that does nothing and returns null (SystemLib::s_nullFunc) on the
1352   activation record.
1354 | LdObjInvoke, D(Func), S(Cls), B
1356   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1357   to block B if it is not present.
1359 | LdArrFuncCtx<offset>, ND, S(Arr,Vec) S(StkPtr) S(FramePtr), Er
1361   Try to load an array as a function context. This is for use translating
1362   FPushFunc when the callee is an array. This instruction attempts to populate
1363   a partially created ActRec pointed to by S1 + `offset' (in cells).
1365 | LdArrFPushCuf<offset>, ND, S(Arr,Vec) S(StkPtr) S(FramePtr), Er
1367 | LdStrFPushCuf<offset>, ND, S(Str) S(StkPtr) S(FramePtr), Er
1369   Try to resolve a method target for FPushCuf when the callee is an Arr or Str,
1370   respectively. These instructions mutate a partially created ActRec pointed to
1371   by S1 + `offset' (in cells).
1373 | LdObjClass, DLdObjCls, S(Obj), NF
1375   Load the class out of the object in S0 and put it in D.
1377 | LdClsName, D(StaticStr), S(Cls), NF
1379   Load the name of the Class* in S0.
1381 | LdFunc<offset>, ND, S(Str) S(StkPtr) S(FramePtr), Er
1383   Loads the Func whose name is S0 into the partially constructed ActRec pointed
1384   to by S1 + `offset` (in cells). Also populate the m_this/m_cls field if
1385   necessary.  Fatal if the named function is not defined, and the autoloader
1386   fails to define it.
1388 | LdFuncCached<funcName>, D(Func), NA, Er
1390   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1391   not defined yet. Fatal if function autoloader fails to define it.
1393 | LdFuncCachedU<funcName,fallbackName>, D(Func), NA, Er
1395   Try to load a Func named funcName from the RDS, if it isn't defined, try to
1396   load a Func named fallbackName. If that also isn't defined, invoke autoload.
1397   If this still doesn't result in a Func, raise a fatal error.
1399 | LdFuncCachedSafe<funcName>, D(Func), NA, B
1401   Try to load the Func named funcName from the RDS. If the function is not
1402   defined, branch to B.
1404 | LdARFuncPtr<offset>, DParam(Func), S(StkPtr), NF
1406   Loads the m_func member of an ActRec. S0 is the base address, with `offset'
1407   cells to the ActRec.
1409 | LdARCtx<T,offset>, DParam(Ctx), S(StkPtr), NF
1411   Loads the m_this/m_cls member of an ActRec. S0 is the base address, with
1412   `offset' cells to the ActRec.
1414 | LdARNumParams, D(Int), S(FramePtr), NF
1416   Loads the number of params from an ActRec. S0 is the address of the ActRec
1418 | LdFuncNumParams, D(Int), S(Func), NF
1420   Returns the value of func->numParams().
1422 | LdStrLen, D(Int), S(Str), NF
1424   Load the length of the string in S0.
1426 | LdClosureStaticLoc<func,staticLocalName>, D(PtrToPropGen), S(Obj), NF
1428   Get pointer to static local named 'staticLocName' for function 'func' whose
1429   closure object is S0. func must either be a Closure, or generatorFromClosure
1431 | LdStaticLoc<func,staticLocalName>, D(BoxedInitCell), NA, PRc
1433   Load the address of the static local variable named 'staticLocalName' for
1434   function 'func' in RDS. The variable must be initialized
1436 8. Allocation
1438 | AllocObj, DAllocObj, S(Cls), PRc|Er
1440   Allocates a new object of class S1.
1442 | RegisterLiveObj, ND, S(Obj), NF
1444   When EnableObjDestructCall is on, we need to keep track of objects to be able
1445   to call their destructors when a request exists.  This instruction is
1446   conditionally emitted to implement that.
1448 | CheckInitProps<class>, ND, NA, B
1450   Check if the properties for class are initialized and branches if not.
1452 | InitProps<class>, ND, NA, Er
1454   Calls the property initializer function (86pinit) for class.  May throw.
1456 | CheckInitSProps<class>, ND, NA, B
1458   Check if static properties for class are initialized and branches if not.
1460 | InitSProps<class>, ND, NA, Er
1462   Calls the static property initializer function (86sinit) for class. May
1463   throw.
1465 | DebugBacktrace, D(Arr), S(Int), PRc
1467   Obtain stack trace by calling the debug_backtrace() method.
1469 | DebugBacktraceFast, D(Res), NA, PRc
1471   Obtain compact stack trace resource that can be expanded lazily.
1473 | InitThrowableFileAndLine, ND, S(Obj), NF
1475   Initialize Throwable's file name and line number assuming the stack trace
1476   was already initialized and the current vmfp() is a built-in.
1478 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1480   Allocates an instance of class.
1482 | InitObjProps<class>, ND, S(Obj), NF
1484   Initializes properties of object S0.
1486 | ConstructInstance<class>, DAllocObj, NA, Er
1488   Call the custom instance constructor of an extension class.
1490 | NewArray, D(Arr), C(Int), PRc
1492   Allocate a new array with the expected capacity S0.
1494 | NewMixedArray, DArrMixed, C(Int), PRc
1496   Allocate a new array in mixed mode with the expected capacity S0.
1498 | NewDArray, DArrMixed, C(Int), PRc
1500   Allocate a new dict-like array with the expected capacity S0.
1502 | NewDictArray, D(Dict), C(Int), PRc
1504   Allocate a new dict with the expected capacity S0.
1506 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc|Er
1508   Allocate a new keyset containing N elements off the stack given by S0, at
1509   `offset'. This instruction moves the elements off the stack without
1510   manipulating their reference counts.
1512 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1514   Allocate a new array in the same mode as S0 and with expected capacity S1,
1515   unless S1 == 0, in which case the capacity is set to S0's size.
1517 | AllocPackedArray<size>, DArrPacked, NA, PRc
1519   Allocate a new uninitialized packed array with space for size elements in it.
1520   The array will be initialized with values using either InitPackedLayoutArray
1521   or InitPackedLayoutArrayLoop.
1523 | AllocVArray<size>, DArrPacked, NA, PRc
1525   Allocate a new uninitialized vec-like array with space for size elements in
1526   it.  The array will be initialized with values using either
1527   InitPackedLayoutArray or InitPackedLayoutArrayLoop.
1529 | AllocVecArray<size>, D(Vec), NA, PRc
1531   Allocate a new uninitialized vector array with space for size elements in it.
1532   The array will be initialized with values using either InitPackedLayoutArray
1533   or InitPackedLayoutArrayLoop.
1535 | InitPackedLayoutArray<index>, ND, S(Arr,Vec) S(Cell), NF
1537   Store the S1 into the slot at index in array S0. This instruction assumes
1538   that it doesn't have to incref the value being stored. Used to initialize an
1539   array allocated with AllocPackedArray or AllocVecArray.
1541 | InitPackedLayoutArrayLoop<offset,size>, ND, S(Arr,Vec) S(StkPtr), CRc
1543   Move `size' elements from the stack given by S1, at `offset', into the array
1544   S0.  Assumes that the first element on the stack is the last element in the
1545   array.  Used to initialize an array allocated with AllocPackedArray or
1546   AllocVecArray that was too big to use a series of InitPackedLayoutArray
1547   instructions.
1549 | NewStructArray<offset,keys...>, DArrMixed, S(StkPtr), PRc|CRc
1551   Allocate a new key/value array, given N immediate keys and taking N elements
1552   off the stack given by S0, at `offset'. This instruction assumes it can take
1553   the values from the stack without increfing them.
1555 | NewStructDArray<offset,keys...>, DArrMixed, S(StkPtr), PRc|CRc
1557   Allocate a new key/value dict-like array, given N immediate keys and taking N
1558   elements off the stack given by S0, at `offset'. This instruction assumes it
1559   can take the values from the stack without increfing them.
1561 | NewStructDict<offset,keys...>, D(Dict), S(StkPtr), PRc|CRc
1563   Allocate a new key/value dict array, given N immediate keys and taking N
1564   elements off the stack given by S0, at `offset'. This instruction assumes it
1565   can take the values from the stack without increfing them.
1567 | NewCol<type>, DCol, NA, PRc
1569   Create an empty new collection of `type'. `type' cannot be Pair.
1571 | NewPair<offset>, DCol, S(Cell) S(Cell), PRc|CRc
1573   Allocate a new Pair and fill it with the given cells. Ownership of the cells
1574   is transferred from $1 and $2 to the pair without manipulating the refcounts.
1576 | NewColFromArray<type>, DCol, S(Vec|Dict), PRc|CRc
1578   Create a collection of `type` from a Vec or Dict kind. `type` cannot be
1579   Pair. S0 must be vec kind when `type` is Vector or ImmVector, and must be
1580   dict kind otherwise. Ownership of S0 is transferred from $1 to the
1581   collection, without manipulating the refcount.
1583 | Clone, DofS(0), S(Obj), PRc|Er
1585   Allocate an object by cloning S0.
1588 9. Call & Return
1590 | SpillFrame<offset,numArgs>,
1591 |   ND,
1592 |   S(StkPtr) S(Func,Nullptr) S(Ctx,Cls,Nullptr) S(Str,Nullptr) S(Bool),
1593 |   NF
1595   Operands:
1597      S0 - caller stack pointer
1598      S1 - callee Func or nullptr
1599      S2 - object (for FPushObjMethod*), class (for FPushClsMethod*), context
1600           (for FPushClsMethodF), or nullptr (for FPushFunc*).
1601      S3 - invoke name for magic dispatch
1602      S4 - whether this is a "dynamic" call
1604   Defines the fields for an activation record and writes them to the stack
1605   pointed to by S0, at `offset'.
1607 | BeginInlining<offset>, ND, S(StkPtr), NF
1609   Marks the start of an inlined function whose stack resides offset cells below
1610   the SP. It has no effect other than to hint to optimization passes that at the
1611   start of the inlined function its stack is dead.
1613 | DefInlineFP<func,retBCOff,retSPOff>, D(FramePtr),
1614 |                                      S(StkPtr) S(FramePtr),
1615 |                                      NF
1617   Defines a frame pointer for an inlined function.
1619   `func' is the function being inlined. `retBCOff' and `retSPOff' represent
1620   what the bytecode and stack offsets should be after the FCall instruction in
1621   ther caller.
1623   This instruction is primarily used to represent a frame in the IR in a way
1624   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1625   it is pushed into an unlikely path) it performs callee-side responsibilities
1626   for setting up an activation record (i.e. setting the return ip and m_soff,
1627   storing the frame pointer into D).
1629   The caller frame pointer is passed as S1. This is used to keep track of the
1630   call chain of inlined functions for simplification and dead code elimination.
1632 | InlineReturn<callerFPOff>, ND, S(FramePtr), NF
1634   Unlinks a frame constructed by DefInlineFP.  `callerFPOff' is the offset of
1635   the caller's frame pointer relative to S0.
1637 | InlineReturnNoFrame<InlineFrameStart>, ND, NA, NF
1639   Mark the end of an inlined function for which no DefInlineFP was required. The
1640   primary purpose of this instruction is to mark the result of a SpillFrame as
1641   dead. InlineFrameStart is the caller FP-relative offset of the start of the
1642   callee frame. Everything below InlineFrameStart is dead.
1644 | CallArray<spOffset,numParams,callOff,after,funcd,destroyLocals>,
1645 |                       DCall,
1646 |                       S(StkPtr) S(FramePtr),
1647 |                       Er
1649   Invoke function corresponding to the current FPI with numParams arguments,
1650   the last of which is an array of the remaining args. Used for FCallArray (in
1651   which case numParams == 1), and FCallUnpack. S0+spOffset points to the stack
1652   resulting after the ActRec for the function and numParams arguments have been
1653   pushed. CallArray pops the array off the stack, pushes the elements of the
1654   array as arguments, and invokes the function in the ActRec.
1656 | SyncReturnBC<spOffset,bcOffset>, ND, S(StkPtr) S(FramePtr), NF
1658   Stores bcOffset into the frame at spOffset from S0 as the return bytecode
1659   address and the frame S1 as the return frame.
1661 | Call<offset,numParams,returnOff,funcd,destroyLocals>, DCall,
1662 |                                                       S(StkPtr) S(FramePtr),
1663 |                                                       Er
1665   Transfer control to a callee, based on the pre-live activation record and set
1666   of args on the stack pointed to by S0 at `offset'. S1 is the current caller
1667   frame pointer. The `funcd' in the extra data is a Func* for the callee if we
1668   know the callee statically.
1670 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), Er
1672   Execute a call to the native builtin specified by the current function. S0
1673   and S1 should be the current vmfp and vmsp, respectively.
1675 | CallBuiltin, DBuiltin, S(FramePtr) S(StkPtr) SVar(PtrToGen,Gen,Cls,Nullptr), Er|PRc
1677   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1678   and vmsp, respectively.
1680   The source and destination types correspond to C++ parameter and return types
1681   as follows:
1683     C++ type            HHIR type         Position
1684     -----------------   ---------         --------
1685     bool                Bool              source, destination
1686     int64_t             Int               source, destination
1687     double              Dbl               source, destination
1688     const String&       PtrToStr          source
1689     const Array&        PtrToArr          source
1690     const Object&       PtrToObj          source
1691     const Variant&      PtrToGen          source
1692     Variant&            PtrToGen          source (ref param)
1693     String              {Str|InitNull}    destination
1694     Array               {Arr|InitNull}    destination
1695     Object              {Obj|InitNull}    destination
1696     Variant             {Gen-UninitNull}  destination
1698 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Gen), T
1700   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1701   frame pointer is stored in rvmfp, then return to the saved return address in
1702   S1.  The return value is S2, which is passed via the rret_*() registers to
1703   the caller.  The `suspendingResumed' flag indicates when this instruction is
1704   suspending a resumable rather than performing a normal function return.
1706 | AsyncFuncRet<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1708   Return from a resumed async function, assuming no surprise. Ensures that
1709   S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored in rvmfp,
1710   packs return value S2 into registers and calls the `asyncFuncRet` unique
1711   stub. The stub stores the result into the wait handle associated with the
1712   frame pointer, marks it as finished, unblocks its parents and if possible,
1713   directly resumes the first parent (fast path), or a pending fast runnable
1714   ResumableWaitHandle (slower path). Otherwise, it will exit VM and return
1715   control to the asio scheduler (slow path). The stack must contain exactly one
1716   cell containing uninitialized garbage, which will be populated by the stub
1717   either to pass the return value to the resumed function, or to return null
1718   to the scheduler.
1720 | AsyncFuncRetSlow<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1722   Return from a resumed async function, assuming unknown surprise flag state
1723   after the previous surprise was handled by executing "return" event hook.
1724   Calls the `asyncFuncRetSlow` stub, which re-checks the surprise flag and
1725   transfers control to the AsyncFuncRet if it was clear, or performs the slow
1726   path of AsyncFuncRet if it was not, without resuming another function, as
1727   we are not able to call a potential "resume await" event hook from the stub.
1729 | AsyncSwitchFast<spOff>, ND, S(StkPtr) S(FramePtr), T
1731   Switch control to another ResumableWaitHandle. Ensures that S0 + `spOff`
1732   (in cells) is stored in rvmsp and that S1 is stored in rvmfp and calls the
1733   `asyncSwitchCtrl` unique stub, which tries to resume a pending fast runnable
1734   ResumableWaitHandle (fast path) if possible, otherwise it will exit VM and
1735   return control to the asio scheduler (slow path). As with AsyncRetFast, the
1736   stack must contain exactly one cell containing uninitialied garbage.
1738 | LdRetVal<T>, DParam(Gen), S(FramePtr), NF
1740   Load the return value from the already-returned-from ActRec pointed to by S0
1741   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1742   NativeImpl return a TypedValue in the C++ ABI registers.
1744 | DbgTrashRetVal, ND, S(FramePtr), NF
1746   For debugging purposes.  Store kTVTrashJITRetVal to the return value slot on
1747   the activation record pointed to by S0.
1749 | ReleaseVVAndSkip, ND, S(FramePtr), B
1751   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1752   nothing. If it is an ExtraArgs, deallocates the ExtraArgs structure.
1753   Otherwise it frees the VarEnv and jumps to block B. This instruction may not
1754   occur in an inlined call.
1756 | GenericRetDecRefs, ND, S(FramePtr), NF
1758   Does decrefs of all the current function's locals, where S0 is a pointer to
1759   the relevant activation record. This instruction may not occur in an inlined
1760   call.
1763 10. Stores
1765 | StMem, ND, S(PtrToGen) S(Gen), NF
1767   Store S1 into the location pointed to by S0.
1769 | StElem, ND, S(PtrToCell) S(Int) S(Cell), NF
1771   Store S2 into the location given by the index S1 from base pointer S0. The
1772   index in S1 is the number of bytes from the base in S0.
1774 | StLoc<localId>, ND, S(FramePtr) S(Gen), NF
1776   Store S1 to local number localId on the frame pointed to by S0.
1778 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Gen), NF
1780   Behaves just like StLoc, except the hard requirement that it is only emitted
1781   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1782   intraprocedural analysis to know whether the store is truly dead.
1784 | StLocRange<localIds>, ND, S(FramePtr) S(Gen), NF
1786   Store S1 to the local variables corresponding to localIds, on the frame
1787   pointed to by S0.
1789 | StClsRef<slot>, ND, S(FramePtr) S(Cls), NF
1791   Store S1 to class-ref slot `slot` on the frame pointed to by S0.
1793 | StRef, ND, S(BoxedCell) S(Cell), NF
1795   Store the value in S1 into the RefData pointed to by S0. Stores the
1796   RefData::m_type also.
1798 | StStk<offset>, ND, S(StkPtr) S(Gen), NF
1800   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1802 | DbgTrashStk<offset>, ND, S(StkPtr), NF
1804   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
1805   by S0, at a given offset (in cells).
1807 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
1809   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
1810   slots starting at the offset (in cells), and going toward higher memory
1811   addresses.
1813 | DbgTrashMem, ND, S(PtrToGen), NF
1815   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
1816   S0.
1819 11. Trace exits
1821 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), NF
1823   Sync the given vmfp and vmsp to their in-memory locations.
1825 | ReqBindJmp<bcOff,transFlags>, ND, S(StkPtr) S(FramePtr), T
1827   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
1829 | ReqRetranslate<transFlags>, ND, S(StkPtr) S(FramePtr), T
1831   Emit a jump to a service request that will chain to a retranslation of this
1832   tracelet.
1834   This instruction is used in exit traces for a type prediction that occurs at
1835   the first bytecode offset of a tracelet.
1837 | ReqRetranslateOpt<transId,bcOff>, ND, S(StkPtr) S(FramePtr), T
1839   Emit a service request to retranslate, with a higher optimization gear,
1840   translation transID, which starts at bcOff. This instruction is used in exit
1841   traces that trigger profile-guided optimizations.
1844 12. Refcounting and copies
1846 | Mov, DofS(0), S(Top), P
1848   Defines D as S0. May imply register-to-register moves at code generation
1849   time. Does not imply an incref or any other manipulation of S0.
1851 | IncRef, ND, S(Gen,Ctx), NF
1853   If S0 is a refcounted type, increment its refcount.
1855 | DecRef<locId>, ND, S(Gen,Ctx), CRc
1857   Decrease the reference count of S0 by one, and call a destructor for types
1858   that require it if it goes to zero.
1860   Note that although DecRef takes a Gen, we don't allow it to use information
1861   about the inner types of a BoxedCell. This is because we don't guard on the
1862   inner types of a BoxedCell except when doing LdRef. For any S0 that is a
1863   strict subtype of BoxedCell, the DecRef must just decref it as if it were a
1864   BoxedCell.
1866   The locId is just a hint to the runtime indicating which local variable is
1867   being DecRef'd, if any.
1869 | DecRefNZ, ND, S(Gen,Ctx), CRc
1871   Decrease the reference count of S0 by one, do not check if it goes to zero.
1872   This instruction can be used for more efficient code when it is provable that
1873   the reference count cannot go to zero.
1876 13. Misc
1878 | DefFP, D(FramePtr), NA, NF
1880   Creates a temporary D representing the current vm frame pointer.
1882 | DefSP<stackOff>, D(StkPtr), S(FramePtr), NF
1884   Creates a temporary D representing the current vm stack pointer. S0 is a
1885   pointer to the current frame. The 'stackOff' is the logical offset between S0
1886   and the stack pointer, but in the case of generators this is not the
1887   physical offset at runtime.
1889   This instruction is used at the beginning of tracelets to represent the state
1890   of the stack on entry and does not emit code.
1892 | FuncGuard<func,prologueAddrPtr>, ND, NA, NF
1894   Emits a function guard for func, and arranges to write the address of the
1895   following instruction to prologueAddrPtr.
1897 | Count, D(Int), S(Cell), Er
1899   Computes the number of elements in S0. The count of an array is the number of
1900   elements it contains, without recursing into containers in the array.
1901   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
1902   count of 0. The count of objects that implement the Countable interface is
1903   computed by returning the value of their count method. Objects that do not
1904   implement Countable have a count of 1.
1906 | CountArray,      D(Int), S(Arr),    NF
1908 | CountArrayFast,  D(Int), S(Arr),    NF
1910 | CountVec,        D(Int), S(Vec),    NF
1912 | CountDict,       D(Int), S(Dict),   NF
1914 | CountKeyset,     D(Int), S(Keyset), NF
1916 | CountCollection, D(Int), S(Obj),    NF
1918   Computes the number of elements in S0 using the same definition as Count, but
1919   with a restriction on the input type.
1921   CountArray expects any array. CountArrayFast expects an array whose kind is
1922   not kGlobalsKind. CountCollection expects a collection object.
1924 | Nop, ND, NA, NF
1926   Does nothing. It's sometimes useful for the simplifier to insert one of these
1927   in the instruction stream.
1929 | ExitPlaceholder, ND, NA, B
1931   Does nothing if executed. Semantically, this instruction carries a taken edge
1932   to a block that was a pure side-exit during initial IR generation.  This
1933   allows later passes to test conditions and create new exits from the region
1934   at this point in the program.
1936 14. Runtime helpers
1938 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), Er
1940   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
1941   a class) or implement (if S1 is an interface) S1, this instruction will raise
1942   a recoverable fatal error describing the type mismatch.
1944 | VerifyParamCallable, ND, S(Gen) C(Int), Er
1946   If S0 is not callable, as defined by the php function is_callable, this
1947   instruction will raise a recoverable fatal error describing the type
1948   mismatch.
1950 | VerifyParamFail, ND, C(Int), Er
1952   Assumes that parameter number S0 in the current function has failed a its
1953   type check. Depending on the typehint being verified and a number of runtime
1954   options, may coerce the parameter to the correct type or raise a recoverable
1955   fatal error describing the type mismatch.
1957 | VerifyParamFailHard, ND, C(Int), Er|T
1959   A terminal version of VerifyParamFail, to be used when the compiler can
1960   statically prove that this failure will result in a fatal error rather than a
1961   type coercion.
1963 | VerifyRetCallable, ND, S(Gen), Er
1965   Verify a return type hint.
1967 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), Er
1969   Verify a return type hint.
1971 | VerifyRetFail, ND, S(PtrToGen), Er
1973   Failure to verify a return type hint.
1975 | VerifyRetFailHard, ND, S(PtrToGen), Er|T
1977   Terminal version of VerifyRetFail, to be used when the compiler can prove
1978   that this failure will result in a fatal error.
1980 | RaiseHackArrParamNotice<type>, ND, S(Arr) S(Func) C(Int), Er
1982   Raise a HackArrCompatNotice corresponding to a parameter type-hint d/varray
1983   mismatch. S0 is the array being passed in. S1 is the function being
1984   called. S2 is the index of the parameter.
1986 | RaiseUninitLoc<localId>, ND, S(Str), Er
1988   Raise a notice for an uninitialized local variable.
1990 | RaiseUndefProp, ND, S(Obj) CStr, Er
1992   Raise a notice for an undefined property named S1 on the class of S0.
1994 | RaiseMissingArg<func,argc>, ND, NA, Er
1996   Raise a missing argument warning because only S1 arguments were passed to
1997   function S0.
1999 | RaiseError, ND, S(Str), T|Er
2001   Raises a fatal error with the text in S0 as its message.
2003 | RaiseWarning, ND, S(Str), Er
2005   Raises a warning with the text in S0 as its message.
2007 | RaiseNotice, ND, S(Str), Er
2009   Raises a notice with the text in S0 as its message.
2011 | RaiseArrayIndexNotice, ND, S(Int), Er
2013   Raises a notice that S0 is an undefined index for an array.
2015 | RaiseArrayKeyNotice, ND, S(StaticStr), Er
2017   Raises a notice that S0 is an undefined key for an array.
2019 | RaiseMissingThis, ND, S(Func), Er
2021   Raises an appropriate notice or fatal to indicate that Func was
2022   called with null $this. In most cases its a notice, but for
2023   builtins and special class methods its a fatal.
2025 | FatalMissingThis, ND, S(Func), T|Er
2027   Similar to RaiseMissingThis, but for cases where we know it will fatal.
2029 | RaiseVarEnvDynCall, ND, S(Func), Er
2031   Indicates that Func, which can access the caller's environment, was called
2032   dynamically. Depending on the setting of the `DisallowDynamicVarEnvFuncs`
2033   runtime option, this opcode might fatal, raise a warning, or do nothing. Used
2034   inside generated wrapper functions for builtins which can modify the caller's
2035   frame. These wrapper functions are called instead of the builtin when the
2036   builtin is called dynamically. Func should refer to the builtin, not the
2037   wrapper itself.
2039 | RaiseHackArrCompatNotice, ND, S(Str), Er
2041   Raises a Hack array compat notice with the text in S0 as its message.
2043 | RaiseParamRefMismatch<paramIndex>, ND, S(Func), Er
2045   Raise a warning indicating that the reffiness of a parameter was incorrectly
2046   annotated at the callsite.
2048 | CheckStaticLoc<func,staticLocalName>, ND, NA, B
2050   Check whether the static local variable named 'staticLocalName' for
2051   function 'func' is initialized in RDS, and branch if not.
2053 | InitStaticLoc<func,staticLocalName>, ND, S(Cell), NF
2055   Initialize the static local variable named 'staticLocalName' for
2056   function 'func' with S0.
2058 | InitClsCns<className,constName>, DCns, NA, Er|PRc
2060   Initialize the RDS entry for a constant for a class, invoking autoload if it
2061   is not defined. The initialized value is returned. This instruction may raise
2062   an undefined constant error if autoload cannot define the constant.
2064 | PrintStr,  ND, S(Str),  Er|CRc
2066 | PrintInt,  ND, S(Int),  Er|CRc
2068 | PrintBool, ND, S(Bool), Er|CRc
2070   Print for various types.
2072 | ConcatIntStr, D(Str), S(Int) S(Str), Er|PRc
2074   Concatenate S0 and S1 after converting S0 to String.
2076 | ConcatStrInt, D(Str), S(Str) S(Int), Er|CRc|PRc
2078   Concatenate S0 and S1 after converting S1 to String.
2080 | ConcatStrStr, D(Str), S(Str) S(Str), Er|CRc|PRc
2082   Concatenate S0 and S1.
2084 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), Er|CRc|PRc
2086   Concatenate S0, S1, and S2.
2088 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), Er|CRc|PRc
2090   Concatenate S0, S1, S2, and S3.
2092 | AddElemStrKey, D(Arr), S(Arr) S(Str) S(Cell), Er|CRc|PRc
2094   Add S2 to the array S0 for the key S1, and return the resulting array.
2096 | AddElemIntKey, D(Arr), S(Arr) S(Int) S(Cell), Er|CRc|PRc
2098   Add S2 to the array S0 for the key S1, and return the resulting array.
2100 | AddNewElem, D(Arr), S(Arr) S(Cell), Er|CRc|PRc
2102 | AddNewElemKeyset, D(Keyset), S(Keyset) S(Cell), Er|CRc|PRc
2104 | AddNewElemVec, D(Vec), S(Vec) S(Cell), CRc|PRc
2106   Add S1 as a new element to the array/keyset/vec S0.  (Note: S1 must actually
2107   be a subtype of InitCell for array invariants, but we can't assert this yet
2108   in the IR because many eval stack slots are not entirely typed wrt initness
2109   right now.)
2111 | DictAddElemStrKey, D(Dict), S(Dict) S(Str) S(Cell), Er|CRc|PRc
2113   Add S2 to the dict S0 for the key S1, and return the resulting dict.
2115 | DictAddElemIntKey, D(Dict), S(Dict) S(Int) S(Cell), Er|CRc|PRc
2117   Add S2 to the dict S0 for the key S1, and return the resulting dict.
2119 | ArrayAdd, D(Arr), S(Arr) S(Arr), Er|CRc|PRc
2121   Has the effects of the php + operator on the two source arrays.
2123 | AKExistsArr, D(Bool), S(Arr) S(Int,Str), Er
2125   Has the effects of array_key_exists(S0, S1).
2127 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
2129   Has the effects of array_key_exists(S0, S1).
2131 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
2133   Has the effects of array_key_exists(S0, S1).
2135 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), Er
2137   Has the effects of array_key_exists(S0, S1) on an object S0. This either does
2138   collection accesses, or uses the ArrayAccess API.
2140 | GetMemoKey, DMemoKey, S(Cell), Er|PRc
2142   Given a cell, produces a string or an int that can be used as a memoize cache
2143   key. Valid values for the input include all basic types, arrays and
2144   collections, and objects that implement IMemozieParam. Any other type will
2145   cause GetMemoKey to throw. This op can only be used within functions marked
2146   as memoize wrappers.
2148 | ArrayIdx, D(Gen), S(Arr) S(Int,Str) S(Cell), Er
2150   Checks if S0 contains the key S1, and returns the result if found. Otherwise
2151   S2 is returned.
2153 | DictIdx, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
2155   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2156   S2 is returned.
2158 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
2160   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2161   S2 is returned.
2163 | MethodExists, D(Bool), S(Cls) S(Str), NF
2165   Checks if the method named S1 exists on class S0.  S0 must be a normal class
2166   that is not abstract.
2168 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
2170   Creates a service request to bind the given target address. Returns a TCA
2171   pointing either to the service request (before the service request is
2172   satisfied) or to the native code for the given target address (once the
2173   service request is satisfied).
2175 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
2177 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
2179 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|Er
2181   These instructions are used to determine the target of a switch statement
2182   with target range [S1:S1 + S2), when invoked with the value S0. They call
2183   helper functions to check whether S0 is an numeric integer in the range
2184   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
2185   target of the default target, S2 + 1.
2187 | LdSSwitchDestFast, D(TCA), S(Gen), NF
2189 | LdSSwitchDestSlow, D(TCA), S(Gen), Er
2191   Load string switch destinations (two different compilation strategies).
2193 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
2194 |                                               S(StkPtr) S(FramePtr),
2195 |                                               Er
2197   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
2198   cells) and S1 are, respectively, the VM stack and frame pointers before this
2199   instruction. T is only present if the instruction pushes to the stack, in
2200   which case it is the type of the top stack element after the call. `bcOff' is
2201   the bytecode offset. `numPopped' is the number of stack cells consumed by the
2202   instruction, and `numPushed' is the number of stack cells produced by the
2203   instruction.
2205 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
2206 |                                           S(StkPtr) S(FramePtr),
2207 |                                           T
2209   Similar to InterpOne, but for instructions that may modify vmpc. This is
2210   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2211   in the context of the stub, not the InterpOneCF instruction.
2213 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), Er
2215   Returns a bool indicating whether the class, interface, or trait named by S0
2216   exists. Invokes autoload if S1 is true.
2218 | SetOpCell<op>, ND, S(PtrToCell) S(Cell), Er
2220   Performs S0 <op>= S1.
2222 | GetTime, D(Dbl), NA, NF
2224   Returns a double of the current time in seconds.
2226 | GetTimeNs, D(Int), C(Int), NF
2228   Returns the current time of the given clock id specified as clockid_t in
2229   nanoseconds as integer. This will call kernel's clock_gettime_ns() API. Note
2230   that this cannot be used for CLOCK_THREAD_CPUTIME_ID, as HHVM provides
2231   different semantics for that counter.
2233 | KillClsRef<slot>, ND, S(FramePtr), NF
2235   Mark the class-ref slot `slot` in frame S0 as no longer containing a
2236   meaningful value. This is used to aid in memory analysis. In debugging
2237   builds, it may overwrite the slot with a poison value.
2239 15. Generators & Closures
2241 | LdClosureCtx, DCtx, S(Obj), NF
2243   Load the context from the closure object S0 into D.
2244   May only be used in S0's closure Func.
2246 | StClosureCtx, ND, S(Obj) S(Ctx,Nullptr), CRc
2248   Store the context represented by S1 into the closure object S0. S1 may be a
2249   Nullptr when there is no context (i.e. the closure is being used in a
2250   non-method).
2252 | StClosureArg<offsetBytes>, ND, S(Obj) S(Gen), CRc
2254   Store one of the closure environment arguments (i.e. from the closure's use
2255   clause) from S1 into the closure object S0.
2257 | CreateGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2259   Create a Generator object and suspend the ActRec provided by S0 into its
2260   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2261   resume address to S2 and resume offset to S3.
2263 | CreateAGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2265   Create an AsyncGenerator object and suspend the ActRec provided by S0 into its
2266   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2267   resume address to S2 and resume offset to S3.
2269 | CreateAFWH, DAllocObj,
2270 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2271 |             CRc|PRc
2273   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2274   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2275   the native resume address to S2, resume offset to S3, and mark it blocked on
2276   non-finished child S4.
2278 | CreateAFWHNoVV, DAllocObj,
2279 |                 S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2280 |                 CRc|PRc
2282   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2283   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2284   the native resume address to S2, resume offset to S3, and mark it blocked on
2285   non-finished child S4.  This version of the instruction guarantees that the
2286   VarEnv is unused.
2288 | CreateAGWH, DAllocObj,
2289 |             S(FramePtr) S(TCA,Nullptr) C(Int) S(Obj),
2290 |             CRc|PRc
2292   Create an AsyncGeneratorWaitHandle object and link it to the AsyncGenerator
2293   associated with the ActRec provided by S0.  Set the native resume address
2294   to S1, resume offset to S2, and mark it blocked on non-finished child S3.
2296 | CreateAAWH<local,count>, DAllocObj, S(FramePtr) S(Int), PRc|Er
2298   Create an AwaitAllWaitHandle and add the count elements from frame contiguous
2299   frame locals beginning at local and extending count locals. S1 denotes the
2300   total number of non-completed waithandles. All locals must be subclasses of
2301   WaitHandle.
2303 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2305   Call c_StaticWaitHandle::CreateSucceeded.
2307 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), Er
2309   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2310   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2311   provided by S0.
2313   Injects S1 into the currently running scheduler instance and performs
2314   cross-scheduler and intra-scheduler cycle detection. Throws if the
2315   dependency cannot be established.
2317 | StArResumeAddr<offset>, ND, S(FramePtr) S(TCA), NF
2319   Store the resume address S1 into the Resumable whose ActRec is given by S0,
2320   marking the offset to resume at as `offset'.
2322 | ContEnter<spOffset,returnBCOffset>, DGenIter,
2323 |                                     S(StkPtr) S(FramePtr) S(FramePtr) S(TCA),
2324 |                                     Er
2326   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2327   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2328   embedded in the Generator object, and S3 is the address to jump to. The
2329   `returnBCOffset' will be stored to the m_soff field of the pre-live ActRec on
2330   the stack.
2332 | ContPreNext, ND, S(Obj) C(Bool), B
2334   Performs operations needed for the next() method of Generator object S0.
2335   If the generator is already running or finished, or it was not started yet
2336   and the S1 check-started flag is set, the branch B is taken. Otherwise,
2337   the generator is marked as running.
2339 | ContStartedCheck, ND, S(Obj), B
2341   Checks if the Generator object S0 has started, and if not branches to
2342   block B.
2344 | ContValid, D(Bool), S(Obj), NF
2346   Return true if a generator is not done, false otherwise.
2348 | ContStarted, D(Bool), S(Obj), NF
2350   Return true if a generator has been run at least once, i.e. is not in the
2351   Created state, false otherwise.
2353 | ContArIncKey, ND, S(FramePtr), NF
2355   Special-case key update for generator, ActRec of which is S0, which
2356   increments the key of a generator if that generator's key is an Int.
2357   This will cause undefined behavior if the generator's key is not an Int.
2359 | ContArIncIdx, D(Int), S(FramePtr), NF
2361   Increment the internal index in the Generator in S0, and return the new index
2362   value.
2364 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2366   Updates the internal index of generator with S1 if necessary, i.e. if S1
2367   is larger than the index. S0 is the pointer to the embedded ActRec.
2369 | LdContActRec, D(FramePtr), S(Obj), NF
2371   Loads the Generator object's ActRec, given a pointer to the generator
2372   object in S0.
2374 | LdContResumeAddr, D(TCA|Nullptr), S(Obj), NF
2376   Load the resume addr from the Generator in S0.
2378 | StContArState<state>, ND, S(FramePtr), NF
2380   Change the state of the Generator object which has frame pointer S0.
2382 | LdContArValue, DParam(Cell), S(FramePtr), PRc
2384   Loads 'value' from the Generator object ActRec of which is S0.
2386 | StContArValue, ND, S(FramePtr) S(Cell), CRc
2388   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2389   new value.
2391 | LdContArKey, DParam(Cell), S(FramePtr), PRc
2393   Loads 'key' from the Generator object ActRec of which is S0.
2395 | StContArKey, ND, S(FramePtr) S(Gen), CRc
2397   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2398   new value.
2400 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2402   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2403   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2405 | LdWHState, D(Int), S(Obj), NF
2407   Loads the state of the WaitHandle in S0, which is a value from the wait
2408   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2409   not a WaitHandle.
2411 | LdWHResult, DParam(Gen), S(Obj), NF
2413   Loads the result of the WaitHandle in S0. This instruction has undefined
2414   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2416 | LdWHNotDone, D(Int), S(Obj), NF
2418   Returns 1 if S0 is not finished, and 0 if S0 is finished.
2420 | CountWHNotDone<local,count>, D(Int), S(FramePtr), NF
2422   Returns the number of unfinished waithandles contained in the contiguous
2423   locals beginning at local and extending count.
2425 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2427   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2428   AsyncFunctionWaitHandle object in S0.
2431 16. Debugging, instrumentation, and profiling
2433 | IncStat, ND, C(Int) C(Int) C(Bool), NF
2435   Increment stat counter. S0 is the implementation defined stat counter index,
2436   S1 is the amount to increment the counter (may be negative), and S2 is a
2437   'force' flag. This opcode becomes a noop iff (force == false and runtime
2438   stats are not enabled) at translation time.
2440 | IncStatGrouped, ND, CStr CStr C(Int), NF
2442   Adds the value S2 to the counter named S1, in the category S0.
2444 | IncProfCounter<TransID>, ND, NA, NF
2446   Increment the profiling counter associated with translation TransID.
2448 | DbgAssertRefCount<AssertReason>, ND, S(Gen,TCtx), NF
2450   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2451   its count is implausible then execute a hardware trap instruction.
2453 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2455   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2456   start of each region, to emit some sanity checking code.
2458 | DbgAssertARFunc<offset>, ND, S(StkPtr) S(Func), NF
2460   Assert that S1 is the function in the ActRec given by s0+offset. If the
2461   assertion fails, execution is aborted via a hardware exception.
2463 | RBTraceEntry, ND, NA, NF
2465 | RBTraceMsg, ND, NA, NF
2467   Ring buffer tracing.
2469 | ZeroErrorLevel, D(Int), NA, NF
2471 | RestoreErrorLevel, ND, S(Int), NF
2473   Helper instructions for fast implementation of the PHP error silencing
2474   operator (@foo()).
2477 17. Iterators
2479 | IterInit<IterData>,   D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2481 | IterInitK<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2483 | WIterInit<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2485 | WIterInitK<IterData>, D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2487 | MIterInit<T,IterData>,  D(Bool), S(BoxedCell) S(FramePtr), Er
2489 | MIterInitK<T,IterData>, D(Bool), S(BoxedCell) S(FramePtr), Er
2491   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2492   the index of the iterator variable, keyId and valId are indices of local
2493   variables.
2495   Initializes the iterator variable whose index is given by iterId.
2496   This instruction creates the appropriate iterator for the array or object that
2497   S0 references, and rewinds the new iterator to its start. S0 points to the
2498   stack frame containing the iterator and local variables with the indices
2499   iterId, keyId and valId.
2501   If the new iterator is at its end (i.e., has no elements to iterate over),
2502   this instruction decrements the refcount of S0 and returns false; otheriwse,
2503   it stores a reference to S0 in the new iterator and returns true. If the
2504   iterator is not at its end, then this instruction stores the iterator's first
2505   value (and key) into the local variable with index valId (and keyId,
2506   respectively).
2508   The IterInit and IterInitK instructions always copy the array element by
2509   value.
2511   The WIterInit and WIterInitK instructions copy referenced array elements by
2512   reference, and non-referenced array elements by value.
2514   The MIterInit and MIterInitK instructions always copy the array element by
2515   reference, and take a type parameter indicating the inner type of S0.  (This
2516   must have been proven via guards prior to running this opcode.)  Right now T
2517   must be Obj or Arr.
2519   This instruction has the ConsumesRC property because it either decrements the
2520   reference count of S0 or stores a reference to S0 into the new iterator.
2522 | IterNext<IterData>,   D(Bool), S(FramePtr), Er
2524 | IterNextK<IterData>,  D(Bool), S(FramePtr), Er
2526 | WIterNext<IterData>,  D(Bool), S(FramePtr), Er
2528 | WIterNextK<IterData>, D(Bool), S(FramePtr), Er
2530 | MIterNext<IterData>,  D(Bool), S(FramePtr), NF
2532 | MIterNextK<IterData>, D(Bool), S(FramePtr), NF
2534   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2535   the index of the iterator variable, keyId and valId are indices of local
2536   variables.  S0 points to the stack frame containing the iterator and local
2537   variables with the indices iterId, keyId and valId.
2539   Advances the iterator variable whose index is given by iterId.
2541   If the iterator has reached the end, this instruction frees the iterator
2542   variable and returns false; otherwise, it returns true. If the iterator has
2543   not reached its end, then this instruction stores the iterator's next value
2544   (and key) into the local variable with index valId (and keyId, respectively).
2546   The IterInit and IterInitK instructions always copy the array element by
2547   value. The WIterInit and WIterInitK instructions copy referenced array
2548   elements by reference, and non-referenced array elements by value. The
2549   MIterNext and MIterNextK instructions always copy the array element by
2550   reference.
2552 | IterFree,  ND, S(FramePtr), NF
2554 | MIterFree, ND, S(FramePtr), NF
2556   Free the iterator variable whose index is given by S1 in the stack frame
2557   pointed to by S0.
2559 | DecodeCufIter<iterId>, D(Bool), S(Arr,Vec,Obj,Str)  S(FramePtr), Er
2561   Decode S0 as a callable, and write the decoded values to the iterator
2562   specified by IterId. Returns true iff it successfully decoded the callable.
2563   Does not raise warnings, or throw exceptions. Does not write to the `dynamic'
2564   field of the iterator, which must be done separately.
2566 | StCufIterFunc<iterId>, ND, S(FramePtr) S(Func), NF
2568   Store S1 to the `func' field of the iterator specified by IterId.
2570 | StCufIterCtx<iterId>, ND, S(FramePtr) S(Ctx,Nullptr), NF
2572   Store S1 to the `this' field of the iterator specified by IterId.
2574 | StCufIterInvName<iterId>, ND, S(FramePtr) S(Str,Nullptr), NF
2576   Store S1 to the `invName' field of the iterator specified by IterId.
2578 | StCufIterDynamic<iterId>, ND, S(FramePtr) S(Bool), NF
2580   Store S1 to the `dynamic' field of the iterator specified by IterId.
2582 | LdCufIterFunc<iterId,T>, DParam(Func), S(FramePtr), NF
2584   Load the `func' field of the iterator specified by IterId.
2586 | LdCufIterCtx<iterId,T>, DParam(Ctx|Nullptr), S(FramePtr), NF
2588   Load the `this' field of the iterator specified by IterId.
2590 | LdCufIterInvName<iterId,T>, DParam(Str|Nullptr), S(FramePtr), NF
2592   Load the `invName' field of the iterator specified by IterId.
2594 | LdCufIterDynamic<iterId>, D(Bool), S(FramePtr), NF
2596   Load the `dynamic' field of the iterator specified by IterId.
2598 | KillCufIter<iterId>, ND, S(FramePtr), NF
2600   Mark the iterator specified by IterId as no longer containing a values. This
2601   is used to aid in memory analysis. In debugging builds, it may overwrite the
2602   slot with a poison value.
2605 18. Member instruction support
2607 | LdMIStateAddr, D(PtrToMISGen), C(Int), NF
2609   Load an MInstrState address. Returns a pointer to offset S0 within the
2610   current MInstrState.
2612 | LdMBase, DParam(PtrToGen), NA, NF
2614   Load the current value of the member base register.
2616 | StMBase, ND, S(PtrToGen), NF
2618   Store a new value to the member base register. It is illegal for any
2619   instruction other than StMBase or InterpOne (when interpreting a member
2620   instruction) to modify the member base register.
2622 | FinishMemberOp, ND, NA, NF
2624   Mark the end of a member operation. This has no effect at runtime but exists
2625   to provide information for certain optimizations.
2627 All of the remaining opcodes in this section are simple wrappers around helper
2628 functions (specified in S0) to perform the corresponding vector operation. If
2629 S1 is a ConstCls it represents the context class for the operation.
2631 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2632 opcode, which almost always pushes its first stack input or a CountedStr as its
2633 stack result. The combinations of input types that cause SetM to push anything
2634 other than those two values are vanishingly rare in correct PHP programs, so
2635 these three instructions have been optimized for the common cases. SetNewElem
2636 and SetProp have no destination, allowing the compiler to predict that the
2637 SetM's output will be the same as its input (and optimize accordingly). If that
2638 turns out to not be the case at runtime, the instruction will throw an
2639 InvalidSetMException. The exception will hold a Cell containing the value the
2640 SetM should push on the stack instead of its input value. The runtime is
2641 responsible for catching this exception, finishing execution of the SetM
2642 instruction, pushing the value from the exception on the stack, and proceeding
2643 as appropriate (most likely with a side exit to the next bytecode instruction,
2644 since it has pushed an unexpected type onto the stack).
2646 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2647 characters within strings. When given a string base and a valid offset, SetElem
2648 returns a string representation of the newly inserted character. In all other
2649 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2650 exception when it detects invalid input types, or when trying to set a string
2651 offset that would grow the string beyond the maximum supported size.
2653 The input types that will cause the errors described above are listed here:
2655 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2656            Bool<false>.
2657 SetElem has the same base constraint as SetNewElem. In addition, the key must
2658         not be a subtype of {Arr|Obj}.
2659 SetProp will fail if the base is not a subtype of {Obj|Null}.
2661 Any instructions that take a pointer to an MInstrState struct use the various
2662 fields of that struct for holding intermediate values.
2664 | BaseG, D(PtrToRMembCell), S(Str), Er
2666   Get a base from global named S0.
2668   NB: BaseG returns either a PtrToGblGen, OR a pointer to a ref that is rooted
2669   in a GblGen.  (I.e. the unbox happens in the C++ helper that this instruction
2670   calls.)  If it is not a defining BaseG it can also return the
2671   init_null_variant, so for now it returns a PtrToRMembCell.
2673 | PropX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), Er
2675   Lookup intermediate property in S0, with key S1.
2677 | PropQ, D(PtrToMembGen), S(Obj,PtrToGen) S(StaticStr) S(PtrToMISGen), Er
2679   A nullsafe version of PropX, returns null if the base S0 is null.
2681 | PropDX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), MProp|Er
2683   Like PropX, but used for intermediate element lookups that may modify the
2684   base.
2686 | CGetProp, D(Cell), S(Obj,PtrToGen) S(Cell), PRc|Er
2688   Get property with key S1 from S0.
2690 | CGetPropQ, D(Cell), S(Obj,PtrToGen) S(StaticStr), PRc|Er
2692   A nullsafe version of CGetProp, returns null if the base S0 is null.
2694 | VGetProp, D(BoxedInitCell), S(Obj,PtrToGen) S(Cell), MProp|PRc|Er
2696   Get property with key S1 from base S0 as a reference.
2698 | BindProp, ND,
2699 |           S(Obj,PtrToGen) S(Cell) S(BoxedCell),
2700 |           MProp|Er
2702   Bind property with key S1 in base S0 to the reference in S2.
2704 | SetProp, ND, S(Obj,PtrToGen) S(Cell) S(Cell), MProp|Er
2706   Set property with key S1 in S0 to S2.
2708 | UnsetProp, ND, S(Obj,PtrToGen) S(Cell), Er
2710   Unset an object property.
2712 | SetOpProp<op>, D(Cell),
2713 |                S(Obj,PtrToGen) S(Cell) S(Cell),
2714 |                MProp|PRc|Er
2716   Set op propery with key S1 in base S0, using S2 as the right hand side.
2718 | IncDecProp<op>, D(Cell),
2719 |                 S(Obj,PtrToGen) S(Cell),
2720 |                 MProp|PRc|Er
2722   Increment/decrement property with key S1 in base S0.
2724 | EmptyProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2726   Returns true iff the property with key S1 in base S0 is empty.
2728 | IssetProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2730   Returns true iff the property with key S1 in base S0 is set.
2732 | ElemX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), Er
2734   Get intermediate element with key S1 from base S0. The base will not be
2735   modified.
2737 | ProfileMixedArrayOffset, ND, S(Arr) S(Int,Str), NF
2739   Profile the offset of the element keyed by S1 in S0.
2741 | CheckMixedArrayOffset<pos>, ND, S(AK(Mixed)) S(Int,Str), B
2743   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2744   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2745   fail, branch to B.  This check is allowed to have false negatives, in the
2746   case of int-like strings.
2748 | CheckArrayCOW, ND, S(ArrLike), B
2750   Check that S0 has a refcount of exactly 1; if not, branch to B.
2752 | ProfileDictOffset, ND, S(Dict) S(Int,Str), NF
2754   Profile the offset of the element keyed by S1 in S0.
2756 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
2758   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2759   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2760   fail, branch to B.  This check is allowed to have false negatives.
2762 | ProfileKeysetOffset, ND, S(Keyset) S(Int,Str), NF
2764   Profile the offset of the element keyed by S1 in S0.
2766 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
2768   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2769   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2770   fail, branch to B.  This check is allowed to have false negatives.
2772 | ElemArray,  D(PtrToMembGen), S(Arr) S(Int,Str), Er
2774 | ElemArrayW, D(PtrToMembGen), S(Arr) S(Int,Str), Er
2776 | ElemArrayD<T>, D(PtrToElemGen), S(PtrToGen) S(Int,Str), MElem|Er
2778 | ElemArrayU<T>, D(PtrToMembGen), S(PtrToGen) S(Int,Str), MElem|Er
2780   Similar to ElemX, but the base S0 is an array and the key S1 is an int/str.
2781   ElemArrayW is for Warn member instrs, ElemArrayD is for Define member instrs,
2782   and ElemArrayU is for Unset.
2784   ElemArray{D,U} both take a PtrToGen for the base operand, but expect it to be
2785   a PtrToArr or PtrToBoxedArr.  T is the type of the base array.
2787 | ElemMixedArrayK<pos>, D(PtrToElemGen), S(AK(Mixed)) S(Int,Str), NF
2789   Like ElemArray, but the element for S1 is at a known position `pos' in S0.
2791 | ElemVecD<T>, D(PtrToElemCell), S(PtrToGen) S(Int), MElem|Er
2793 | ElemVecU<T>, D(PtrToMembCell), S(PtrToGen) S(Int), MElem|Er
2795   Similar to ElemX, but the base S0 is a vec and the key S1 is an int. ElemVecD
2796   is for Define member instrs and ElemVecU is for Unset. (Other variations can
2797   be implemented without special IR instructions).
2799   ElemVec{D,U} both take a PtrToGen for the base operand, but expect it to be a
2800   PtrToVec or PtrToBoxedVec. T is the type of the base vec.
2802 | ElemDict,  D(PtrToMembCell), S(Dict) S(Int,Str), Er
2804 | ElemDictW, D(PtrToMembCell), S(Dict) S(Int,Str), Er
2806 | ElemDictD<T>, D(PtrToElemCell), S(PtrToGen) S(Int,Str), MElem|Er
2808 | ElemDictU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2810   Similar to ElemX, but the base S0 is a dict and the key S1 is an int/str.
2811   ElemDictW is for Warn member instrs, ElemDictD is for Define member instrs,
2812   and ElemDictU is for Unset.
2814   ElemDict{D,U} both take a PtrToGen for the base operand, but expect it to be
2815   a PtrToDict or PtrToBoxedDict.  T is the type of the base array.
2817 | ElemDictK<pos>, D(PtrToElemCell), S(Dict) S(Int,Str), NF
2819   Like ElemDict, but the element for S1 is at a known position `pos' in S0.
2821 | ElemKeyset,  D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2823 | ElemKeysetW, D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2825 | ElemKeysetU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2827   Similar to ElemX, but the base S0 is a keyset and the key S1 is an int/str.
2828   ElemKeysetW is for Warn member instrs and ElemKeysetU is for Unset.
2830   ElemKeysetU both take a PtrToGen for the base operand, but expect it to be
2831   a PtrToKeyset or PtrToBoxedKeyset.  T is the type of the base array.
2833 | ElemKeysetK<pos>, D(PtrToElemCell), S(Keyset) S(Int,Str), NF
2835   Like ElemKeyset, but the element for S1 is at a known position `pos' in S0.
2837 | ElemDX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2839   Like ElemX, but used for intermediate element lookups that may modify the
2840   base.
2842 | ElemUX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2844   Like ElemX, but used for intermediate element lookups that may modify the
2845   base as part of an unset operation.
2847 | ArrayGet, DArrElem, S(Arr) S(Int,Str), Er
2849   Get element with key S1 from base S0.
2851 | MixedArrayGetK<pos>, DArrElem, S(AK(Mixed)) S(Int,Str), NF
2853   Like ArrayGet, but the element for S1 is at a known position `pos' in S0.
2855 | DictGet, DDictElem, S(Dict) S(Int,Str), Er
2857   Get element with key S1 from base S0, throwing if the element is not present.
2859 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
2861   Get element with key S1 from base S0, returning null if the element is not
2862   present.
2864 | DictGetK<pos>, DDictElem, S(Dict) S(Int,Str), NF
2866   Like DictGet, but the element for S1 is at a known position `pos' in S0.
2868 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), Er
2870   Get element with key S1 from base S0, throwing if the element is not present.
2872 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
2874   Get element with key S1 from base S0, returning null if the element is not
2875   present.
2877 | KeysetGetK<pos>, DKeysetElem, S(Keyset) S(Int,Str), NF
2879   Like KeysetGet, but the element for S1 is at a known position `pos' in S0.
2881 | StringGet, D(StaticStr), S(Str) S(Int), PRc|Er
2883   Get string representing character at position S1 from base string S0.  Raises
2884   a notice if the position is out of bounds.
2886 | MapGet, D(Cell), S(Obj) S(Int,Str), PRc|Er
2888   Get element with key S1 from base S0.
2890 | CGetElem, D(Cell), S(PtrToGen) S(Cell), PRc|Er
2892   Get element with key S1 from S0.
2894 | VGetElem, D(BoxedInitCell), S(PtrToGen) S(Cell), MElem|PRc|Er
2896   Get element with key S1 from base S0 as a reference.
2898 | MemoGet<loc-begin, loc-count>, D(Cell), S(FramePtr) S(PtrToGen), PRc
2900   Perform a memoize cache lookup using S1. S1 must point to a dict serving as a
2901   memoize cache, or point to a RefData containing such a dict. The keys used
2902   are read from the exclusive local range [loc_begin, loc_begin+loc_count]
2903   (where S0 is the pointer to the frame containing the locals). If the lookup
2904   is successful, the element is returned (already inc-refd). If the element
2905   is not found, Uninit is returned. This op can only be used inside a function
2906   marked as a memoize wrapper.
2908 | MemoSet<loc-begin, loc-count>, ND, S(FramePtr) S(PtrToGen) S(Cell), MElem
2910   Store S2 in the memoize cache given by S1. S1 must point to a dict serving as
2911   a memoize cache or point to a RefData containing such a dict. They keys used
2912   as read from the exclusive local range [loc_begin, loc_begin+loc_count]
2913   (where S0 is the pointer to the frame containing the locals). S2 must not be
2914   Uninit and will be inc-refd by the operation internally. This op can only be
2915   used inside a function marked as a memoize wrapper.
2917 | BindElem, ND, S(PtrToGen) S(Cell) S(BoxedCell), MElem|Er
2919   Bind element with key S1 in base S0 to the reference S2.
2921 | ArraySet, D(Arr), S(Arr) S(Int,Str) S(Cell), PRc|CRc|Er
2923   Set element with key S1 in S0 to S2. The dest will be a new Array that should
2924   replace S0.
2926 | ArraySetRef, ND, S(Arr) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2928   Like ArraySet, but for binding operations on the array. S3 must point to a
2929   RefData with an array type when this instruction is executed, and it must be
2930   the same array that is in S0.
2932 | VecSet, D(Vec), S(Vec) S(Int) S(Cell), PRc|CRc|Er
2934   Set element with key S1 in S0 to S2. The dest will be a new Vec that should
2935   replace S0.
2937 | VecSetRef, ND, S(Vec) S(Int) S(Cell) S(BoxedCell), CRc|Er
2939   Like VecSet, but for binding operations on the vec. S3 must point to a
2940   RefData with a vec type when this instruction is executed, and it must be the
2941   same vec that is in S0.
2943 | DictSet, D(Dict), S(Dict) S(Int,Str) S(Cell), PRc|CRc|Er
2945   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
2946   replace S0.
2948 | DictSetRef, ND, S(Dict) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2950   Like DictSet, but for binding operations on the dict. S3 must point to a
2951   RefData with a vec type when this instruction is executed, and it must be the
2952   same dict that is in S0.
2954 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), Er
2956   Set element with key S1 in S0 to S2.
2958 | SetElem, DSetElem, S(PtrToGen) S(Cell) S(Cell), MElem|PRc|Er
2960   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
2961   case, where the logical result of the hhbc SetM is its right hand side. In
2962   the case of string bases, the SetM returns a new string containing the newly
2963   inserted character. So the return value of this instruction is Nullptr unless
2964   SetM needed to create a new counted string.
2966   Furthermore, in the case of "invalid offsets", SetElem may throw an
2967   InvalidSetMException (see discussion above).
2969 | SetWithRefElem, ND, S(PtrToGen) S(Gen) S(Gen), MElem|Er
2971   Set element with key S1 in S0 to S2.
2973 | UnsetElem, ND, S(PtrToGen) S(Cell), MElem|Er
2975   Unsets the element at key S1 in the base S0.
2977 | SetOpElem<op>, D(Cell),
2978 |                S(PtrToGen) S(Cell) S(Cell),
2979 |                MElem|PRc|Er
2981   Set op elem with key S1 in base S0, using S2 as the right hand side.
2983 | IncDecElem, D(Cell), S(PtrToGen) S(Cell), MElem|PRc|Er
2985   Increment/decrement element with key S1 in base S0.
2987 | SetNewElem, ND, S(PtrToGen) S(Cell), MElem|Er
2989   Append the value in S1 to S0.
2991 | SetNewElemArray, ND, S(PtrToGen) S(Cell), MElem|Er
2993   Append the value in S1 to S0, where S0 must be a pointer to a array.
2995 | SetNewElemVec, ND, S(PtrToGen) S(Cell), MElem|Er
2997   Append the value in S1 to S0, where S0 must be a pointer to a vec.
2999 | SetNewElemKeyset, ND, S(PtrToGen) S(Int,Str), MElem|Er
3001   Append the value in S1 to S0, where S0 must be a pointer to a keyset.
3003 | BindNewElem, ND, S(PtrToGen) S(BoxedCell), MElem|Er
3005   Append the reference in S1 to S0.
3007 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), Er
3009   Returns true iff the element at key S1 in the base S0 is set.
3011 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
3013   Returns true iff the element at key S1 in the base S0 is set.
3015 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
3017   Returns true iff the element at key S1 in the base S0 is set.
3019 | StringIsset, D(Bool), S(Str) S(Int), NF
3021   Returns true iff the string S0 has a character at position S1.
3023 | VectorIsset, D(Bool), S(Obj) S(Int), NF
3025   Returns true iff the element at key S1 in the base S0 is set.
3027 | PairIsset, D(Bool), S(Obj) S(Int), NF
3029   Returns true iff the element at key S1 in the base S0 is set.
3031 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
3033   Returns true iff the element at key S1 in the base S0 is set.
3035 | IssetElem, D(Bool), S(PtrToGen) S(Cell), Er
3037   Returns true iff the element at key S1 in S0 is set.
3039 | EmptyElem, D(Bool), S(PtrToGen) S(Cell), Er
3041   Returns true iff the element at key S1 in S0 is set and not equal (as defined
3042   by the hhbc Eq instruction) to false.
3044 | DictEmptyElem, D(Bool), S(Dict) S(Int,Str), NF
3046   Like EmptyElem, but specialized for dicts.
3048 | KeysetEmptyElem, D(Bool), S(Keyset) S(Int,Str), NF
3050   Like EmptyElem, but specialized for dicts.
3052 | CheckRange, D(Bool), S(Int) S(Int), NF
3054   Returns true iff S0 is in the range [0, S1).
3056 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Gen), Er|T
3058   Throws an OutOfBoundsException corresponding to an access of S0 with the key
3059   S1.
3061 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Gen), Er|T
3063   Throws an InvalidArgumentException corresponding to an access of S0 with the
3064   key S1, which has a type invalid for that array.
3066 | ThrowInvalidOperation, ND, S(Str), Er|T
3068   Throws an InvalidOperationException with a message indicating S0.
3070 | ThrowArithmeticError, ND, S(Str), Er|T
3072   Throws an ArithmeticError with a message indicating S0.
3074 | ThrowDivisionByZeroError, ND, S(Str), Er|T
3076   Throws a DivisionByZeroError with a message indicating S0.
3078 | ProfileArrayKind, ND, S(Arr), NF
3080   Profile the array kind of S0.
3082 | ProfileType, ND, S(Gen), NF
3084   Profile the type of S0.
3086 | ProfileMethod<rdsHandle,spOff>, ND, S(StkPtr) S(Cls,Nullptr), NF
3088   Profile the Func in the ActRec that was just pushed onto the stack.
3090 | CheckPackedArrayDataBounds, ND, S(AK(Packed),Vec) S(Int), B
3092   Checks that the index in S1 is within the bounds of the packed array or
3093   vector array in S0. Branches to B if the index is out of bounds.
3095 | LdPackedArrayDataElemAddr<T>, DParamPtr(Elem), S(AK(Packed),Vec) S(Int), NF
3097   Loads the address of the element at index S1 of the packed array or vec array
3098   in S0. This instruction assumes the array actually contains an element at
3099   that offset (IE, the array has the proper length).
3101 | ReservePackedArrayDataNewElem, D(Int), S(AK(Packed),Vec), B
3103   If there is room in the packed or vec array (which is assumed to be mutable),
3104   increments the array size and returns the index of the new last element
3105   (which you must initialize); else jumps to the taken branch.
3107 | LdVecElem, DVecElem, S(Vec) S(Int), NF
3109   Loads the element of the vec array in S0 at offset S1. This instruction
3110   assumes that the vec actually contains an element at that offset (IE, the vec
3111   has the proper length).
3113 | LdVectorSize, D(Int), S(Obj), NF
3115   Returns the size of the given Vector collection in S0.
3117 | VectorDoCow, ND, S(Obj), NF
3119   Triggers a copy on write for a Vector that has a live ImmVector sharing
3120   the same copy of the elements.
3122 | VectorHasImmCopy, ND, S(Obj), B
3124   Given a vector, check if it has a immutable copy and jump to the taken branch
3125   if so.
3127 | ColIsEmpty, D(Bool), S(Obj), NF
3129 | ColIsNEmpty, D(Bool), S(Obj), NF
3131   Returns whether a collection instance is empty or not.  S0 must be known to
3132   be an instance of a collection class at compile time.
3135 19. Exception/unwinding support
3137 | BeginCatch, ND, NA, NF
3139   Marks the beginning of a catch region. Exact behavior is implementation and
3140   architecture specific.
3142 | EndCatch<spOffset>, ND, S(FramePtr) S(StkPtr), T
3144   Marks the end of a catch region and returns control to the unwinder.  The
3145   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
3146   the vm stack pointer, however the stack pointer is not actually adjusted
3147   before this instruction returns control to the unwinder.  The unwinder
3148   instead relies on fixup map information to find the appropriate stack
3149   pointers.  Instead it's part of this instruction to facilitate assertions and
3150   memory effect analysis.
3152 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
3154   Branches to B if the currently executing catch region should return control
3155   to the unwinder rather than side exiting.  Used to control behavior in catch
3156   traces for the InvalidSetMException and TVCoercionException situations.
3158 | LdUnwinderValue<T>, DParam(Cell), NA, PRc
3160   Loads the value contained by the current unwinder exception.
3163 20. Function prologues
3165 | EnterFrame, ND, S(FramePtr), NF
3167   Stash the return address of the call in m_savedRip.
3169 | CheckStackOverflow, ND, S(FramePtr), Er
3171   Check if the stack depth has exceeded its limit.  If it has, jump to the
3172   stack overflow helper stub, which will throw.
3174 | InitExtraArgs<func,argc>, ND, S(FramePtr), Er
3176   Set up the ExtraArgs struct on the live ActRec.  If extra args are present
3177   and need to be discarded, they will be decref'd and may re-enter to run
3178   destructors.
3180 | InitCtx, ND, S(FramePtr) S(Ctx,Nullptr), CRc
3182   Store S1 to the m_this/m_cls field in the frame pointer S0.
3184   If InitCtx appears in an IR unit, it must dominate all occurrences of LdCtx
3185   and LdCctx with the same FramePtr.
3187 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), Er
3189   Test the implementation-specific surprise flags.  If they're nonzero, call
3190   the function enter helper.
3192 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), Er
3194   Test surprise flags and stack overflow at the same time.
3196 | CheckARMagicFlag, ND, S(FramePtr), B
3198   If the MagicDispatch flags on the ActRec pointed to by the frame pointer S0
3199   are not set, branch to block B.
3201 | LdARNumArgsAndFlags, D(Int), S(FramePtr), NF
3203   Load the value of m_numArgsAndFlags on the ActRec pointed to by the frame
3204   pointer S0.
3206 | StARNumArgsAndFlags, ND, S(FramePtr) S(Int), NF
3208   Store S1 to m_numArgsAndFlags on the ActRec pointed to by the frame pointer
3209   S0.
3211 | LdARInvName, D(Str), S(FramePtr), NF
3213   Load the value of m_invName off the ActRec pointed to by the frame pointer S0.
3214   The compiler should generate this only if it knows that m_invName is a
3215   StringData* (rather than, e.g., a VarEnv*).
3217 | StARInvName, ND, S(FramePtr) S(Str,Nullptr), CRc
3219   Store S1 to m_invName on the ActRec pointed to by the frame pointer S0.
3221 | PackMagicArgs, DArrPacked, S(FramePtr), PRc
3223   Call PackedArray::MakeVArray() with the value of numArgs() on the ActRec
3224   pointed to by the frame pointer S0 as the first argument, and the pointer to
3225   the first parameter in the frame as the second argument.
3227 | LdTVAux<ValidBits>, D(Int), S(Gen), NF
3229   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
3230   specifying which bits are allowed to be set.  The runtime may ignore it.
3232   Note that when we pass TypedValues around in registers, we usually use a byte
3233   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
3234   when we know that S0's m_type and m_aux were both materialized into the same
3235   64-bit register.
3237 /* Local Variables: */
3238 /* fill-column: 79 */
3239 /* End: */
3240 vim:textwidth=80