1 **********************************
2 * HipHop Bytecode v1 revision 18 *
3 **********************************
9 HipHop bytecode (HHBC) v1 is intended to serve as the conceptual basis for
10 encoding the semantic meaning of HipHop source code into a format that is
11 appropriate for consumption by interpreters and just-in-time compilers. By
12 using simpler constructs to encode more complex expressions and statements,
13 HHBC makes it straightforward for an interpreter or a compiler to determine
14 the order of execution for a program.
16 HHBC was designed with several competing goals in mind:
18 1) Run-time efficiency. The design of HHBC should be congruous to implementing
19 an efficient execution engine, whether it be an interpreter or a just-in-time
22 2) PHP 5.5 compatibility. It should be possible to compile valid PHP 5.5 source
23 code into HipHop bytecode in a way that preserves the semantic meaning of the
26 3) Simplicity. The design of HHBC should avoid features that could be removed
27 or simplified without compromising PHP 5.5 compatibility, run-time efficiency,
28 or design cleanliness.
34 Each HipHop source file is compiled into a separate "compilation unit", or
35 "unit" for short. Units are composed of bytecode and metadata.
37 A unit's bytecode is an array of bytes encoding a sequence of HHBC
38 instructions, where each instruction is encoded using one or more bytes. This
39 specification defines an instruction set and defines the behavior of each HHBC
40 instruction, but the exact byte values used to encode HHBC instructions is
41 currently unspecified.
43 A unit's metadata is a set of structures that provide essential information
44 that is needed at run time by the execution engine. This specification will
45 describe a unit's metadata as a set of named tables with ordered rows, but the
46 exact format of the metadata is currently unspecified.
48 Each instruction in a unit's bytecode can be referred to using a "bytecode
49 offset", which is the distance in bytes from the first byte of a unit's
50 bytecode to the first byte of the instruction.
52 A unit's bytecode is partitioned into sections called "functions". The unit's
53 metadata uses bytecode offsets to specify which instructions belong to which
56 When a unit is loaded at run time, the execution engine assigns the unit's
57 bytecode a logical range of addresses called "bytecode addresses". An
58 instruction is referred to at run time using its bytecode address.
64 HipHop bytecode models the flow of execution using a stack of frames referred
65 to as the "call stack". A "frame" is a structure that logically consists of a
66 header, a program counter (PC), a local variable store, an iterator variable
67 store, and an evaluation stack.
69 The frame at the top of the call stack is referred to as the "current frame".
70 The current frame represents the function that is currently executing. The
71 program counter (PC) of the current frame is referred to as the "current PC".
72 At any given time, the current PC holds the bytecode address of the current
73 instruction to execute. When the execution engine executes an instruction, the
74 current PC is updated to point to the next instruction. By default, the current
75 PC is updated to point to the byte that sequentially follows the last byte of
76 the current instruction in the bytecode. Some instructions override the default
77 behavior and explicitly update the current PC in a specific way.
79 HHBC provides special instructions to allow for calling a function and
80 returning from a function. When a function is called, a new frame is pushed
81 onto the call stack, and the PC of the new frame is initialized to the
82 appropriate entry point (typically the instruction of the function that is
83 sequentially first in the bytecode). The new frame becomes the current frame,
84 and the PC of the new frame becomes the current PC. When a function returns,
85 the current frame is popped off the call stack. The previous frame becomes the
86 current frame, and its PC becomes the current PC. The facility provided by the
87 execution engine that is responsible for handling function calls and returns is
88 called the "dispatcher".
90 Typically, a frame is removed from the call stack when its corresponding
91 function returns. However, a frame may be removed from the call stack before
92 its corresponding function returns in the course of processing an exception.
93 The facility provided by the execution engine that is responsible for
94 processing exceptions is called the "unwinder".
100 HHBC instructions may push and pop values on the current frame's evaluation
101 stack and they may read and write values to the current frame's local
102 variables. A value (or "cell") is a structure that contains a type identifier
103 and either data (for non-refcounted types) or a pointer to data (for refcounted
104 types). When a cell containing a pointer is duplicated, the new cell will point
105 to the same data as the original cell. When a cell containing a pointer is
106 duplicated or discarded, the execution engine is responsible for honoring the
107 data's refcount logic. Throughout this document, we use "cell" and "value"
113 A unit's bytecode is organized into functions. Each function has its own
114 metadata that provides essential information about the function, such as the
115 name of the function, how many local variables it has, how many iterator
116 variables it has, how many formal parameters it has, the names of the local
117 variables, the names of the formal parameters, how each parameter should be
118 passed (pass by value vs. pass by reference), whether each parameter has a
119 default value, and an upper bound for the maximum depth the evaluation stack
120 can reach at run time.
122 Each local variable and iterator variable has an id, and HHBC instructions can
123 reference these variables using these ids. The id space for local variables and
124 iterator variables are all distinct from each other. Thus local id 1 refers to
125 a different variable than iterator id 1. Local variable ids and iterator ids
126 are signed 32-bit integer values. No function may have more than 2^31 - 1 each
127 of local variables or iterator variables.
129 Some local variables have names associated with them (called "named local
130 variables"), while other local variables do not have names associated with them
131 (called "unnamed local variables"). All local variables that reference formally
132 declared parameters have names associated with them. Iterator variables do not
133 have names associated with them. Variables that have a name associated with
134 them will appear in the current variable environment (if they are defined),
135 while variables that do not have a name associated with them will never appear
136 in the current variable environment.
138 Formally declared parameters are considered to be local variables. Given a
139 function with n formally declared parameters, local ids 0 through n-1 will be
140 used to reference the formally declared parameters. Formal parameters without
141 default values are called "required parameters", while formal parameters with
142 default values are called "optional parameters".
144 The metadata of each function specifies a set of non-overlapping ranges of
145 bytecode that compose the function body, and it specifies the main entry point
146 and 0 or more default value ("DV") entry points (entry points are discussed in
147 more detail in the "Entry points" section).
149 The total size of the bytecode for the function body must not exceed 2^31 - 1
150 bytes. The bytecode for a function must be one contiguous range of bytecode.
152 Each function's metadata provides a "line number table" to allow mapping
153 bytecode offsets back to source line numbers. Each row in the line number table
154 consists of a source line number and a range of bytecode. The table is sorted
155 by starting bytecode offset, lowest offset first. The bytecode offset of the
156 beginning of each instruction in the function must belong to exactly one of the
157 ranges of bytecode in the line number table.
163 Functions may be grouped into metadata for classes. Class metadata objects are
164 used to describe several PHP-level language features including traits,
165 interfaces, closures, and (of course) classes.
167 Class metadata includes information about the properties on the class, special
168 functions on the class such as constructors or internal property initialization
169 routines (86sinit, 86pinit), class constants, list of used traits, list of
170 extended classes, list of implemented interfaces, etc.
172 Classes also include a flag indicating their "hoistability". For now this isn't
173 documented much here. See class.h.
179 Closures are implemented in HHBC as subclasses of Closure, in conjunction with
180 the CreateCl opcode. It is legal HHBC to create other subclasses of Closure (to
181 represent user code that attempts to do the same), but attempting to
182 instantiate one will result in a fatal error. The documentation of the CreateCl
183 opcode below lists the requirements for a closure subclass to be usable with
190 The basic compilation strategy for generators is to create bytecode functions
191 consisting of two parts.
193 The first part, executed when the generator function is called, must consist
194 of a CreateCont, which is responsible for suspending execution state into a new
195 Generator object (includes resume offset pointing to the start of the second
196 part of the function) and returning it back to the caller.
198 The second part is where the real user-level code of the generator should be
199 placed. ContEnter and ContRaise opcodes used in Generator's next(), send()
200 and raise() methods resume execution and transfer control to the resume offset
201 stored in the Generator object. The user-level code yields values using
202 Yield and YieldK opcodes and returns using RetC opcode.
208 Async functions are special type of functions representing asynchronous
209 execution. They can suspend while waiting for other asynchronous operations to
210 finish. This is achieved using Await opcode, which suspends execution into
211 an AsyncFunctionWaitHandle object. Once the given dependency is finished,
212 the scheduler resumes async function at the next opcode.
214 The async function body can be executed in 2 different modes. If the execution
215 was never suspended, we are in "eager execution" mode. The code executed after
216 the resume is executed in "resumed execution" mode.
218 The "eager execution" can end in 3 different ways. If a RetC opcode is reached,
219 the result is wrapped into a succeeded StaticWaitHandle and returned to the
220 caller. If an exception is thrown, it is wrapped into a failed StaticWaitHandle
221 and returned to the caller. Otherwise, if an Await opcode was reached and the
222 provided child WaitHandle has not finished, the current execution state is
223 suspended into an AsyncFunctionWaitHandle object and returned to the caller.
224 This mechanism allows fast execution if no blocking asynchronous operation was
227 The "resumed execution" mode is always entered from the scheduler. In this mode,
228 the async function either gets blocked on another dependency, or gets finished.
229 The scheduler is notified of these events using Await and RetC opcodes (or via
230 the unwinder if an exception was thrown) and the control is given back.
232 The async function implementation is still changing and the implementation may
233 change significantly, so this spec is staying light on details for now.
239 Entry points come in three varieties: the main entry point, default value ("DV")
240 entry points, and catch entry points.
242 Every function has exactly one main entry point. When a function is called, the
243 dispatcher will set the PC of the new frame to point to the main entry point if
244 either (1) the function does not have any optional parameters or (2) the caller
245 provides values for all of the optional parameters.
247 DV entry points are normally used to handle initializing optional parameters
248 that the caller did not provide. Generally the DV entries contain blocks that
249 initialize parameters, and then fall through directly into one another, with
250 the last block ending with a jump to the main entry point. This is not a
251 requirement, however. The dispatcher selects the appropriate DV entry point
252 based on the number of arguments passed into the function.
254 The main entry point and DV entry points are used by the dispatcher when
255 handling a function call. Each function's metadata provides an "entry point
256 table". Each row in the entry point table consists of a number of arguments and
257 the bytecode offset of the entry point that should be used by the dispatcher
258 (either the main entry point or a DV entry point).
260 Catch entry points are used by the unwinder to resume normal execution once a
261 matching "catch" block has been found and all the necessary cleanup has been
262 performed. When catch entry points are entered, the stack contains a single
265 More details about the unwinder and catch entry points can be found in the
266 "Exception handler (EH) table" and "Processing exceptions" sections.
272 Every compilation unit has a litstr table, a scalar array table, a function
273 table, and a class table.
275 The litstr table maps litstr ids to literal strings. Bytecodes that refer to
276 literal strings do so by litstr id. Litstr ids are signed 32-bit integer
277 values, which must be between 0 and 2^31 - 2 inclusive. In addition to the
278 per-unit litstr tables, a global table is built when generating an
279 "authoritative" repo (one in which all the PHP code is known at bytecode
280 generation time, and is guaranteed not to change). Global litstr ids can be
281 used in any unit, and are encoded in the range [2^30..2^31-2].
283 The scalar array table maps scalar array ids to a description of the contents
284 of a scalar array. An array is a scalar array if and only if each element of
285 the array is a null, boolean, integer, double, string, or a scalar array.
286 Furthermore, each element of a scalar array must be a cell. Finally, scalar
287 arrays may not recurse infinitely. Each scalar array id must be between 0 and
290 Each row in the function table contains a unique function id, a function name
291 specified by a litstr id, the bytecode offset for the corresponding function, a
292 flag that indicates if the function is unconditionally declared in the
293 outermost scope, and the function metadata. Note that there may be multiple
294 rows in the function table with same function name. However, there may not be
295 multiple rows that are marked as being unconditionally declared in the
296 outermost scope with the same function name. Each function id must be between 0
297 and 2^31 - 2 inclusive.
299 Each row in the class table contains a class name specified by a litstr id and
306 The caller may pass any number of parameters to the callee by pushing zero or
307 more cells or refs on the stack prior to executing a FCall* instruction. The
308 caller must pass the parameters in forward order, i.e. the first pushed value
309 corresponds to the first parameter, and so forth.
311 The FCall* instructions can be used to call a global function, a method on
312 an object, or a method from a class. The caller is responsible for evaluating
313 all of the parameters in forward order. When the caller executes the FCall*
314 instruction, the dispatcher creates a new frame and moves the parameters
315 prepared by the caller into the callee's variable environment. The dispatcher
316 then transfers control to the appropriate entry point of the callee (either the
317 main entry point or a DV entry point) based on the number of parameters passed.
319 When the callee executes the Ret* instruction, the dispatcher pushes the return
320 value onto the caller's evaluation stack. Then the dispatcher destroys the
321 callee's frame and transfers control back to the caller.
324 Exception handler (EH) table
325 ----------------------------
327 The metadata for each function provides an "exception handler (EH) table".
328 Each row in the EH table (called an "EH entry") consists of a non-negative
329 integer "region depth", a set of non-overlapping ranges of bytecode that
330 compose the "protected region", and an offset of a catch entry point.
332 Each range of bytecode is given by a starting offset and an ending offset,
333 where the starting offset is the bytecode offset of the first byte of the first
334 instruction in the range and the ending offset is the bytecode offset after the
335 last byte of the last instruction in the range.
337 Note that two or more EH entries may refer to the same catch entry point.
338 Regardless of whether multiple EH entries share the same catch entry point,
339 each EH entry in the EH table will be considered to declare a distinct
342 The EH entries in each EH table must honor the following rules:
344 1) For each EH entry with a region depth of D and a protected region P, for all
345 other protected regions Q that overlap with P, one of the following must be
346 true: (i) Q has a region depth that is greater than D and P is a superset of
347 (or equal to) Q; or (ii) Q has a region depth that is less than D and P is a
348 subset of (or equal to) Q.
350 2) For each EH entry with a region depth of D and a protected region P, for
351 each integer I where 0 <= I < D there must be exactly one protected region Q in
352 the EH table where Q's region depth equals I and P overlaps with Q.
355 Processing exceptions
356 ---------------------
358 HHBC allows programs to throw exceptions via the Throw instruction. When a
359 Throw instruction executes it transfers control to the unwinder, which follows
360 the steps below starting with step 1 until control is transferred elsewhere.
362 Step 1) Discard all temporary values on the evaluation stack.
364 Step 2) Consult the EH table of the current function. If there are any EH
365 entries that cover the current PC, choose the EH entry with the
366 greatest region depth and continue on to step 3. If no matching EH
367 entries are found go to step 4.
369 Step 3) Push the exception object implementing the Throwable interface on the
370 evaluation stack, then transfer control to the catch entry point. If
371 this catch entry point corresponds to a PHP try/catch statement, it is
372 responsible for finding the matching PHP catch clause (e.g. by using
373 the InstanceOfD opcode) and rethrowing the exception if no matching
376 Step 4) Check if we are handling user exception in an eagerly executed async
377 function. If so, pop the current frame, wrap the exception into a
378 failed StaticWaitHandle object, leave it on the stack as a return
379 value from the async function and resume execution.
381 Step 5) Pop the current frame off of the call stack and then check if the call
382 stack is empty. If the call stack is empty transfer control to the
383 unhandled exception facility passing along the exception. If the call
384 stack is not empty, then set the PC to point to the FCall* instruction
385 which invoked the frame we just discarded and go to step 1.
391 As object properties are accessed during execution, the execution engine is
392 responsible for following certain rules to honor each property's accessibility
395 The accessibility and visibility of a property in a given class is determined
396 by that class's definition and the definitions of all of that class's
397 ancestors. When a property is declared in a class definition (a "declared
398 property") it may be specified as being "public", "protected", or "private".
399 Accessibility and visibility are two related but distinct concepts. Depending
400 on the current context, a property may be visible and accessible, visible but
401 inaccessible, or invisible and inaccessible.
403 If a property P is declared with the "public" qualifier in the definition of
404 class C, for instances of class C and descendent classes the property P will be
405 visible and accessible in all contexts. If C has an ancestor that declares a
406 public property with the same name as P, C is said to "redeclare" property P,
407 and the declaration of P in class C is considered to refer to the same property
408 as the declaration in the ancestor class.
410 If a property P is declared as "protected" in the definition of class C, for
411 instances of class C the property P will be visible in all contexts, but only
412 accessible in the context of class C, an ancestor class, or descendent class.
413 When class C is loaded at run time, a semantic check must be performed to
414 ensure that all ancestor classes of C do not declare a property as "public"
415 with the same name as P. If C has an ancestor that declares a public property
416 with the same name as P, the execution engine must throw a fatal error when
417 class C is loaded. If C has an ancestor that declares a protected property with
418 the same name as P, C is said to "redeclare" property P, and the declaration of
419 P in class C is considered to refer to the same property as the declaration in
420 the ancestor class. Note that there may exist a class D that is a descendent of
421 C and declares a property as "public" with the same name as P. In such cases
422 the new "public" declaration in D is considered to refer to the same property
423 as the original "protected" declaration in C, and the "protected" qualifier
424 from the original declaration is effectively overridden by the "public"
425 qualifier from the new declaration. Class D is said to "redeclare" property P
426 with the "public" qualifier. Thus, for instances of class D and descendent
427 classes of D, property P will be visible and accessible in all contexts.
428 Finally, if a class E that is descendent of C does not redeclare P as public
429 and does not have an ancestor class that redeclares P as public, for instances
430 of class E the property P will be visible in all contexts, but only accessible
431 in the context of class E, an ancestor class of E, or a descendent class of E.
433 If a property P is declared with the "private" qualifier in the definition of
434 class C, for instances of class C the property P will be visible in all
435 contexts, but only accessible in the context of class C. For instances of
436 descendent classes of C, the property P will be visible and accessible in the
437 context of the class C, and in all other contexts property P will be invisible
438 and inaccessible. When class C is loaded at run time, a semantic check must be
439 performed to ensure that all ancestor classes of C do not declare a property as
440 "public" or "protected" with the same as P. If C has an ancestor that declares
441 a public or protected property with the same name as P, the execution engine
442 must throw a fatal error when class C is loaded. Note that descendent classes
443 of C may declare another property with the same name as P. The declaration of
444 property P as "private" in class C is considered to define a separate property
445 that is distinct from all other properties of the same name declared in
446 ancestor classes and descendent classes of C.
448 An instruction that accesses a property specifies the property by a name N via
449 a litstr id, a local variable id, or a cell consumed from the evaluation stack.
450 As noted above, it is possible for a class to have multiple distinct properties
451 named N. In cases where there are multiple distinct properties named N, the
452 visibility rules are used to determine which property is retrieved. If there is
453 a visible private property P named N, then property P is retrieved. Otherwise,
454 if there is a visible non-private property Q named N, then property Q is
455 retrieved. If there is no visible property named N, the behavior is determined
456 by the specific instruction. The semantic checks and the visibility rules
457 ensure that for any context there cannot be more than one visible private
458 property, and there cannot be more than one visible non-private property.
460 Some instructions can create a new property at run time with a name that is
461 different than the names of all declared properties that are visible in the
462 current context. Such properties are called "non-declared properties" or
463 "dynamic properties". Dynamic properties are considered to be visible and
464 accessible in all contexts.
466 If a declared property is unset, and then re-accessed/re-created, then it is
467 treated the same way as an invisible property with the same attributes as the
468 original declared property. Specifically, if the property gets created again,
469 it must have the same access attributes as the original declared property.
472 Magic property access methods
473 -----------------------------
475 Instructions that access properties may in some cases invoke a magic property
476 access method (__get, __set, __isset, or __unset) if an object implements the
477 method and the method is considered eligible for invocation. A magic property
478 access method is considered "eligible" for a given object if there is not a
479 frame on the call stack that corresponds to an invocation of the same method on
483 Static property access
484 ----------------------
486 As a class's static properties are accessed during execution, the execution
487 engine is responsible for following certain rules to honor each static
488 property's accessibility and visibility.
490 The accessibility and visibility of a static property in a given class is
491 determined by that class's definition and the definitions of all of that
492 class's ancestors. When a static property is declared in a class definition it
493 may be specified as being "public", "protected", or "private". Depending on the
494 current context, a static property may be visible and accessible, visible but
495 inaccessible, or invisible and inaccessible.
497 Conceptually, each class has a "static store" associated with it at run time
498 that provides storage for the static properties declared in the class's
499 definition. Static properties are accessed at run time by name through the
500 scope of a class. When an instruction accesses a static property through the
501 scope of class C, it will search the static store of C and then the static
502 stores of C's ancestors (starting with C's base class and moving up the
503 inheritance chain) for the first static property with the given name that is
504 visible in the current context.
506 If a static property S is declared with the "public" qualifier in the
507 definition of class C, the static property S when accessed through the scope of
508 class C or a descendent of C will be visible and accessible in all contexts.
509 Note that descendent classes of C may declare another static property with the
510 same name as S. The declaration in class C is considered to define a separate
511 static property that is distinct from all other static properties declared in
512 descendent classes of C.
514 If a static property S is declared with the "protected" qualifier in the
515 definition of class C, the static property S when accessed through the scope of
516 class C or a descendent of C will be visible in all contexts, but only
517 accessible in the context of class C, an ancestor class of C, or descendent
518 class of C. When class C is loaded at run time, a semantic check must be
519 performed to ensure that all ancestor classes of C do not declare a static
520 property as "public" with the same name as S. If C has an ancestor that
521 declares a public static property with the same name as S, the execution engine
522 must throw a fatal error when class C is loaded. Note that descendent classes
523 of C may declare another static property with the same name as S. The
524 declaration in class C is considered to define a separate static property that
525 is distinct from all other static properties declared in descendent classes of
528 If a static property S is declared with the "private" qualifier in the
529 definition of class C, the static property S when accessed through the scope of
530 class C will be visible in all contexts, but only accessible in the context of
531 class C. The static property S when accessed through the scope of a descendent
532 of C will only be visible and accessible in the context of class C. When class
533 C is loaded at run time, a semantic check must be performed to ensure that all
534 ancestor classes of C do not declare a static property as "public" or
535 "protected" with the same name as S. If C has an ancestor that declares a
536 public or protected static property with the same name as S, the execution
537 engine must throw a fatal error when class C is loaded. Note that descendent
538 classes of C may declare another static property with the same name as S. The
539 declaration in class C is considered to define a separate static property that
540 is distinct from all other static properties declared in descendent classes of
543 Note that instructions cannot create new static properties in a class that were
544 not declared in the class definition.
550 Any given value on the stack must either be a cell or ref at run time. However,
551 at bytecode generation time the specific flavor of a value on the stack is not
552 always known. HipHop bytecode uses symbols called "flavor descriptors" to
553 precisely describe what is known at bytecode generation about the state of the
554 evaluation stack at each instruction boundary.
556 Each instruction description specifies the flavor descriptor produced for each
557 of its outputs. Each description also specifies the flavor descriptor consumed
558 for each of the instruction's inputs.
560 Here is a description of each flavor descriptor:
562 C - cell; specifies that the value must be a typed value at run time
563 U - uninit; specifies that the value must be an uninitialized null at run
564 time; this is only used for FCallBuiltin, CreateCl, and CUGetL.
569 Because instructions specify constraints on the flavor descriptor of each
570 input, it is important to be able to determine if a given HHBC program
571 satisfies these constraints. A program that satisfies the constraints on the
572 inputs to each instruction is said to be "flavor-safe".
574 HHBC provides a set of verification rules that can be mechanically applied to
575 verify that an HHBC program is flavor-safe. All valid HHBC programs must be
576 verifiably flavor-safe, and the execution engine may refuse to execute HHBC
577 programs that cannot be verified.
579 At bytecode generation time, what is known about the state of the evaluation
580 stack at a given instruction boundary can be precisely described using flavor
583 In addition to being flavor-safe, there are other invariants that valid HHBC
584 programs must uphold with respect to metadata and how certain instructions are
587 Below is the complete list of verifiability rules. If the bytecode to be
588 executed does not come from a trusted source, it is the responsibility of the
589 bytecode execution engine to verify that these invariants hold.
591 1) The depth of the evaluation stack at any given point in the bytecode must be
592 the same for all possible control flow paths. The flavor descriptor of any
593 given slot on the evaluation stack at any given point in the bytecode must be
594 the same for all possible control flow paths.
596 2) No instruction may consume more values from the evaluation stack than are
597 available at that given point in the bytecode. Likewise, the flavor descriptor
598 of each slot on the evaluation stack must be compatible with the instruction's
599 inputs' flavor descriptors.
601 3) The evaluation stack must be empty at any offset listed as a catch entry
604 4) If a given instruction is not the target of a forward branch and it follows
605 a Jmp, Switch, SSwitch, RetC, Fatal, Throw, or NativeImpl instruction, the
606 evaluation stack before executing the given instruction must be empty.
608 5) Before executing the RetC instruction, the evaluation stack must contain
609 exactly one value and the flavor descriptor of the value must be cell.
610 Finally, before executing the NativeImpl instruction, the evaluation stack must
613 6) The code for the function body must be laid out in one contiguous block.
615 7) The last instruction of the function body must be either a control flow
616 without fallthrough or a terminal instruction.
618 8) The initialization state of each iterator variable must be known at every
619 point in the code and must be the same for all control paths. There are two
620 possible states: (1) uninitialized, and (2) "iter-initialized" (initialized
621 via IterInit*). Every range of bytecode for which an iterator variable i is
622 initialized must be protected by an EH entry with a catch handler that unsets
623 i by calling IterFree.
625 9) The iterator variable referenced by IterInit* must be in the uninitialized
626 state when the instruction executes. An iterator variable referenced by
627 IterNext* and IterFree must be in the "iter-initialized" state. Note that
628 IterInit* conditionally initialize the iterator variable, and IterNext*
629 conditionally free the iterator variable.
631 10) Each EH table must follow all of the rules specified in the "Exception
632 handler (EH) table" section.
634 11) Assertion (AssertRATL and AssertRATStk) instructions cannot be separated
635 from the following instruction by control flow. Practically speaking, this means
636 that the instruction immediately following an assertion cannot be a jump target.
638 12) Sequences of member instructions should be consistent and continuous. That
639 is, only member instructions and asserts may appear in the sequence, control
640 flow cannot interrupt the sequence, and the member op mode should be consistent
641 across all instructions in the sequence. This is because in the case of
642 exceptions the unwinder decides whether the member state is live by looking at
643 the instruction that threw.
648 Each instruction description below consists of a mnemonic, followed by 0 or
649 more immediate operands, followed by a stack transition description of the form
650 "[xn,...,x2,x1] -> [ym,...,y2,y1]", where "[xn,...,x2,x1]" is a list of flavor
651 descriptors describing what the instruction consumes from the evaluation stack
652 and "[ym,...,y2,y1]" is the list of flavor descriptors describing what the
653 instruction pushes onto the stack. x1 and y1 represent the topmost stack
654 elements before and after execution, respectively.
656 Each element of a stack transition may also contain an optional type
657 annotation. Here is the list of the type annotations used in instruction
660 Null - denotes the null type
661 Bool - denotes the boolean type
662 Int - denotes the integer type
663 Dbl - denotes the double-precision floating-point type
664 Str - denotes the string type
665 Vec - denotes the vec type
666 Dict - denotes the dict type
667 Keyset - denotes the keyset type
668 Obj - denotes the object type
669 Rec - denotes the record type
670 ArrLike - denotes array, vec, dict, or keyset
671 Class - denotes class pointer type
672 LazyClass - denotes lazy class type
673 EnumClassLabel - denotes enum class label type
675 Multiple type annotations may be combined together using the "|" symbol. For
676 example, the type annotation "Int|Dbl" means that a value is either integer or
679 Some instructions may contain multiple stack transition descriptions to express
680 the relationship between the types of the values consumed from the stack and
681 types of the values pushed onto the stack. Also, in some stack transition
682 descriptions, "<T>" is used as shorthand to represent any one specific type.
683 For example, a transition such as "[C:<T>] -> [C:<T>]" indicates that the type
684 of value that the instruction pushes onto the stack will match the type of
685 value that it consumed from the stack. Likewise, "<F>" is used as shorthand to
686 represent any one specific flavor descriptor.
688 $1 is used to refer to the value at the top of the evaluation stack, $2 is used
689 to refer to the value directly below $1 on the evaluation stack, $3 is used to
690 refer to the value directly below $2, and so forth. Also, %1 is used to refer
691 to the first immediate argument, and %2 is used to refer to the second
692 immediate argument. Thus, the indices used to refer to values on both
693 the evaluation stack and in the immediate arguments list are 1-indexed.
695 Note that the relative offset immediate used by a Jmp*, Iter*, Switch,
696 or SSwitch instruction is relative to the beginning of the instruction.
698 There are numerous instructions that operate on different kinds of locations.
699 Locations are specified using "location descriptors". The complete list of
700 location descriptors is given below:
702 L - local id; location is the local variable whose id is given by an
704 N - local name; location is the local variable whose name is given by the
706 G - global name; location is the global variable whose name is given by the
708 S - static property; location is the static property whose class is given by
709 value of a cell, and whose name is given by value of a cell.
710 C - cell; location is a temporary value given by a cell.
711 H - $this; location is the $this pointer in the current frame. Must only be
712 used in a frame that is known to have a non-null $this pointer; CheckThis
713 is most commonly used to ensure this.
715 There are several groups of similarly named instructions where the name of each
716 instruction ends with a different location descriptor (for example, Set*). Each
717 instruction in the group performs similar actions but takes different kinds of
718 inputs to specify the location to access.
720 There are numerous instructions which incorporate a readonly immediate.
721 These opcodes can be Mutable, Any, ReadOnly, CheckROCOW, or CheckMutROCOW and
722 specify the readonlyness constraint on the property read/written by the
723 instruction. The Any immediate is equivalent to no runtime check.
724 The ReadOnly immediate specifies this property must be readonly.
725 The Mutable immediate specifies this property must be mutable. The CheckROCOW
726 immediate specifies this property must be readonly and COW. The CheckMutROCOW
727 immediate specifies this property must be mutable unless it is readonly
730 The member instructions provide functionality to operate on elements and
731 properties. Many of these instructions incorporate a readonly immediate
732 argument, as well as an immediate argument which specifies one of the
733 following member descriptors.
735 EC - consume a cell from the evaluation stack as an element
736 EL:<id> - consume a local given by an immediate id as an element
737 ET:<id> - consume a litstr given by an immediate id as an element
738 EI:<int> - consume a immediate integer as an element
739 PC - consume a cell from the evaluation stack as a property
740 PL:<id> - consume a local given by an immediate id as a property
741 PT:<id> - consume a litstr given by an immediate id as a property
742 QT:<id> - a nullsafe version of PT:<id>. The null-base doesn't issue
743 a warning, and no stdClass promotion in write context for the
744 base happens. Consume a litstr given by an immediate id
746 W - synthesize a new element (no corresponding local variable or
747 evaluation stack slot)
749 The instruction set is organized into the following sections:
750 1. Basic instructions
751 2. Literal and constant instructions
752 3. Operator instructions
753 4. Control flow instructions
755 6. Isset and type querying instructions
756 7. Mutator instructions
759 10. Member instructions
760 11. Iterator instructions
761 12. Include, eval, and define instructions
762 13. Miscellaneous instructions
763 14. Generator creation and execution
767 1. Basic instructions
768 ---------------------
772 No operation. This instruction does nothing.
777 Pop. Discards the value on the top of the stack.
779 PopU2 [U C:<T>] -> [C:<T>]
781 Pop two. Discards the uninit underneath the cell on top of the stack.
783 PopL <local variable id> [C] -> []
785 Teleport value from the stack into a local. This instruction marks the local
786 variable given by %1 as defined and pops and stores the value $1 into the
787 local variable. This instruction behaves as if it was a SetL PopC pair, but
788 might be implemented more efficiently.
790 Dup [C:<T>] -> [C:<T> C:<T>]
792 Duplicate. Duplicates the cell $1 and pushes it onto the stack.
794 CGetCUNop [C|U:<T>] -> [C:<T>]
796 Convert a cell or uninit value to a cell, no op. This is a flavor-safety only
797 opcode and should only be used when $1 is statically known to be a cell.
799 UGetCUNop [C|U:<T>] -> [U:<T>]
801 Convert a cell or uninit value to an uninit, no op. This is a flavor-safety
802 only opcode and should only be used when $1 is statically known to be an
805 2. Literal and constant instructions
806 ------------------------------------
812 Push constant. Null pushes null onto the stack, True pushes true onto the
813 stack, and False pushes false onto the stack.
817 Push an uninitialized null on the stack.
819 Int <signed 64-bit integer value> [] -> [C:Int]
820 Double <double value> [] -> [C:Dbl]
821 String <litstr id> [] -> [C:Str]
822 Vec <scalar vec id> [] -> [C:Vec]
823 Dict <scalar dict id> [] -> [C:Dict]
824 Keyset <scalar keyset id> [] -> [C:Keyset]
825 LazyClass <litstr id> [] -> [C:LazyClass]
826 EnumClassLabel <litstr id> [] -> [C:EnumClassLabel]
828 Push immediate. Pushes %1 onto the stack.
830 NewDictArray <capacity hint> [] -> [C:Dict]
832 New dict, with a capacity hint. Creates a new dict and pushes
833 it onto the stack. The implementation may make use of the hint in %1 to
834 pre-size the array. The hint %1 must be greater than or equal to 0.
836 NewStructDict <litstr id vector> [C..C] -> [C:Dict]
838 New dict array. Creates a new dict array from the names given in %1 and
839 values from the stack. The vector of litstr ids gives the element names, one
840 value for each name is popped from the stack. Names are in array insertion
841 order, and values were pushed onto the stack in insertion order, so are added
842 to the array in reverse order (the topmost value will become the last element
843 in the array). For example:
845 NewStructDict < "a" "b" > [ 1 2 ] -> [ dict("a"=>1, "b"=>2) ]
847 NewVec <num elems> [C..C] -> [C:Vec]
849 New vec. Creates a new vec from the top %1 cells on the stack, pops those
850 cells, then pushes the new vec onto the stack. Elements are pushed on the
851 stack in vec insertion order.
853 NewKeysetArray <num elems> [C..C] -> [C:Keyset]
855 New keyset. Creates a new keyset from the top %1 cells on the stack, pops
856 those cells, then pushes the new keyset onto the stack. Elements are pushed
857 on the stack in keyset insertion order.
859 AddElemC [C C C] -> [C:Arr|Dict]
861 Add element. If $3 is an array or dict, this instruction executes $3[$2] = $1
862 and then pushes $3 onto the stack.
864 If $3 is not an array or dict, this instruction throws a fatal error.
866 AddNewElemC [C C] -> [C:Arr|Vec|Keyset]
868 Add new element. If $2 is an array, vec, or keyset this instruction executes
869 $2[] = $1 and then pushes $2 onto the stack.
871 If $2 is not an array, vec, or keyset, this instruction throws a fatal error.
873 NewCol <coll type> [] -> [C:Obj]
875 New collection. Creates a empty new collection of type %1, and pushes it
876 onto the stack. %1 must be one of the values of the CollectionType enum other
879 NewPair [C C] -> [C:Obj]
881 New Pair collection. Creates a Pair from the top 2 cells on the stack, and
882 pushes it onto the stack. Values were pushed onto the stack in the order
883 they exist in the pair, so are added to it in reverse order (the top value
884 on the stack will become the second element of the pair).
886 ColFromArray <coll type> [C:Arr] -> [C:Obj]
888 Create a collection of type %1 from array $1, and pushes the collection onto
889 the stack. %1 must be one of the values of the CollectionType enum other
890 than Pair. The array will be used to implement the collection without
891 conversion or duplication, thus it should not contain references. $1 must be
892 in packed mode if %1 is Vector or ImmVector, and must be in mixed mode
895 Note that integer-like string keys are converted to integers in arrays, but
896 not in collections; thus not all collections can be created using this
899 CnsE <litstr id> [] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
901 Get constant. Pushes the value of the global constant named %1 onto the stack
902 as a cell. If there is no constant named %1, throws a fatal error.
904 ClsCns <litstr id> [C:Class] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
906 Get class constant. This instruction pushes the value of the class constant
907 named %1 from the class $1 onto the stack. If there is no class
908 constant named %1 in class $1, this instruction throws a fatal error.
910 ClsCnsL <local variable id> [C:Class] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
912 Get class constant (local). This instruction pushes the value of the class
913 named %1 from the class $1 onto the stack. If there is no class constant
914 named %1 in class $1, this instruction throws a fatal error.
916 ClsCnsD <litstr id> <litstr id> [] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
918 Get class constant (direct). This instruction first checks if %2 matches the
919 name of a defined class. If %2 does not match the name of a defined class,
920 this instruction will invoke the autoload facility passing in the class name
921 %2, and then it will again check if %2 matches the name of a defined class.
922 If %2 still does not match the name of a defined class this instruction
923 throws a fatal error.
925 Next, this instruction pushes the value of the class constant named %1 from
926 class %2 onto the stack. If there is no class constant named %1 in class %2,
927 this instruction throws a fatal error.
929 File [] -> [C:Static Str]
930 Dir [] -> [C:Static Str]
931 Method [] -> [C:Static Str]
933 Push string. File pushes __FILE__ onto the stack, Dir pushes __DIR__ onto
934 the stack, and Method pushes __METHOD__.
936 FuncCred [] -> [C:Obj]
938 Push object holding information about current executing function
941 ClassName [C:Class] -> [C:Static Str]
943 Push the name of the class in $1 as a string.
945 LazyClassFromClass [C:Class] -> [C:LazyClass]
947 Push the lazy class corresponding to the class in $1.
949 EnumClassLabelName [C:EnumClassLabel] -> [C:Static Str]
951 Push the name of the enum class label in $1 as a string.
953 3. Operator instructions
954 ------------------------
956 Concat [C C] -> [C:Str]
958 Concatenation (.). Pushes ((string)$2 . (string)$1) on the stack.
960 ConcatN <n> [C..C] -> [C:Str]
962 Concatenation (.). Pushes ((string)$n . ... . (string)$1) on the stack.
964 Add [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
965 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl)
967 Addition (+). Pushes ($2 + $1) onto the stack. This instruction throws a
968 fatal error if either $1 or $2 is not numeric.
970 Sub [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
971 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl)
973 Subtraction (-). Pushes ($2 - $1) onto the stack. This instruction throws a
974 fatal error if either $1 or $2 is not numeric.
976 Mul [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
977 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl)
979 Multiplication (*). Pushes ($2 * $1) onto the stack. This instruction throws a
980 fatal error if either $1 or $2 is not numeric.
982 Div [C C] -> [C:Bool|Int|Dbl]
983 [C:Dbl C:Int] -> [C:Bool|Dbl]
984 [C:Int C:Dbl] -> [C:Bool|Dbl]
985 [C:Dbl C:Dbl] -> [C:Bool|Dbl]
987 Division (/). Pushes ($2 / $1) onto the stack. This instruction throws a
988 fatal error if either $1 or $2 is not numeric, or if $1 is zero.
990 Mod [C C] -> [C:Bool|Int]
992 Modulus (%). Pushes ((int)$2 % (int)$1) onto the stack. This instruction throws a
993 fatal error if either $1 or $2 is not numeric, or if $1 is zero.
995 Pow [C C] -> [C:Int|Dbl]
997 Power. Pushes $2 raised to the power of $1 onto the stack. This instruction throws a
998 fatal error if either $1 or $2 is not numeric.
1002 Logical not (!). Pushes (!(bool)$1) onto the stack.
1004 Same [C C] -> [C:Bool]
1006 Same (===). Pushes ($2 === $1) onto the stack.
1008 NSame [C C] -> [C:Bool]
1010 Not same (!==). Pushes ($2 !== $1) onto the stack.
1012 Eq [C C] -> [C:Bool]
1014 Equals (==). Pushes ($2 == $1) onto the stack.
1016 Neq [C C] -> [C:Bool]
1018 Not equal (!=). Pushes ($2 != $1) onto the stack.
1020 Lt [C C] -> [C:Bool]
1022 Less than (<). Pushes ($2 < $1) onto the stack.
1024 Lte [C C] -> [C:Bool]
1026 Less than or equal to (<=). Pushes ($2 <= $1) onto the stack.
1028 Gt [C C] -> [C:Bool]
1030 Greater than (>). Pushes ($2 > $1) onto the stack.
1032 Gte [C C] -> [C:Bool]
1034 Greater than or equal to (>=). Pushes ($2 >= $1) onto the stack.
1036 Cmp [C C] -> [C:Int]
1038 Comparison. Pushes either -1, 0, or 1 onto the stack if ($1 < $2), ($1 ==
1039 $2), or ($1 > $2), respectively.
1041 BitAnd [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1042 [C:Str C:Str] -> [C:Str]
1044 Bitwise and (&). Pushes ($2 & $1) onto the stack. If either $1 or $2 is an
1045 object, this instruction throws a fatal error.
1047 BitOr [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1048 [C:Str C:Str] -> [C:Str]
1050 Bitwise or (|). Pushes ($2 | $1) onto the stack. If either $1 or $2 is an
1051 object, this instruction throws a fatal error.
1053 BitXor [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1054 [C:Str C:Str] -> [C:Str]
1056 Bitwise xor (^). Pushes ($2 ^ $1) onto the stack. If either $1 or $2 is an
1057 object, this instruction throws a fatal error.
1059 BitNot [C:<T>] -> [C:Int] (where T != Str)
1062 Bitwise not (~). Pushes (~$1) onto the stack. If $1 is null, a boolean, an
1063 array, or an object, this instruction throws a fatal error.
1065 Shl [C C] -> [C:Int]
1067 Shift left (<<). Pushes ((int)$2 << (int)$1) onto the stack. This instruction
1068 never throws a fatal error.
1070 Shr [C C] -> [C:Int]
1072 Shift right (>>). Pushes ((int)$2 >> (int)$1) onto the stack. This
1073 instruction never throws a fatal error.
1075 CastBool [C] -> [C:Bool]
1077 Cast to boolean ((bool),(boolean)). Pushes (bool)$1 onto the stack.
1079 CastInt [C] -> [C:Int]
1081 Cast to integer ((int),(integer)). Pushes (int)$1 onto the stack.
1083 CastDouble [C] -> [C:Dbl]
1085 Cast to double ((float),(double),(real)). Pushes (double)$1 onto the stack.
1087 CastString [C] -> [C:Str]
1089 Cast to string ((string),(binary)). Pushes (string)$1 onto the stack. If $1
1090 is an object that implements the __toString method, the string cast returns
1091 $1->__toString(). If $1 is an object that does not implement __toString
1092 method, the string cast throws a fatal error.
1094 CastVec [C] -> [C:Vec]
1096 Cast to vec array. Pushes vec($1) onto the stack.
1098 CastDict [C] -> [C:Dict]
1100 Cast to dict. Pushes dict($1) onto the stack.
1102 CastKeyset [C] -> [C:Keyset]
1104 Cast to keyset. Pushes keyset($1) onto the stack.
1106 InstanceOf [C C] -> [C:Bool]
1108 Instance of (instanceof). If $1 is a string and it matches the name of a
1109 defined class and $2 is an object that is an instance of $1, this instruction
1110 pushes true onto the stack. If $1 is an object and get_class($1) matches the
1111 name of a defined class and $2 is an object that is an instance of
1112 get_class($1), this instruction pushes true onto the stack. If $1 is not a
1113 string or an object, this instruction throws a fatal error.
1115 InstanceOfD <litstr id> [C] -> [C:Bool]
1117 Instance of direct (instanceof). If %1 matches the name of a defined class
1118 and $1 is an instance of the %1, this instruction pushes true onto the stack,
1119 otherwise it pushes false onto the stack.
1121 Select [C C C] -> [C]
1123 Pushes (bool)$1 ? $2 : $3 onto the stack.
1125 DblAsBits [C] -> [C]
1127 If $1 is a double, reinterpret it as an integer (with the same bit-pattern)
1128 and push it onto the stack. Otherwise, push 0.
1130 IsLateBoundCls [C] -> [C:Bool]
1132 If $1 is a subtype of the current late-bound class, this instruction pushes
1133 true onto the stack, otherwise it pushes false onto the stack.
1135 IsTypeStructC <type struct resolve op> [C C] -> [C:Bool]
1137 If $1 matches the type structure of a defined type and $2 is a subtype of $1,
1138 this instruction pushes true onto the stack, otherwise it pushes false onto
1140 If the type struct resolve op is Resolve, then resolves the type structure in
1141 $1 before performing the subtype check.
1142 If the type struct resolve op is DontResolve and the given type structure is
1143 unresolved, then this instruction raises an error.
1145 ThrowAsTypeStructException <as exception kind> [C C] -> []
1147 Throws a user catchable type assertion exception that indicates what the
1148 given type of $2 is, what the expected type is (given on $1) and which key
1149 it failed at, if applicable. If the exception kind is Error, then throw
1150 a recoverable error. If it is Typehint raise a TypehintViolationException.
1152 CombineAndResolveTypeStruct <num type structures> [C..C] -> [C]
1154 Consumes a type structure from the stack that potentially has holes in it,
1155 and (%1 - 1) amount of type structures from the stack and merges these type
1156 structures into the first type structure. Merging means that the hole on the
1157 first type structure denoted by the reified type kind will be replaced by the
1158 type structure whose id matches the id provided at this field. If the id at
1159 this field does not match that of any given type structures or the provided
1160 inputs are not valid type structures, this instruction throws a fatal error.
1161 After merging, this instruction resolves the final type structure and pushes
1164 Print [C] -> [C:Int]
1166 Print (print). Outputs (string)$1 to STDOUT and pushes the integer value 1
1169 Clone [C] -> [C:Obj]
1171 Clone (clone). Clones $1 and pushes it onto the stack. If $1 is not an
1172 object, this instruction throws a fatal error.
1174 Exit [C] -> [C:Null]
1176 Exit (exit). Terminates execution of the program.
1178 If $1 is an integer, this instruction will set the exit status to $1, push
1179 null onto the stack, and then it will terminate execution.
1181 If $1 is not an integer, this instruction will output (string)$1 to STDOUT,
1182 set the exit status to 0, push null onto the stack, and then it will
1183 terminate execution.
1185 Fatal <fatal subop> [C] -> []
1187 Fatal. This instruction throws a fatal error using $1 as the error message.
1188 If $1 is not a string, this instruction throws a fatal error with an error
1189 message that indicates that the error message was not a string. Setting %1 to
1190 0 will throw a runtime fatal error with a full backtrace. Setting %1 to 1
1191 will throw a parse fatal error with a full backtrace. Setting %1 to 2 will
1192 throw a runtime fatal error with the backtrace omitting the top frame.
1194 StaticAnalysisError [] -> []
1196 Produces either a request level Fatal or a process level assertion indicating
1197 that code believed to be unreachable during static analysis has been executed.
1200 4. Control flow instructions
1201 ----------------------------
1203 Enter <rel offset> [] -> []
1205 Enter the function body. This instruction is used at the end of default value
1206 initializers to transfer control to the function body.
1208 Jmp <rel offset> [] -> []
1210 Jump. Transfers control to the location specified by %1.
1212 JmpZ <rel offset> [C] -> []
1214 Jump if zero. Conditionally transfers control to the location specified by %1
1215 if (bool)$1 == (bool)0.
1217 JmpNZ <rel offset> [C] -> []
1219 Jump if not zero. Conditionally transfers control to the location specified
1220 by %1 if (bool)$1 != (bool)0.
1222 Switch <bounded> <base> <offset vector> [C] -> []
1224 Switch over integer case values. If bounded == SwitchKind::Unbounded, the
1225 implementation will assume that $1 is an integer in the range [0,
1226 length(vector)) and unconditionally transfer control to the location
1227 specified by vector[$1]. Undefined behavior will result if $1 is not an
1228 integer inside this range. If bounded == SwitchKind::Bounded, the following
1231 For a bounded Switch, the last two elements of the offset vector are special:
1232 they represent the first non-zero case and the default case, respectively.
1233 base + length(vector) - 2 must not be greater than 2^63-1. If $1 === true,
1234 control will be transferred to the location specified by
1235 vector[length(vector) - 2]. If $1 is equal (as defined by Eq) to any integer
1236 $n in the range [base, base + length(vector) - 2), control will be
1237 transferred to the location specified by vector[$n - base]. Otherwise,
1238 control will be transferred to the location specified by
1239 vector[length(vector) - 1].
1241 SSwitch <litstr id/offset vector> [C] -> []
1243 Switch over string case values. This instruction will search the
1244 string/offset vector from the beginning until it finds a string that is equal
1245 to $1. If one is found, control will be transferred to the location specified
1246 by the offset corresponding to that string. If a matching string is not
1247 found, control is transferred to the location specified by the final element
1248 in the vector, which must have a litstr id of -1.
1252 Return a cell. Returns $1 to the caller.
1254 If this instruction is used inside an async function executed in an "eager
1255 execution" mode, the $1 is wrapped into a StaticResultWaitHandle prior to
1256 return. In a "resumed execution" mode, the control is given back to the
1257 scheduler and it is informed that the async function has finished.
1259 If used in a generator, the Generator object is marked as finished and
1260 the control is given back to the next instruction after ContEnter or
1261 ContRaise instruction in a previous frame. The $1 must be Null.
1263 RetCSuspended [C] -> []
1265 Return a cell. Returns $1, which is an already suspended wait-handle, to the
1266 caller. This instruction can only be used within async functions. This is
1267 meant to be used within memoized async functions where the memoized value to
1268 be returned is already wrapped in a wait-handle.
1270 RetM <num returns> [C..C] -> []
1272 RetM is a variant of RetC that allows multiple cells to be returned. The RetM
1273 bytecode must be the only form of return used in a single function, and all
1274 callers must use FCall* with the matching number of returned values to invoke
1279 Throw. Throws the object $1. If $1 is not an object that extends the
1280 Exception class, this instruction throws a fatal error.
1286 CGetL <local variable id> [] -> [C]
1288 Get local as cell. If the local variable given by %1 is defined, this
1289 instruction gets the value of the local variable and pushes it onto the stack
1290 as a cell. If the local variable is not defined, this instruction raises a
1291 warning and pushes null onto the stack.
1293 CGetQuietL <local variable id> [] -> [C]
1295 Get local as cell. If the local variable given by %1 is defined, this
1296 instruction gets the value of the local variable and pushes it onto the stack
1297 as a cell. If the local variable is not defined, this instruction pushes null
1300 CGetL2 <local variable id> [<C>:<T>] -> [C <C>:<T>]
1302 Get local as cell. First, $1 is popped off the stack. If the local variable
1303 given by %1 is defined, this instruction then gets the value of the local variable,
1304 pushes it onto the stack as a cell, and then pushes $1 back onto the stack.
1306 If the local variable is not defined, this instruction raises a warning,
1307 pushes null onto the stack, and then pushes $1 back onto the stack.
1309 CUGetL <local variable id> [] -> [C|U]
1311 Get local as cell or uninit. If the local variable given by %1 is defined,
1312 this instruction gets the value of the local variable and pushes it onto the
1313 stack as a cell. If the local variable is not defined, this instruction pushes
1314 uninit onto the stack.
1316 PushL <local variable id> [] -> [C]
1318 Teleport local value to eval stack. The local variable given by %1 must be
1319 defined and must not contain a reference. This instruction pushes the local's
1320 value on the stack, then unsets it, equivalent to the behavior of UnsetL.
1324 Get global as cell. This instruction first computes x = (string)$1. Next,
1325 this instruction reads the global variable named x pushes its value onto the
1328 If there is not a global variable defined named x, this instruction pushes
1329 null onto the stack.
1331 CGetS <readonly op> [C C:Class] -> [C]
1333 Get static property as cell. This instruction first checks if class $1 has a
1334 visible and accessible static property named (string)$2. If it doesn't, this
1335 instruction throws a fatal error. Otherwise, this instruction pushes the
1336 static property onto the stack as a cell.
1338 ClassGetC <mode> [C] -> [C:Class]
1340 Fetch class. This instruction has different modes selected by the %1 enum.
1343 This instruction checks if $1 is a string, object, or class. If
1344 a class, it pushes the input unchanged. If a string, it checks if $1 is the
1345 name of a defined class. If so, the class is pushed. If not, this instruction
1346 will invoke the autoload facility passing in $1, and then it will again check
1347 if $1 matches the name of a defined class. If still not defined, this
1348 instruction throws a fatal error. If $1 is an object, it pushes the runtime
1349 class of the object. If $1 is not any of the above cases, this instruction
1350 throws a fatal error.
1352 ExplicitConversion mode:
1353 This is an explicit str-to-class conversion through HH\classname_to_class().
1354 Checks if $1 is a string, class, or lazy class; objects are not admitted and
1355 classes pointers are pushed unchanged. When $1 is a string, we check whether
1356 the target class has the <<__DynamicallyReferenced>> attribute and raise a
1357 sampled notice otherwise. If the target class fails to load, we throw a
1358 catchable InvalidArgumentException.
1360 ClassGetTS [C:Dict] -> [C:Class, C:StaticVec|Null]
1362 Fetch class from type-structure. This instruction checks if $1 is a valid
1363 type-structure (darray or dict). If not, this instruction throws a fatal
1364 error. Otherwise, $1['classname'] is loaded, and mangled as dictated by the
1365 type-structure's generics information (if present). The possibly mangled
1366 classname is then processed like ClassGetC and the resulting class is
1367 pushed. If present, the type-structure's generics information is processed as
1368 in RecordReifiedGeneric and pushed. If not present, null is pushed.
1371 6. Isset and type querying instructions
1372 -----------------------------------------------
1374 IssetL <local variable id> [] -> [C:Bool]
1376 Isset local. This instruction reads the local variable given by %1. If the
1377 local variable is undefined or null, this instruction pushes false onto the
1378 stack, otherwise it pushes true.
1380 IsUnsetL <local variable id> [] -> [C:Bool]
1382 IsUnset local. This instruction reads the local variable given by %1. If the
1383 local variable is undefined, this instruction pushes true onto the
1384 stack, otherwise it pushes false.
1386 IssetG [C] -> [C:Bool]
1388 Isset global. This instruction reads the global variable named (string)$1. If
1389 the global variable is undefined or null, this instruction pushes false onto
1390 the stack, otherwise it pushes true.
1392 IssetS [C C:Class] -> [C:Bool]
1394 Isset static property. This instruction first computes x = (string)$2. Next
1395 it checks if class $1 has an accessible static property named x. If it
1396 doesn't, this instruction pushes false.
1398 If class $1 does have an accessible property named x, this instruction reads
1399 the static property named x. If the static property is null, this instruction
1400 pushes false onto the stack, otherwise it pushes true.
1402 IsTypeC <op> [C] -> [C:Bool]
1404 Is type. This instruction checks the type of a value on the stack, according
1405 to the following table:
1418 ArrLike | Vec or Dict or Keyset
1419 Scalar | Int or Dbl or Str or Bool
1421 Class | Class or LazyClass
1423 If t is Obj, this instruction checks if the operand in an object.
1424 Instances of a special class __PHP_Incomplete_Class are not considered
1426 Otherwise, the result is true if $1 is of type t and false otherwise.
1427 The result is pushed on the stack.
1429 IsTypeL <local variable id> <op> [] -> [C:Bool]
1431 Is type. This instruction checks the type of a local, according to the
1445 ArrLike | Vec or Dict or Keyset
1446 Scalar | Int or Dbl or Str or Bool
1448 Class | Class or LazyClass
1450 If the local variable given by %1 is defined, the logic is the same as for
1451 IsTypeC (see above).
1452 If the local is of kind reference, then the inner value is used to determine
1454 If the local variable given by %1 is not defined, this instruction raises a
1455 warning and pushes false onto the stack, unless if the operand is Null, in
1456 which case it pushes true.
1459 7. Mutator instructions
1460 -----------------------
1462 SetL <local variable id> [C] -> [C]
1464 Set local. This instruction marks the local variable given by %1 as defined,
1465 stores the value $1 into the local variable, and then pushes $1 onto the
1470 Set global. This instruction marks the global variable named (string)$2 as
1471 defined, assigns the value $1 to the global variable, and then pushes $1 onto
1474 SetS <readonly op> [C C:Class C] -> [C]
1476 Set static property. First this instruction checks if the class $2 has an
1477 accessible static property named (string)$3. If it doesn't, this instruction
1478 throws a fatal error. Otherwise, this instruction assigns the value $1 to the
1479 static property, and then it pushes $1 onto the stack.
1481 SetOpL <local variable id> <op> [C] -> [C]
1483 Set op local. If the local variable given %1 is not defined, this instruction
1484 marks it as defined, sets it to null, and raises a warning.
1486 Next, this instruction reads the local variable into x, then executes y = x
1487 <op> $1, assigns y into local variable %1, and then pushes y onto the stack.
1488 The immediate value must be one of the following opcodes:
1489 Add, Sub, Mul, Div, Mod, Shl, Shr, Concat, BitAnd,
1492 SetOpG <op> [C C] -> [C]
1494 Set op global. This instruction first computes x = (string)$2. If the global
1495 variable named n is not defined, this instruction marks it as defined, sets
1496 it to null, and raises a warning.
1498 Next, this instruction reads the global variable named x into y, executes z =
1499 y <op> $1, assigns z into the global variable named x, and then pushes z onto
1500 the stack as a cell. The immediate value must be one of the following
1502 Add, Sub, Mul, Div, Mod, Shl, Shr, Concat, BitAnd, BitOr, BitXor.
1504 SetOpS <op> [C C:Class C] -> [C]
1506 Set op static property. This instruction first computes x = (string)$3. Next
1507 it checks if class $2 has an accessible static property named x. If it
1508 doesn't, this instruction throws a fatal error. Otherwise, this instruction
1509 reads the static property named x into y, executes z = y <op> $1, assigns z
1510 into the static property, and then pushes z onto the stack. The immediate
1511 value must be one of the following opcodes:
1512 Add, Sub, Mul, Div, Mod, Shl, Shr, Concat, BitAnd, BitOr, BitXor.
1514 IncDecL <local variable id> <op> [] -> [C]
1516 Increment/decrement local. If the local variable given by %1 is not defined,
1517 this instruction marks it as defined, sets it to null, and raises a warning.
1519 Where x is the local given by %1, this instruction then does the following:
1521 If op is PreInc, this instruction executes ++x and then pushes x onto the
1524 If op is PostInc, this instruction pushes x onto the stack and then it
1527 If op is PreDec, this instruction executes --x and then pushes x onto the
1530 If op is PostDec, this instruction pushes x onto the stack and then it
1533 IncDecG <op> [C] -> [C]
1535 Increment/decrement. This instruction first computes x = (string)$1. Next, if
1536 the global variable named x is not defined, this instruction first defines it,
1537 sets it to null, and raises a warning.
1539 Where v is the local variable or global variable named x, this instruction
1540 performs the following:
1542 If op is PreInc, this instruction executes ++v and then pushes v onto the
1545 If op is PostInc, this instruction pushes v onto the stack and then it
1548 If op is PreDec, this instruction executes --v and then pushes v onto the
1551 If op is PostDec, this instruction pushes v onto the stack and then it
1554 IncDecS <op> [C C:Class] -> [C]
1556 Increment/decrement static property. This instruction first computes x =
1557 (string)$2. Next it checks if class $1 has an accessible static property
1558 named x. If it doesn't, this instruction throws a fatal error.
1560 Where s is the static property named x, this instruction performs the
1563 If op is PreInc, this instruction increments the ++s and then pushes s onto
1566 If op is PostInc, this instruction pushes s onto the stack and then it
1569 If op is PreDec, this instruction executes --s and then pushes s onto the
1572 If op is PostDec, this instruction pushes s onto the stack and then it
1575 UnsetL <local variable id> [] -> []
1577 Unset local. Breaks any bindings the local variable given by %1 may have and
1578 marks the local variable as undefined.
1582 Unset global. This instruction breaks any bindings the global variable named
1583 (string)$1 may have and marks the global variable as undefined.
1585 CheckProp <propName> [] -> [C:Bool]
1587 Check non-scalar property initializer. This instruction checks the
1588 initializer for property named %1 in the context class, and pushes
1589 true on the stack if it is initialized, and false otherwise.
1591 InitProp <propName> <op> [C] -> []
1593 Initialize non-scalar property. If %2 is 'NonStatic', this instruction sets
1594 the initializer for the property named %1 in the context class to $1. If %2
1595 is 'Static', this instruction sets the initializer for the static property
1596 named %1 in the context class to $1.
1598 The CheckProp and InitProp opcodes should only be used in 86pinit methods.
1599 86pinit methods are HHVM-internal property initialization methods that
1600 cannot be called from user-land. After 86pinit runs, no declared properties
1601 of the class can be of type NullUninit.
1603 8. Call instructions
1604 --------------------
1606 NewObj [C:Class] -> [C:Obj]
1607 NewObjD <litstr id> [] -> [C:Obj]
1608 NewObjS <mode> [] -> [C:Obj]
1610 New object. First, these instructions load a class into x as given
1611 by the following table:
1619 When loading %1 into x, NewObjD will perform the work performed
1620 by the ClassGetC instruction to convert the name given by %1 into a class.
1621 NewObjS will perform the same work as LateBoundCls/SelfCls/ParentCls depending
1622 on the specified mode.
1624 This instruction pushes a default-initialized object onto the stack. The
1625 initialization will complete by running a constructor with FCallCtor, and
1626 clearing the IsBeingConstructed flag using LockObj.
1628 LockObj [C:Obj] -> [C:Obj]
1630 Clears the IsBeingConstructed flag on the object, leaving it on the stack.
1635 FCall* opcodes are responsible for invoking the callee determined by the
1636 specific opcode and performing operations related to the function call as
1637 specified by the FCA (FCall arguments) immediate consisting of the following
1640 <flags> <num args> <num returns> <inout bool vector> <async eager offset>
1641 [C|V..C|V] -> [C..C]
1643 FCall* first looks up the callee function according to the specific opcode.
1645 The vector %4 must be either empty or it must contain exactly %2 booleans.
1646 If it is non-empty, FCall* checks whether inout-ness of parameters 1..%2
1647 of the callee matches the corresponding inout-ness values specified by the
1648 vector %4. Throws an exception if there is a mismatch.
1650 Finally, FCall* transfers the top %2 values from the stack to the callee as
1651 parameters and invokes the callee. When the callee returns, it will transfer
1652 %3 return values onto the caller's evaluation stack using the C flavor. The
1653 callee must return the matching number of values using either RetC opcode
1654 (if %3 was one) or RetM opcode (otherwise).
1656 If the optional offset %5 was specified, the callee supports async eager
1657 return and it would return a finished Awaitable, it may instead return the
1658 unpacked result of the Awaitable and continue execution of the caller at
1661 If %5 was specified and the callee raised an exception, the exception will
1662 continue to propagate thru the caller instead of being wrapped into Awaitable.
1663 Note that for the purposes of exception handling inside the caller, the PC
1664 will point after the FCall* rather than %5 so it is not advised to have
1665 different EH entries for these two locations.
1667 Async eager offset feature is used to avoid the cost of construction of short
1668 lived Awaitables that are produced by eagerly finishing asynchronous code and
1669 then immediately awaited by the caller.
1671 The %1 contains a list of boolean flags:
1673 Unpack: if enabled, %2 arguments on the stack are followed by an additional
1674 value, which must be an array. Its elements are transferred to the callee as
1675 parameters, following the regular %2 parameters.
1677 Generics: if enabled, %2 arguments and an optional unpack array on the stack
1678 are followed by an additional value containing the list of reified generics.
1679 Only FCall*D opcodes are allowed to pass generics.
1681 LockWhileUnwinding: whether to lock newly constructed objects if unwinding the
1684 FCallFunc <fca> [U U C|V..C|V C] -> [C..C]
1685 FCallFuncD <fca> <litstr id> [U U C|V..C|V] -> [C..C]
1687 Call a callable. First, these instructions load a value into x as given by
1688 the following table:
1695 If x is a string, this instruction attempts to lookup a function named x. If
1696 a function named x is defined, this instruction calls it. Otherwise it throws
1697 a fatal error. With FCallFunc*D the litstr in %2 must not start with a '\'
1698 character, or be of the form "Class::Method". Function names should be
1699 normalized with respect to namespace and never start with a '\'.
1701 If x is an object, this instruction checks if the object has an __invoke
1702 method. If the object does have an __invoke method, this instruction calls
1703 it. Otherwise it throws a fatal error.
1705 if x is an array, this instruction will check that the first array element is
1706 either the name of a class, or an instance of one, and that the second array
1707 element is the name of a method implemented by the class. If a method exists,
1708 this instruction calls it. Otherwise it throws a fatal error.
1710 If x is a func or a clsmeth, this instruction calls it.
1712 If x is not a string, object, array, func, or clsmeth, this instruction
1713 throws a fatal error.
1715 FCallObjMethod <fca> <class hint> <nullsafe>
1716 [C U C|V..C|V C] -> [C..C]
1717 FCallObjMethodD <fca> <class hint> <nullsafe> <litstr id>
1718 [C U C|V..C|V] -> [C..C]
1720 Call an instance method. First, these instructions load values into x
1721 and y as given by the following table:
1724 -----------------+---------------------------------------------+-----
1725 FCallObjMethod | $(num args + has unpack + 4) | $1
1726 FCallObjMethodD | $(num args + has unpack + has generics + 3) | %3
1728 If x is not an object and nullsafe != ObjMethodOp::NullThrows, or if y is not
1729 a string, this instruction throws a fatal error. Next, this instruction checks
1730 if object x has an accessible method named y. If it does, this instruction
1733 If object x does not have an accessible method named y, this instruction
1734 throws a fatal error.
1736 The string in %2 provides a static analysis hint. If it is non-empty, it is
1737 the class name with the implementation of method y that will be called.
1739 FCallClsMethod <fca> <class hint> <op>
1740 [U U C|V..C|V C C:Class] -> [C..C]
1741 FCallClsMethodM <fca> <class hint> <op> <litstr id>
1742 [U U C|V..C|V C] -> [C..C]
1743 FCallClsMethodD <fca> <litstr id> <litstr id>
1744 [U U C|V..C|V] -> [C..C]
1745 FCallClsMethodS <fca> <class hint> <mode>
1746 [U U C|V..C|V C] -> [C..C]
1747 FCallClsMethodSD <fca> <class hint> <mode> <litstr id>
1748 [U U C|V..C|V] -> [C..C]
1750 Call a static method. First, these instructions load values into x and
1751 y as given by the following table:
1754 --------------------+----+-----
1755 FCallClsMethod | $1 | $2
1756 FCallClsMethodM | $1 | %4
1757 FCallClsMethodD | %2 | %3
1758 FCallClsMethodS | %3 | $1
1759 FCallClsMethodSD | %3 | %4
1761 When loading litstr id %2 into x, FCallClsMethodD will perform the work
1762 performed by the ClassGetC instruction to convert the name given by %2 into
1763 a class. Similarly, FCallClsMethodM will convert $1 into a class.
1765 When loading mode %3 into x, FCallClsMethodS and FCallClsMethodSD will
1766 perform the work performed by LateBoundCls/SelfCls/ParentCls depending
1767 on the specified mode.
1769 If y is not a string, this instruction throws a fatal error. Next, this
1770 instruction checks if class x has an accessible method named y. If it does,
1771 this instruction calls that method.
1773 If class x does not have an accessible method named y, this instruction
1774 throws a fatal error.
1776 The string in %2 provides a static analysis hint. If it is non-empty, it is
1777 the class name with the implementation of method y that will be called.
1779 If op is DontLogAsDynamicCall all logging set up for dynamic calls will be
1782 FCallCtor <fca> <class hint> [C:Obj U C|V..C|V] -> [C]
1784 This instruction calls a constructor for class of the object given by
1785 $(num args + has unpack + 3).
1787 The string in %2 provides a static analysis hint. If it is non-empty, it is
1788 the class name with the implementation of __construct() that will be called.
1790 Constructors do not support inout, so the "num returns" in %1 must be 1.
1793 9. Member operations
1794 --------------------
1796 Member operations represent one part of a member expression such as
1797 "$a[0]['name'] = $foo". Each operation corresponds to one bytecode instruction,
1798 but the operations are described separately from their instruction mapping to
1799 separate them from any concerns about instruction encoding.
1801 Operations can produce and consume intermediate values called "bases". A "base"
1802 is a pointer to a memory location that is occupied by a cell or a ref, typically
1803 a local variable, array element, or object property. The current base is stored
1804 in a VM register called the member base register, or MBR for short. Bases are
1805 never stored on the evaluation stack or in any VM location other than the MBR.
1807 A base never owns a reference to the value it points to. It may point to a
1808 temporary value in a scratch register, but the lifetime of the value is always
1811 There are three categories of member operations: base, intermediate, and
1812 final. Base operations produce a base, intermediate operations consume the
1813 current base and produce a new base, and final operations consume the current
1814 base without producing a new one.
1816 Operations are specified as if they directly operate on the top of the
1817 evaluation stack in the name of consistency and clarity, but in fact their
1818 inputs and outputs may reside elsewhere. The symbol 'B' is used in the input
1819 descriptions and output descriptions of operations to indicate that a given
1820 operation consumes a base as input or produces a base as output.
1822 9.1 Member base operations
1823 --------------------------
1827 Get base from value. This operation outputs a base that points to the value
1830 BaseL <local variable id> [] -> [B]
1832 Get base from local. This operation outputs a base that points to the local
1833 given by %1. If the local is not defined, this operation outputs a base that
1836 BaseLW <local variable id> [] -> [B]
1838 Get base from local. This operation outputs a base that points to the local
1839 given by %1. If the local is not defined, this operation raises a warning and
1840 outputs a base that points to null.
1842 BaseLD <local variable id> [] -> [B]
1844 Get base from local. This operation outputs a base that points to the local
1845 given by %1, whether or not it is defined.
1848 BaseGL <local variable id> [] -> [B]
1850 Get base from global name. This operation outputs a base that points to the
1851 global variable whose name is given by (string)%1 or (string)$1. If the
1852 global is not defined, this operation produces a base that points to null.
1855 BaseGLW <local variable id> [] -> [B]
1857 Get base from global name. This operation outputs a base that points to the
1858 global variable whose name is given by (string)%1 or (string)$1. If the
1859 global is not defined, this operation raises a warning and outputs a base
1860 that points to null.
1863 BaseGLD <local variable id> [] -> [B]
1865 Get base from global name. This operation outputs a base that points to the
1866 global variable whose name is given by (string)%1 or (string)$1, defining it
1869 BaseSC [C C:Class] -> [B]
1871 Get base from static property. First, this operation computes x = (string)$2.
1872 Then this instruction checks if class $1 has an accessible property named
1873 x. If it does, this operation outputs a base that points to the static
1874 property. Otherwise, this operation throws a fatal error.
1878 Get base from $this. This operation assumes that the current frame contains a
1879 valid $this pointer and outputs a base pointing to the object in $this.
1881 9.2 Intermediate member operations
1882 ----------------------------------
1885 ElemL <local variable id> [B] -> [B]
1887 Fetch element if it exists. First, these operations load a value into x and a
1888 base into y, as given by the following table:
1891 ----------+----+-----
1895 Then, if y is an array, hack array, or hack collection this operation outputs
1896 a base that points to the element at index x in y. If there is no element at
1897 index x, this operation outputs a base that points to null.
1899 If y is an object that is not a hack collection, this operation throws a
1902 If y is a string, this operation computes z = (int)x. If z >= 0 and z <
1903 strlen(z), this operation builds a new string consisting of the character at
1904 offset z from y and outputs a base that contains the new string. Otherwise,
1905 this operation outputs a base that points to the empty string.
1907 If y is not a string, array, or object, this operation will output a base
1911 ElemLW <local variable id> [B] -> [B]
1913 Fetch element; warn if it doesn't exist.
1915 First, these operations load a value into x and a base into y, as given by
1916 the following table:
1919 ----------+----+-----
1923 If y is an array, hack array, or hack collection this operation outputs a
1924 base that points to the element at index x in y. If there is no element at
1925 index x, this operation outputs a base that points to null and raises a
1928 If y is an object that is not a hack collection, this operation throws a
1931 If y is a string, this operation continues to compute z = (int)x. If z >= 0
1932 and z < strlen(z), this operation builds a new string consisting of the
1933 character at offset z from y and outputs a base that points to the new string.
1934 Otherwise, this operation raises a warning and outputs a base that points to
1937 If y is not a string, array, or object, this operation will output a base
1941 ElemLD <local variable id> [B] -> [B]
1943 Fetch element; define it if it doesn't exist.
1945 First, these operations load a value into x and a base into y, as given by
1946 the following table:
1949 ----------+----+-----
1953 If y is an array, hack array, or hack collection this operation outputs a
1954 base that references the element at index x. If there is no element at index
1955 x, this operation creates an element at index x, and outputs a base that
1956 references the element.
1958 If y is non-empty string or an object that is not a hack collection, this
1959 operation throws a fatal error.
1961 If y is null, the empty string, or false, this operation will set y to a new
1962 empty array, create an element at index x, and output a base that points to
1965 If y is true, integer, double, this operation raises a warning and outputs a
1966 base that points to null.
1969 ElemLU <local variable id> [B] -> [B]
1971 Fetch element for unset.
1973 First, these operations load a value into x and a base into y, as given by
1974 the following table:
1977 ----------+----+-----
1981 If y is an array, hack array, or hack collection this operation outputs a
1982 base that points to the element at index x in y. If there is no element at
1983 index x, this operation outputs a base that points to null.
1985 If y is an object that is not a hack collection, this operation throws a
1988 If y is a string, this operation throws a fatal error.
1990 If y is not a string, array, or object, this operation will output a base
1995 Fetch new element. If $1 is an array, hack array, or hack collection this
1996 operation creates a new element with the next available numeric key in $1
1997 and outputs a base that points to the new element.
1999 If $1 is a non-empty string or an object that is not a hack collection, this
2000 operation throws a fatal error.
2002 If $1 is null, false, or the empty string, this operation sets $1 to a new
2003 empty array, creates a new element with the next available numeric key in
2004 array $1, and then outputs a base that points to the new element.
2006 If $1 is true, integer, or double, this operation raises a warning and
2007 outputs a base that points to null.
2010 PropL <local variable id> [B] -> [B]
2012 Fetch property if it exists.
2014 First, these operations load a value into x and a base into y, as given by
2015 the following table:
2018 ----------+----+-----
2022 Next, produce a base pointing to:
2027 y has eligible __get method
2028 y->x has been unset previously
2029 ------+---------------------------------------------------------------------
2033 1100X | throw fatal error
2040 PropLW <local variable id> [B] -> [B]
2042 Fetch property; warn if it doesn't exist.
2044 First, these operations load a value into x and a base into y, as given by
2045 the following table:
2048 ----------+----+-----
2052 Next, produce a base pointing to:
2057 y has eligible __get method
2058 y->x has been unset previously
2059 ------+---------------------------------------------------------------------
2060 0XXXX | raise warning; null
2061 10X0X | raise warning; null
2063 1100X | throw fatal error
2066 11101 | raise warning; null
2070 PropLD <local variable id> [B] -> [B]
2072 Fetch property; define it if it doesn't exist.
2074 First, these operations load a value into x and a base into y, as given by
2075 the following table:
2078 ----------+----+-----
2082 Next, produce a base pointing to:
2088 y has eligible __get method
2089 y->x has been unset previously
2090 -------+--------------------------------------------------------------------
2092 01XXXX | y = new stdClass; create property y->x; y->x
2093 1X0X0X | create property y->x; y->x
2094 1X0X1X | y->__get(x)
2095 1X100X | throw fatal error
2096 1X101X | y->__get(x)
2098 1X1101 | re-create property y->x, y->x
2099 1X1111 | y->__get(x)
2102 PropLU <local variabld id> [B] -> [B]
2104 Fetch property for unset.
2106 First, these operations load a value into x and a base into y, as given by
2107 the following table:
2110 ----------+----+-----
2114 Next, produce a base pointing to:
2119 y->x has been unset previously
2120 -----+----------------------------------------------------------------------
2122 10XX | create property y->x; y->x
2123 110X | throw fatal error
2125 1111 | re-create property y->x; y->x
2127 9.3 Final member operations
2128 ---------------------------
2130 CGetElemC [C B] -> [C]
2131 CGetElemL <local variable id> [B] -> [C]
2133 Get element as cell.
2135 These instructions first load a value into x and a base into y, as given by
2136 the following table:
2139 ------------+----+-----
2143 If y is an array, hack array, or hack collection this operation retrieves
2144 the element at index x from y and pushes it onto the stack as a cell. If
2145 there is no element at index x, this operation raises a warning and pushes
2146 null onto the stack.
2148 If y is an object that is not a hack collection, this operation throws a
2151 If y is a string, this operation continues to compute z = (int)x. If z >= 0
2152 and z < strlen(z), this operation builds a new string consisting of the
2153 character at offset z from y and pushes it onto the stack. Otherwise, this
2154 operation raises a warning and pushes the empty string onto the stack.
2156 If y is not a string, array, or object, this operation will push null onto
2159 IssetElemC [C B] -> [C:Bool]
2160 IssetElemL <local variable id> [B] -> [C:Bool]
2164 These instructions first load a value into x and a base into y, as given by
2165 the following table:
2168 ------------+----+-----
2169 IssetElemC | $2 | $1
2170 IssetElemL | %1 | $1
2172 If y is an array, hack array, or hack collection this operation pushes
2173 !is_null(y[x]) onto the stack.
2175 If y is an object that is not a hack collection, this operation throws a
2178 If y is a string, this operation computes z = (int)x and then it pushes (z >=
2179 0 && z < strlen(y)) onto the stack.
2181 If y is a not a string, array, or object, this operation pushes false onto
2184 SetElemC [C C B] -> [C]
2186 Set element. If $1 is an array, hack array, or hack collection this operation
2187 executes $1[$3] = $2 and then pushes $2 onto the stack.
2189 If $1 is an object that is not a hack collection, this operation throws a
2192 If $1 is null, the empty string, or false, this operation sets $1 to a new
2193 empty array, executes $1[$3] = $2, and then pushes $2 onto the stack.
2195 If $1 is a non-empty string, this operation first computes x = (int)$3. If x
2196 is negative, this operation raises a warning and does nothing else. If x is
2197 non-negative, this operation appends spaces to the end of $1 as needed to
2198 ensure that x is in bounds, then it computes y = substr((string)$2,0,1), and
2199 then it sets the character at index x in $1 equal to y (if y is not empty) or
2200 it sets the character at index x in $1 to "\0" (if y is empty). Then this
2201 operation pushes y on to the stack.
2203 If $1 is true, integer, or double, this operation raises a warning and pushes
2204 null onto the stack as a cell.
2206 SetElemL <local variable id> [C B] -> [C]
2208 Set element. If $1 is an array, hack array, or hack collection this operation
2209 executes $1[%1] = $2 and then pushes $2 onto the stack.
2211 If $1 is an object that is not a hack collection, this operation throws a
2214 If $1 is null, the empty string, or false, this operation sets $1 to a new
2215 empty array, executes $1[%1] = $2, and then pushes $2 onto the stack.
2217 If $1 is a non-empty string, this operation first computes x = (int)%1. If x
2218 is negative, this operation raises a warning and does nothing else. If x is
2219 non-negative, this operation appends spaces to the end of $1 as needed to
2220 ensure that x is in bounds, then it computes y = substr((string)$2,0,1), and
2221 then it sets the character at index x in $1 equal to y (if y is not empty) or
2222 it sets the character at index x in $1 to "\0" (if y is empty). Then this
2223 operation pushes y on to the stack.
2225 If $1 is true, integer, or double, this operation raises a warning and pushes
2226 null onto the stack as a cell.
2228 SetOpElemC <op> [C C B] -> [C]
2230 Set element op. If $1 is an array, hack array, or hack collection this
2231 operation first checks if $1 contains an element at offset $2. If it does
2232 not, this operation creates an element at offset $2, sets it to null, and
2233 raises a warning. Next, this operation executes x = $1[$3], y = x <op> $2,
2234 and $1[$3] = y, and then it pushes y onto the stack as a cell.
2236 If $1 is null, false, or the empty string, this operation first sets $1 to a
2237 new empty array. Then it follows the rules described in the case above.
2239 If $1 is a non-empty string or an object that is not a hack collection, this
2240 operation throws a fatal error.
2242 If $1 is true, integer, or double, this operation raises a warning and pushes
2243 null onto the stack.
2245 SetOpElemL <op> <local variable id> [C B] -> [C]
2247 Set element op. If $1 is an array, hack array, or hack collection this
2248 operation first checks if $1 contains an element at offset $2. If it does
2249 not, this operation creates an element at offset $2, sets it to null, and
2250 raises a warning. Next, this operation executes x = $1[%1], y = x <op> $2,
2251 and $1[%1] = y, and then it pushes y onto the stack as a cell.
2253 If $1 is null, false, or the empty string, this operation first sets $1 to a
2254 new empty array. Then it follows the rules described in the case above.
2256 If $1 is a non-empty string or an object that is not a hack collection, this
2257 operation throws a fatal error.
2259 If $1 is true, integer, or double, this operation raises a warning and pushes
2260 null onto the stack.
2262 IncDecElemC <op> [C B] -> [C]
2264 Increment/decrement element. If $1 is an array, hack array, or hack
2265 collection this operation checks if $1 contains an element at offset $2. If
2266 it does not, this operation creates an element at offset $2, sets it to null,
2267 and raises a warning. Next, this operation executes x = $1[$2], y = x, and
2268 either ++y (if op is PreInc or PostInc) or --y (if op is PreDec or PostDec).
2269 Then it assigns y to $1[$2] and pushes either y (if op is PreInc or PreDec)
2270 or x (if op is PostInc or PostDec) onto the stack.
2272 If $1 is null, false, or the empty string, this operation first sets $1 to an
2273 empty array. Then it follows the rules described in the case above.
2275 If $1 is a non-empty string or an object that is not a hack collection, this
2276 operation throws a fatal error.
2278 If $1 is true, integer, or double, this operation raises a warning and pushes
2279 null onto the stack.
2281 IncDecElemL <op> <local variable id> [B] -> [C]
2283 Increment/decrement element. If $1 is an array, hack array or hack collection
2284 this operation checks if $1 contains an element at offset %1. If it does not,
2285 this operation creates an element at offset %1, sets it to null, and raises
2286 a warning. Next, this operation executes x = $1[%1], y = x, and either ++y
2287 (if op is PreInc or PostInc) or --y (if op is PreDec or PostDec). Then it
2288 assigns y to $1[%1] and pushes either y (if op is PreInc or PreDec) or x (if
2289 op is PostInc or PostDec) onto the stack.
2291 If $1 is null, false, or the empty string, this operation first sets $1 to an
2292 empty array. Then it follows the rules described in the case above.
2294 If $1 is a non-empty string or an object that is not a hack collection, this
2295 operation throws a fatal error.
2297 If $1 is true, integer, or double, this operation raises a warning and pushes
2298 null onto the stack.
2300 UnsetElemC [C B] -> []
2301 UnsetElemL <local variable id> [B] -> []
2305 These instructions first load a value into x and a base into y, as given by
2306 the following table:
2309 ------------+----+-----
2310 UnsetElemL | %1 | $1
2311 UnsetElemC | $2 | $1
2313 If y is an array, hack array, or hack collection this operation removes the
2314 element at index x from y.
2316 If y is an object that is not a hack collection, this operation throws a
2319 If y is a string, this operation throws a fatal error.
2321 If y is not a string, array, or object, this operation does nothing.
2323 SetNewElem [C B] -> [C]
2325 Set new element. If $1 is an array, hack array, or hack collection this
2326 operation executes $1[] = $2 and then pushes $2 onto the stack.
2328 If $1 is null, false, or the empty string, this operation sets $1 to a new
2329 empty array, and then it executes $1[] = $2 and pushes $2 onto the stack.
2331 If $1 is a non-empty string or an object that is not a hack collection, this
2332 operation throws a fatal error.
2334 If $1 is true, integer, or double, this operation raises a warning and pushes
2335 null onto the stack.
2337 SetOpNewElem <op> [C B] -> [C]
2339 Set op new element. If $1 is an array, hack array, or hack collection this
2340 operation first determines the next available integer offset k in $1. Next,
2341 this operation executes $1[k] = null, x = $1[k], and y = x <op> $2. Then it
2342 assigns y to $1[k] and pushes y onto the stack.
2344 If $1 is null, false, or the empty string, this operation first sets $1 to an
2345 empty array. Then it follows the rules described in the case above.
2347 If $1 is a non-empty string or an object that is not a hack collection, this
2348 operation throws a fatal error.
2350 If $1 is true, integer, or double, this operation raises a warning and pushes
2351 null onto the stack.
2353 IncDecNewElem <op> [B] -> [C]
2355 Increment/decrement new element. If $1 is an array, hack array, or hack
2356 collection this operation first determines the next available integer offset
2357 k in $1. Next, this operation executes $1[k] = null, x = $1[k], y = x, and
2358 either ++y (if op is PreInc or PostInc) or --y (if op is PreDec or PostDec).
2359 Then it assigns y to $1[k] and pushes either y (if op is PreInc or PreDec) or
2360 x (if op is PostInc or PostDec) onto the stack.
2362 If $1 is null, false, or the empty string, this operation first sets $1 to an
2363 empty array. Then it follows the rules described in the case above.
2365 If $1 is a non-empty string or an object that is not a hack collection, this
2366 operation throws a fatal error.
2368 If $1 is true, integer, or double, this operation raises a warning and pushes
2369 null onto the stack.
2371 CGetPropC [C B] -> [C]
2372 CGetPropL <local variable id> [B] -> [C]
2374 Get property as cell.
2376 These instructions first load a value into x and a base into y, as given by
2377 the following table:
2380 ------------+----+-----
2384 If y is an object that does not have an eligible __get method, this operation
2385 first checks if y has a visible property named x. If it does not, this
2386 operation raises a warning and pushes null. Otherwise, this operation
2387 continues to check if the property named x is accessible. If the property
2388 named x is accessible this operation pushes it onto the stack as a cell,
2389 otherwise this operation throws a fatal error.
2391 If y is an object that has an eligible __get method, this operation checks if
2392 y has a visible and accessible property named x. If it does, this operation
2393 pushes the property onto the stack. Otherwise, this operation pushes
2394 y->__get(x) onto the stack.
2396 If y is not an object, this operation will raise a warning and push null onto
2399 IssetPropC [C B] -> [C:Bool]
2400 IssetPropL <local variable id> [B] -> [C:Bool]
2404 These instructions first load a value into x and a base into y, as given by
2405 the following table:
2408 -------------+----+-----
2409 IssetPropC | $2 | $1
2410 IssetPropL | %1 | $1
2412 If y is an object that does not have an eligible __isset method, this
2413 operation checks if y has a visible accessible property named x. If it does,
2414 this operation pushes !is_null(y->x) onto the stack. Otherwise this operation
2415 pushes false onto the stack.
2417 If y is an object that has an eligible __isset method, this operation checks
2418 if y has a visible and accessible property named x. If it does, this
2419 operation pushes !is_null(y->x) onto the stack. Otherwise this operation
2420 pushes y->__isset(x) onto the stack.
2422 If y is an array, this operation pushes !is_null(y[x]) onto the stack.
2424 If y is not an object or array, this operation pushes false.
2426 SetPropC [C C B] -> [C]
2427 SetPropL <local variable id> [C B] -> [C]
2429 Set property. Perform one of the following actions:
2431 First, these operations load values into k and x, and a base into y, as given
2432 by the following table:
2435 ----------+----+----+----
2436 SetPropC | $3 | $2 | $1
2437 SetPropL | %1 | $2 | $1
2439 Next, performs one of the following actions:
2445 y has eligible __set method
2446 y->k has been unset previously
2447 -------+--------------------------------------------------------------------
2448 00XXXX | raise warning; push null
2449 01XXXX | y = new stdClass; y->k = x; push x
2450 1X0X0X | create property y->k; y->k = x; push x
2451 1X0X1X | y->__set(k, x); push x
2452 1X100X | throw fatal error
2453 1X101X | y->__set(k, x); push x
2454 1X11X0 | y->k = x; push x
2455 1X1101 | re-create property y->k; y->k = x; push x
2456 1X1111 | y->__set(k, x); push x
2458 SetOpPropC <op> [C C B] -> [C]
2459 SetOpPropL <op> <local variable id> [C B] -> [C]
2463 First, these operations load values into k and x, and a base into y, as given
2464 by the following table:
2467 ------------+----+----+----
2468 SetOpPropC | $3 | $2 | $1
2469 SetOpPropL | %1 | $2 | $1
2471 Next, perform one of the following actions:
2477 y has eligible __get method
2478 y has eligible __set method
2479 y->k has been unset previously
2480 --------+-------------------------------------------------------------------
2481 00XXXXX | raise warning; push null
2482 01XXXXX | y = new stdClass; z = null <op> x; y->k = z; push z
2483 100X0XX | z = null <op> x; y->k = z; push z
2484 100X10X | w = y->__get(k); z = w <op> x; y->k = z; push z
2485 100X11X | w = y->__get(k); z = w <op> x; y->__set(k, z), push z
2486 10100XX | throw fatal error
2487 101010X | throw fatal error
2488 101011X | w = y->__get(k); z = w <op> x; y->__set(k, z), push z
2489 1011XX0 | w = y->k; z = w <op> x; y->k = z; push z
2490 10110X1 | z = null <op> x; re-create y->k; y->k = z; push z
2491 1011101 | w = y->__get(k); z = w <op> x; re-create y->k; y->k = z; push z
2492 1011111 | w = y->__get(k); z = w <op> x; y->__set(k, z); push z
2494 IncDecPropC <op> [C B] -> [C]
2495 IncDecPropL <op> <local variable id> [B] -> [C]
2497 Increment/decrement property.
2499 First, these operations load a value into x and a base into y, as given by
2500 the following table:
2503 -------------+----+----
2504 IncDecPropC | $2 | $1
2505 IncDecPropL | %1 | $1
2507 Next, perform one of the following actions:
2513 y has eligible __get method
2514 y has eligible __set method
2515 y->x has been unset previously
2516 --------+-------------------------------------------------------------------
2517 00XXXXX | raise warning; push null
2518 01XXXXX | y = new stdClass; b = null; a = b; <op>a; y->x = a;
2519 | push a (Pre*) or b (Post*)
2520 100X0XX | b = null; a = b; <op>a; y->x = a; push a (Pre*) or b (Post*)
2521 100X10X | b = y->__get(x); a = b; <op>a; y->x = a;
2522 | push a (Pre*) or b (Post*)
2523 100X11X | b = y->__get(x); a = b, <op>a; y->__set(x, a);
2524 | push a (Pre*) or b (Post*)
2525 10100XX | throw fatal error
2526 101010X | throw fatal error
2527 101011X | b = y->__get(x); a = b, <op>a; y->__set(x, a);
2528 | push a (Pre*) or b (Post*)
2529 1011XX0 | b = y->x; a = b; <op>a; y->x = a; push a (Pre*) or b (Post*)
2530 10110X1 | b = null; a = b; <op>a; re-create y->x; y->x = a;
2531 | push a (Pre*) or b (Post*)
2532 1011101 | b = y->__get(x); a = b; <op>a; re-create y->x; y->x = a;
2533 | push a (Pre*) or b (Post*)
2534 1011111 | b = y->__get(x); a = b; <op>a; y->__set(x, a);
2535 | push a (Pre*) or b (Post*)
2537 UnsetPropC [C B] -> []
2538 UnsetPropL <local variable id> [B] -> []
2542 These instructions first load a value into x and a base into y, as given by
2543 the following table:
2546 -------------+----+-----
2547 UnsetPropC | $2 | $1
2548 UnsetPropL | %1 | $1
2550 Next, performs one of the following actions:
2555 y has eligible __unset method
2556 -----+----------------------------------------------------------------------
2559 10X1 | y->__unset(x)
2560 1100 | throw fatal error
2561 1101 | y->__unset(x)
2565 10. Member instructions
2566 -----------------------
2568 Each instruction in this section corresponds to one member operation from the
2569 previous section. The same bytecode may represent multiple different member
2570 operations, differentiating between the options using MOpMode immediates.
2572 Since they represent member operations, these instructions produced and/or
2573 consume a base in the member base register. The MBR is live starting after a
2574 Base* bytecode, modified by zero or more Dim* bytecodes, then finally consumed
2575 by a final operation:
2577 bytecode | MBR in-state | MBR out-state
2578 ----------+--------------+--------------
2581 Final Ops | live | dead
2583 Finally, many of these instructions have a <member key> immediate. This is
2584 described in the "Instruction set" introduction section.
2586 10.1 Base Operations
2587 ---------------------
2589 BaseGC <stack index> <member op mode> [] -> []
2590 BaseGL <local id> <member op mode> [] -> []
2592 BaseG{C,L}{,W,D} member operation.
2594 BaseSC <stack index> <stack index> <member op mode> <readonly op> [] -> []
2596 BaseSC member operation. %1 gives the location of the static property name,
2597 and %2 gives the location of the class.
2599 BaseL <local id> <member op mode> <readonly op> [] -> []
2601 BaseL{,W,D} member operation.
2603 BaseC <stack index> <member op mode> [] -> []
2605 BaseC member operation.
2609 BaseH member operation.
2611 10.2 Intermediate operations
2612 -----------------------------
2614 Dim <member op mode> <member key> [] -> []
2616 {Prop,Elem}{L,C,I,T}{W,D,U} member operation.
2620 10.3 Final operations
2621 ----------------------
2623 All final operations take a <stack count> immediate, which indicates the number
2624 of elements on the eval stack that must be consumed before pushing the final
2625 result. These are elements read by Base*C instructions, and member keys.
2627 QueryM <stack count> <query op> <member key> [...] -> [C]
2629 {CGet,Isset}{Prop,Elem} member operation.
2631 SetM <stack count> <member key> [... C] -> [C]
2633 Set{Prop,Elem} or SetNewElem member operation.
2635 SetRangeM <stack count> <op> <elem size> [... C C C] -> []
2637 Store raw data into a string, optionally reversing the order of elements
2638 based on op, which may be Forward or Reverse.
2640 The current member base must be a string (if this or any other required
2641 conditions are violated, an exception will be thrown). $3, and $1 are cast to
2642 Int before inspecting their values. $3 gives the offset within the base
2643 string to begin copying data into. The data comes from a source value in $2;
2644 supported types are described below. $1 is the count of items to copy from
2645 $2, and it maybe be -1 to request that an appropriate value is inferred from
2646 $2. The range [$3, count * size) must fit within [0, length of base).
2648 The following types are supported as data sources (the value in $2):
2650 - Bool: op must be Forward, count is ignored, and size must be 1. Stored as a
2651 1-byte value, either 0 or 1.
2653 - Int: op must be Forward, count is ignored, and size must be 1, 2, 4, or
2654 8. The value is truncated to the requested size and stored using the
2655 current machine's byte ordering.
2657 - Dbl: op must be Forward, count is ignored, and size must be 4 or 8. The
2658 value is converted to the requested size and stored using the current
2659 machine's byte ordering.
2661 - Str: count indicates the number of characters to copy, starting at the
2662 beginning of $2, and size must be 1. If op is Reverse, the characters are
2663 copied in reverse order. Note that characters are still copied starting at
2664 the beginning of $2, so Forward vs. Reverse never affects which characters
2665 are copied, just their order as they're written to the base string.
2667 - Vec: count indicates the number of elements to copy, and size indicates the
2668 size of each element. All elements of the vec must have the same type,
2669 which must be Bool, Int, or Dbl. The operation may modify the base string
2670 before failing if there are elements with mismatched types. Size must be
2671 one of the allowed values for the contained type, described above. Count
2672 must not be greater than the size of the vec. If op is Reverse, the
2673 elements will be copied in reverse order (always starting from offset 0 of
2674 the vec, as with string sources).
2676 IncDecM <stack count> <op> <member key> [...] -> [C]
2678 IncDec{Prop,Elem} or IncDecNewElem member operation.
2680 SetOpM <stack count> <op> <member key> [... C] -> [C]
2682 SetOp{Prop,Elem} or SetOpNewElem member operation.
2684 UnsetM <stack count> <member key> [...] -> []
2686 Unset{Prop,Elem} member operation.
2688 11. Iterator instructions
2689 -------------------------
2691 Several iterator instructions take an IterArgs struct. This struct contains an
2692 iterator ID, an value output local ID, and optionally a key output local ID.
2693 Below, when we refer to "the iterator ID in %1", "the value local given in %1",
2694 etc., we're referring to these IDs.
2696 IterBase [C] -> [C:Arr|Obj]
2698 Extract iterator base from $1.
2700 - If $1 is array-like, pushes $1 onto the stack.
2702 - If $1 is a collection object, pushes the underlying vec or dict onto
2705 - If $1 is an object that implements Iterator, pushes $1 onto the stack.
2707 - If $1 is an object that implements the IteratorAggregate interface, then
2708 we repeatedly execute "x = x->getIterator()" until x is no longer an
2709 object that implements the IteratorAggregate interface. If x is now an
2710 object that implements the Iterator interface, pushes x onto the stack.
2711 Otherwise, we throw an object of type Exception.
2713 - If $1 is an object that does not match any of the cases above, then we
2714 create a dict that contains all accessible properties of the base's class,
2715 in the order that they were defined, then push that dict onto the stack.
2716 Keys and values of the dict correspond to the property names and values.
2718 - If $1 is not an array-like or object, an exception is thrown.
2720 IterInit <IterArgs> <rel offset> [C:Arr|Obj] -> []
2722 Initialize an iterator. This instruction takes a "base" in $1, which must be
2723 an array-like or an object implementing the Iterator interface. It creates
2724 an iterator with ID given in %1 pointing to the beginning of $1 and, if $1 is
2725 an Iterator object, rewinds $1. It then checks if the base is empty. If so,
2726 it frees the iterator (with an implicit IterFree) and transfers control to
2729 If the base is non-empty, this instruction writes the value of the base's
2730 first element to the value local given in %1. If the iterator is a key-value
2731 iterator, then this instruction also writes the key of the base's first
2732 element to the key local given in %1.
2734 This instruction stores to its key and value output locals with the same
2735 semantics as SetL (non-binding assignment).
2737 The precise semantics of "rewind", "is empty", "get key", and "get value"
2738 depend on the type of the base:
2740 - If $1 is array-like, we will create a new array iterator. "rewind" does
2741 nothing in this case - array iterators don't have base-internal state.
2742 The "is empty" check is a check on the length of $1, and "get key" and
2743 "get value" load $1's first element.
2745 - If $1 is an object that implements Iterator, then we create a new object
2746 iterator. We call $1->rewind() to reset the base's internal state, then
2747 call $1->valid() to check if $1 is non-empty. If $1 is valid, then we call
2748 $1->current() (and $1->key()) to get the $1's first value (and key).
2750 LIterInit <IterArgs> <local id> <rel offset> [] -> []
2752 Initialize iterator with local. This instruction creates an iterator pointing
2753 to the beginning of %2, but leaves %2 in its local rather than copying it into
2754 the iterator and inc-ref-ing it.
2756 If the base is non-empty, this instruction sets the output value (and, for
2757 key-value iterators, the output key) to the first element of the base.
2758 Otherwise, it frees the iterator and transfers control to the target %3.
2760 Since we don't store bases in the iterator, all other operations on this
2761 iterator must use the LIter variants (LIterNext, LIterFree) and must provide
2762 the same local (containing the same iterator base) as immediates.
2764 IterNext <IterArgs> <rel offset> [] -> []
2766 Iterator next. This instruction first advances the iterator with the ID given
2767 in %1. If the iterator has more elements, then it writes the next element's
2768 value (and, for key-value iters, its key) to the output locals given in %1
2769 and transfers control to the location specified by %2, Otherwise, the base
2770 frees the iterator (with an implicit IterFree).
2772 As with IterInit, the precise semantics of "advance" and "has more elements"
2773 depend on the iterator type. (We could also say it depends on the type of
2774 the base, but we use some iterator types (e.g. array iterator) for multiple
2775 base types (e.g. array-likes and collection objects).)
2777 - For array iterators: "advance" increments the iterator's position, and
2778 the base "has more elements" if this position is not the final position
2779 for the stored array. If the array has more elements, we take its key
2780 and value at the new position.
2782 - For object iterators: we call $base->next() to update the base's internal
2783 state, then call $base->valid() to check whether it has more elements. If
2784 so, we use $base->key() and $base->current() to get the new key and value.
2786 - For default class iterators, we advance to the base's class's next
2787 accessible property (if there are more) and we use its name and value as
2788 the new key and value.
2790 LIterNext <IterArgs> <local id> <rel offset> [] -> []
2792 Iterator next with local. The iterator with ID given in %1 must have been
2793 initialized with LIterInit. This instructions behaves similarily to IterNext,
2794 except that it will use the %2 local as the iterator's base rather than the
2795 one stored in the iterator.
2797 IterFree <iterator id> [] -> []
2799 Iterator free. This instruction frees the iterator with ID %1. An iterator is
2800 typically freed by IterInit or IterNext when its base has no more elements,
2801 so IterFree is only needed for guarding against exceptions.
2803 LIterFree <iterator id> [] -> []
2805 Iterator free with local. This instruction frees the iterator with ID %1,
2806 which must have been initialized by LIterInit with base %2. Since the
2807 iterator does not contain the base, this does not actually free anything.
2808 This instruction is just used to inform the VM that the iterator slot is
2812 12. Include, eval, and define instructions
2813 ------------------------------------------
2817 Include. Includes the compilation unit containing the file (string)$1. The
2818 instruction eagerly marks all functions and classes that are unconditionally
2819 declared in the outermost scope as defined. Next this instruction calls the
2820 pseudo-main function from the file (string)$1. The pseudo-main function
2821 inherits the caller's variable environment. If the execution engine cannot
2822 find a compilation unit containing the file (string)$1, this instruction
2827 Include once. Include the compilation unit containing the file (string)$1 if
2828 it hasn't been included already. This instruction eagerly marks all functions
2829 and classes that are unconditionally declared in the outermost scope as
2830 defined, and then calls the pseudo-main function from (string)$1 if it hasn't
2831 run already. The pseudo-main function inherits the caller's variable
2832 environment. If the execution engine cannot find a compilation unit
2833 containing the file (string)$1, this instruction raises a warning.
2837 Require. Includes the compilation unit containing the file (string)$1. The
2838 instruction eagerly marks all functions and classes that are unconditionally
2839 declared in the outermost scope as defined. Next this instruction calls the
2840 pseudo-main function from the file (string)$1. The pseudo-main function
2841 inherits the caller's variable environment. If the execution engine cannot
2842 find a compilation unit containing the file (string)$1, this instruction
2843 throws a fatal error.
2847 Require once. Include the compilation unit containing the file (string)$1 if
2848 it hasn't been included already. This instruction eagerly marks all functions
2849 and classes that are unconditionally declared in the outermost scope as
2850 defined, and then calls the pseudo-main function from (string)$1 if it hasn't
2851 run already. The pseudo-main function inherits the caller's variable
2852 environment. If the execution engine cannot find a compilation unit
2853 containing the file (string)$1, this instruction throws a fatal error.
2857 As ReqOnce except the string is always taken to be relative to the document
2858 root (ie SourceRoot).
2862 Eval. Executes the source code in (string)$1. This instruction eagerly marks
2863 all functions and classes that are unconditionally declared in the outermost
2864 scope as defined, and then calls the pseudo-main function from (string)$1.
2865 The pseudo-main function from (string)$1 inherits the caller's variable
2868 13. Miscellaneous instructions
2869 ------------------------------
2873 This. This instruction checks the current instance, and if it is null, this
2874 instruction throws a fatal error. Next, this instruction pushes the current
2875 instance onto the stack.
2877 BareThis <notice> [] -> [C:Obj|Null]
2879 This. This instruction pushes the current instance onto the stack. If %1 is
2880 BareThisOp::Notice, and the current instance is null, emits a notice. If %1
2881 is BareThisOp::NeverNull the current value of $this is guaranteed to be
2882 available and can be loaded with no null check.
2886 Check existence of this. This instruction checks the current instance, and if
2887 it is null, throws a fatal error.
2889 ChainFaults [C C] -> [C]
2891 Chain exception objects. If either $1 or $2 is not an object that implements
2892 Throwable, raise a fatal error. Otherwise, start at $1 and walk the chain of
2893 "previous" properties until an unset one is found. Set that property to $2,
2894 unless the previous chain of $1 or $2 forms a cycle. In either case, $1 is
2895 left on the top of the stack.
2897 OODeclExists <Class|Interface|Trait> [C C] -> [C:Bool]
2899 Check for class/interface/trait existence. If $1 cannot be cast to a bool or
2900 $2 cannot be cast to a string, this instruction will throw a fatal error.
2901 Otherwise, it will check for existence of the entity named by $2, invoking
2902 the autoloader if needed and if $1 is true. The result of the existence check
2903 will be pushed on the stack.
2905 VerifyOutType <parameter id> [C] -> [C]
2907 Verify out param type. Check that $1 is a value compatible with the declared
2908 parameter type specified by the given parameter. In case of a mismatch
2909 a warning or recoverable error is raised.
2911 VerifyParamType <parameter id> [C] -> [C]
2913 Verify parameter type. Functions and methods can optionally specify the types
2914 of arguments they will accept.
2916 VerifyParamType checks the type of the parameter in $1 against the enclosing
2917 function's corresponding parameter constraints for `parameter id`. In case
2918 of a mismatch, a recoverable error is raised.
2920 VerifyRetTypeC [C] -> [C]
2922 Verify return type. This instruction pops $1 off of the stack, checks if $1
2923 is compatible with the current function's return type annotation and raises
2924 a warning if there is a mismatch, and then it pushes $1 back onto the stack.
2926 VerifyRetNonNullC [C] -> [C]
2928 This is intended to provide the same behavior as VerifyRetTypeC, except in
2929 only checks that $1 is non null. This should only be emitted by HHBBC if it
2930 can statically verify that return value will pass the function's type
2931 annotation if it is non null.
2933 VerifyParamTypeTS <parameter id> [C] -> []
2935 VerifyParamTypeTS pops a type structure from the stack and checks the
2936 specified parameter against this type structure. In case of a mismatch, a
2937 recoverable error is raised. If the popped cell is not a type structure,
2938 an error is raised. This instruction also verifies the reified generic type
2939 parameters of the specified parameter.
2941 VerifyRetTypeTS [C C] -> [C]
2943 VerifyRetTypeTS pops a type structure from the stack and checks whether
2944 $2 is compatible with this type structure. In case of a mismatch, a
2945 recoverable error is raised. If the popped cell is not a type structure,
2946 an error is raised. This instruction also verifies the reified generic type
2949 SelfCls [] -> [C:Class]
2951 Push a class that refers to the class in which the current function is
2952 defined. This instruction throws a fatal error if the current method is
2953 defined outside of a class.
2955 ParentCls [] -> [C:Class]
2957 Push a class that refers to the parent of the class in which the
2958 current method is defined. This instruction throws a fatal error if the
2959 current method is defined outside of a class or if the class in which the
2960 current method is defined has no parent.
2962 LateBoundCls [] -> [C:Class]
2964 Late-bound class. Push a class that refers to the current late-bound
2967 RecordReifiedGeneric [C:Vec] -> [C:Vec]
2969 Takes a varray or vec based on runtime flag of type structures from $1
2970 and unless the entry already exists adds a mapping from the grouped name of
2971 these type structures to a static array that contains the runtime
2972 representation of these type structures to the global reified generics table.
2973 Pushes the resulting static list of type structures.
2975 CheckClsReifiedGenericMismatch [C:Vec] -> []
2977 Throws a fatal error unless whether each generic in $1 is reified or erased
2978 matches exactly to the expectations of the current class. If there is
2979 no class in the current context, throws a fatal error as well.
2981 ClassHasReifiedGenerics [C:Class|LazyClass] -> [C:Bool]
2983 Checks if the class in $1 has reified generics and pushes the
2984 resulting boolean onto the stack. Throws a fatal error if $1 is not a class
2987 GetClsRGProp [C:Class|LazyClass] -> [C:Vec|Null]
2989 Gets the reified generics property for current instance, using the index of this
2990 property as stored in class $1. Raises a fatal error if the current instance
2991 is null or $1 is not a class or lazy class. Returns null if the current
2992 instance or $1 doesn't have reified generics.
2994 HasReifiedParent [C:Class|LazyClass] -> [C:Bool]
2996 Checks if the parent of the class in $1 has reified generics and pushes the
2997 resulting boolean onto the stack. Throws a fatal error if $1 is not a class.
3000 CheckClsRGSoft [C:Class|LazyClass] -> []
3002 Raises a warning if every reified generic in class $1 is soft.
3003 Otherwise, raises a fatal error. This bytecode should only be emitted
3004 when a class which expects reified generics is being instantiated without
3005 any reified generics given (thus guarded by a ClassHasReifiedGenerics bytecode).
3006 Throws a fatal error if $1 is not a class or lazy class.
3010 Native implementation. This instruction invokes the native implementation
3011 associated with current function and returns the return value to the caller
3012 of the current function.
3014 AKExists [C C] -> [C:Bool]
3016 Checks if array (object) in $1 contains key (property) in $2 and pushes the
3017 resulting boolean onto the stack. If $2 is null, uses the empty string as
3018 key. Throws a fatal error if $1 is not an array or object, and raises a
3019 warning if $2 is not a string, integer, or null.
3021 CreateCl <num args> <class name> [C|U..C|U] -> [C]
3023 Creates an instance of the class specified by <class name> and pushes it on the
3026 The specified class must be a subclass of "Closure", must have a single
3027 public method named __invoke, and must be defined in the same unit as the
3030 If there is more than one CreateCl opcode in the unit for the Closure
3031 subclass named by %2, all of the opcodes must be possible to associate with
3032 the same class (or trait), or none if the closure will not inherit a class
3033 context at runtime. This is intended to mean that CreateCl opcodes for a
3034 given closure may only occur in bytecode bodies of functions that are
3035 generated to represent a single user-visible PHP function, async function,
3036 async closure, generator, or generator closure.
3038 Moreover, for normal (non-async, non-generator) functions and methods, there
3039 must be at most a single CreateCl opcode in the unit for a given Closure
3040 subclass contained in the unit.
3044 Checks if object in $3 contains key in $2 and pushes the result onto the
3045 stack if found. Otherwise, $1 is pushed onto the stack. $3 must be an array,
3046 hack array, or hack collection.
3048 ArrayIdx [C C C] -> [C]
3050 Checks if array in $3 contains key in $2 and pushes the result onto the stack
3051 if found. Otherwise, $1 is pushed onto the stack. A fatal error will be
3052 thrown if $3 is not an array.
3054 ArrayMarkLegacy [C C] -> [C]
3056 Marks the array in $2 as a legacy array and pushes it onto the stack. If $1
3057 is true then the it is done recursively. If $1 isn't a bool then an exception
3060 ArrayUnmarkLegacy [C C] -> [C]
3062 Marks the array in $2 as a non-legacy array and pushes it onto the stack. If
3063 $1 is true then the it is done recursively. If $1 isn't a bool then an
3064 exception is thrown.
3066 AssertRATL <local id> <repo auth type> [] -> []
3067 AssertRATStk <stack offset> <repo auth type> [] -> []
3069 Assert known "repo authoritative type", for locals or stack offsets.
3071 These opcodes may be used to communicate the results of ahead of time static
3072 analysis (hhbbc) to the runtime. They indicate that the value in the
3073 specified local or stack offset is statically known to have a particular
3074 type. The "repo auth type" immediate is an encoded RepoAuthType struct (for
3075 details see runtime/base/repo-auth-type.h).
3077 As suggested by the name, these opcodes are generally for use with
3078 RepoAuthoritative mode. They may appear in non-RepoAuthoritative mode with
3079 one restriction: "specialized" array type information may not be asserted,
3080 because the global array type table may only be present in RepoAuthoritative
3083 BreakTraceHint [] -> []
3085 This opcode has no effects, but is a hint that code immediately following it
3086 is probably not worth including in the same compilation unit as the code in
3087 front of it. In HHVM, this is used to tell the JIT to break a Tracelet when
3088 it sees this opcode.
3090 Silence <local id> <Start|End> [] -> []
3092 With %2 = Start, sets the error reporting level to 0 and stores the previous
3093 one in the local variable %1. The local variable will be overwritten without
3096 With %2 = End, if the error reporting level is 0, restores the error
3097 reporting level to the previous value (stored in local variable %1); if the
3098 error reporting level is not 0, does nothing.
3100 The verifier requires that all code paths to an End on local variable %1
3101 contain a Start on %1, and that all code paths with a Start lead to an End on
3102 the same variable. It additionally requires that none of these paths store
3103 any value in %1 between the Start and End operations. Lastly, the set of
3104 variables storing the error reporting state must be consistent across block
3107 In either case, the local variable %1 must be an unnamed local.
3109 GetMemoKeyL <local id> [] -> [C:<Int/String>]
3111 Push an int or string which is an appropriate memoize cache key for the
3112 specified local. The local should be one of the function's parameters. The
3113 exact scheme for the cache key generation depends on whether the parameter is
3114 constrained by an appropriate type constraint. This op may throw if the input
3115 value is one that cannot be converted to a cache key (IE, an object that does
3116 not implement IMemoizeParam). This op can only be used within a function
3117 marked as being a memoize wrapper.
3119 MemoGet <rel offset> <local range> [] -> [C]
3121 Retrieve a memoization value associated with the current function and push it
3122 onto the stack. The values of the specified range of locals are used as the
3123 keys to perform the lookup (if any). If any of the locals are not ints or
3124 strings, fatal. The number of locals must match the number of formal
3125 parameters to the function. If no value is present, branch to the specified
3126 offset (without pushing anything). This op can only be used within a function
3127 marked as being a memoize wrapper.
3129 MemoGetEager <rel offset> <rel offset> <local range> [] -> [C]
3131 Retrieve a memoization value associated with the current function and push it
3132 onto the stack. This instruction behaves similarily to MemoGet, but is meant
3133 to be used within an async memoize wrapper. If no value is present, branch to
3134 the first specified offset (without pushing anything). If a value is present,
3135 but it is a suspended wait-handle, push it onto the stack and branch to the
3136 second specified offset. If a value is present, and it represents an eagerly
3137 returned value (not a suspended wait-handle), push it without branching.
3139 MemoSet <local range> [C] -> [C]
3141 Store $1 as a memoization value associated with the current function and
3142 leave it on the stack. The values of the specified range of locals are used
3143 as keys to perform the lookup (if any). If any of the locals are not ints or
3144 strings, fatal. The number of locals must match the number of formal
3145 parameters to the function. If there is already a value stored with that
3146 particular set of keys, it is overwritten. This op can only be used within a
3147 function marked as being a memoize wrapper. If the function is an async
3148 memoize wrapper, this marks the value as representing a suspended return
3149 value from the wrapped async function (and therefore must be a wait-handle).
3151 MemoSetEager <local range> [C] -> [C]
3153 Store $1 as a memoization value associated with the current function and
3154 leave it on the stack. This instruction behaves similarily as MemoSet, but is
3155 meant to be used within async memoize wrappers. It indicates that the value
3156 being stored represents an eager return from the wrapped async function (and
3157 is not a suspended wait-handle).
3159 ResolveFunc <litstr id> [] -> [C]
3161 Resolve %1 as a function name to a function pointer value, then push the
3162 pointer onto the top of stack. When resolution fails, raise an error.
3164 ResolveMethCaller <litstr id> [] -> [C]
3166 Resolve %1 as a function name to a function pointer value corresponding to a
3167 MethCaller. If the method called is not available in the current context then
3168 an exception is thrown. Otherwise, the function pointer is pushed to the top
3169 of the stack. The meth caller must exist in the same unit as the resolving
3172 ResolveRFunc <litstr id> [C:Vec] -> [C]
3174 Similar to ResolveFunc, resolve %1 as a function name to a function pointer
3175 and raises an error if the resolution fails. $1 contains a list of reified
3176 generics. If the function pointer takes reified generics, pushes a value
3177 capturing the function pointer and reified generics onto the top of stack.
3178 If the function pointer does not take reified generics, pushes just the
3179 function pointer into the top of stack.
3181 ResolveClsMethod <litstr id> [C:Class] -> [C]
3182 ResolveClsMethodD <litstr id> <litstr id> [] -> [C]
3183 ResolveClsMethodS <mode> <litstr id> [] -> [C]
3185 Push a class method pointer value. First, these instructions load values
3186 into x and y as given by the following table:
3189 ---------------------+----+-----
3190 ResolveClsMethod | $1 | %1
3191 ResolveClsMethodD | %1 | %2
3192 ResolveClsMethodS | %1 | %2
3194 When loading litstr id %1 into x, ResolveClsMethodD will perform the work
3195 done by the ClassGetC instruction to convert the name given by %1 into a
3198 When loading mode %1 into x, ResolveClsMethodS will perform the same work
3199 as LateBoundCls/SelfCls/ParentCls depending on the specified mode.
3201 This instruction checks if class x has an accessible static method named y.
3202 If not, it raises a fatal error. Otherwise, it creates a value that can be
3203 used to call that method and pushes the resulting class method pointer onto
3206 ResolveRClsMethod <litstr id> [C:Vec C:Class] -> [C]
3207 ResolveRClsMethodD <litstr id> <litstr id> [C:Vec] -> [C]
3208 ResolveRClsMethodS <mode> <litstr id> [C:Vec] -> [C]
3210 Similar to their non-reified counterparts (ResolveClsMethod*), these
3211 instructions load values into x and y based on the same table and performing
3212 the same work and the same checks to resolve the class method pointer.
3214 $1 contains a list of reified generics. If the class x has accessible
3215 static method y and takes the given reified generics, pushes a value
3216 capturing the class method pointer and the reified generics. If the
3217 class method does not accept the reified generics, pushes the class
3218 method pointer onto the stack.
3220 ThrowNonExhaustiveSwitch [] -> []
3222 Throws an exception indicating that the switch statement is non exhaustive.
3223 This exception can be downgraded to a warning or a noop through a runtime
3225 This bytecode instruction does not do any checks, it assumes that it was
3228 ResolveClass <litstr id> [] -> [C:Class] (where %1 is a class name)
3230 If %1 is a valid class name, resolve it to a class pointer value, then push
3231 the pointer onto the top of stack. When resolution fails, raise an error.
3233 RaiseClassStringConversionNotice [] -> []
3235 Raises a notice indicating an implicit class to string conversion.
3236 This notice is emitted at a sampled rate through a runtime option.
3238 SetImplicitContextByValue [C:?Obj] -> [C:?Obj]
3240 Sets the implicit context to %1 and returns the previous implicit context.
3242 CreateSpecialImplicitContext [C:Int C:?Str] -> [C:?Obj]
3244 Creates a special implicit context as if by calling the
3245 create_special_implicit_context builtin. $1 is one of the
3246 ImplicitContext::State enum values, and $2 is a nullable string optionally
3247 providing a memo-key. If $1 is not an int, or if $2 is not a nullable string,
3250 14. Generator creation and execution
3251 ---------------------------------------
3253 CreateCont [] -> [C:Null]
3255 This instruction may only appear in bodies of generators. Creates a new
3256 Generator object, moves all local variables from the current frame into
3257 the object, sets resume offset at the next opcode and suspends execution by
3258 transferring control flow back to the caller, returning the Generator
3259 object. Once the execution is resumed, the Null value sent by ContEnter
3260 becomes available on the stack. It is illegal to resume newly constructed
3261 Generator using ContEnter with a non-null value or ContRaise opcodes.
3263 ContEnter [C] -> [C]
3265 This instruction may only appear in non-static methods of the Generator
3266 class. It transfers control flow to the saved resume offset of a function
3267 associated with $this Generator object. The $1 will remain available
3268 on the stack after the control is transferred. Once the control is
3269 transferred back, a value determined by suspending opcode (Await, Yield,
3270 YieldK or RetC) will be pushed on the stack. This value corresponds to
3271 the next()/send() return value -- null for non-async generators, and
3272 WaitHandle or null for async generators.
3274 ContRaise [C:Obj] -> [C]
3276 This instruction may only appear in non-static methods of the Generator
3277 class. It transfers control flow to the saved resume offset of a function
3278 associated with $this Generator object. The Exception stored at $1 is
3279 thrown instead of invoking code at the resume offset. Once the control is
3280 transferred back, a value determined by suspending opcode (Await, Yield,
3281 YieldK or RetC) will be pushed on the stack. This value corresponds to
3282 the raise() return value -- null for non-async generators, and WaitHandle
3283 or null for async generators.
3287 This instruction may only appear in bodies of generators. Stores $1
3288 in the generator as the result of the current iteration, sets resume
3289 offset at the next opcode and suspends execution by transferring control
3290 flow back to the ContEnter or ContRaise. Once the execution is resumed,
3291 the value sent by ContEnter becomes available on the stack, or
3292 an exception sent by ContRaise is thrown.
3296 This instruction may only appear in bodies of generators. Stores $1
3297 in the generator as the result and $2 as the key of the current
3298 iteration, sets resume offset at the next opcode and suspends execution
3299 by transferring control flow back to the ContEnter or ContRaise. Once
3300 the execution is resumed, the value sent by ContEnter becomes available
3301 on the stack, or an exception sent by ContRaise is thrown.
3303 ContCheck <check started> [] -> []
3305 Check whether generator can be iterated. $this must be a Generator
3306 object. If the generator is finished, already running, or not yet started
3307 and <check started> is enabled, an exception will be thrown.
3309 ContValid [] -> [C:Bool]
3311 Check generator validity. $this must be a Generator object. Pushes true
3312 onto the stack if the generator can be iterated further, false otherwise.
3316 Get generator key. $this must be a Generator object. Pushes the most
3317 recently yielded key from the generator onto the stack.
3319 ContCurrent [] -> [C]
3321 Get generator value. $this must be a Generator object. Pushes the most
3322 recently yielded value from the generator onto the stack.
3324 ContGetReturn [] -> [C]
3326 Get generator's return value. $this must be a Generator object. Pushes the
3327 return value of the generator onto the stack.
3332 WHResult [C:Obj] -> [C]
3334 If $1 is not a subclass of WaitHandle, throws a fatal error. If $1 succeeded,
3335 this instruction pushes the result value from the WaitHandle. If $1 failed,
3336 this instruction throws the exception stored in the WaitHandle. If $1 is not
3337 finished, throws an Exception.
3341 This instruction may only appear in bodies of async functions. Awaits
3342 a WaitHandle provided by $1, suspending the execution if the WaitHandle
3345 If $1 is not a subclass of WaitHandle, throws a fatal error. If $1 succeeded,
3346 this instruction pushes the result value from the WaitHandle. If $1 failed,
3347 this instruction throws the exception from the WaitHandle. Otherwise the
3348 execution needs to be suspended:
3350 If the async function is executed eagerly, creates an AsyncFunctionWaitHandle
3351 object, moves all local variables and iterators from the current frame into
3352 the object, sets resume offset at the next opcode, marks the
3353 AsyncFunctionWaitHandle as blocked on the WaitHandle provided by $1 and
3354 suspends execution by transferring control flow back to the caller, returning
3355 the AsyncFunctionWaitHandle object.
3357 If the async function is executed in resumed mode, sets resume offset at
3358 the next opcode, marks the AsyncFunctionWaitHandle as blocked on the
3359 WaitHandle provided by $1 and suspends execution by transferring control
3360 flow back to the scheduler.
3362 Once the execution is resumed, the result of the WaitHandle provided by $1
3363 becomes available on the stack.
3365 AwaitAll<local-range> [] -> [C:Null]
3367 Fetches instances of Awaitables from the locals in range %1, and suspends
3368 until all of them have completed, at which point execution is resumed with a
3369 single null on the stack.
3371 Nulls in %1 are ignored, a fatal error is thrown if other non-Awaitables are
3372 encountered. The stack must be empty. Should all of the Awaitables in %1
3373 already be complete a null will be pushed to the stack without suspending
3374 the current function.
3376 Basic statement transformations
3377 -------------------------------
3379 To achieve HHBC's goal of making it straightforward for an interpreter or a
3380 compiler to determine order of execution, control flow statements are
3381 transformed to use the simpler constructs. Most control flow statements such as
3382 "if", "while", and "for" are implemented in a straightforward manner using the
3385 HHBC provides the Switch instruction for implementing very simple switch
3386 statements; most real switch statements are implemented naively using the Eq
3387 and JmpNZ instructions. Also, the functionality of both the echo statement and
3388 the print statement is implemented with the Print instruction.
3390 Foreach statements are implemented using iterator variables and the Iter*
3391 instructions. Each foreach loop must be protected by an EH catch entry to
3392 ensure that the iterator variable is freed when a foreach loop exits abnormally
3393 through an exception.
3395 Simple break statements and continue statements are implemented using the Jmp*
3396 and IterFree instructions. Dynamic break is implemented using an unnamed local
3397 (to store the 'break count') and a chain of basic blocks, where each block
3398 decrements the unnamed local variable and compares it with 0, and then decides
3402 Basic expression transformations
3403 --------------------------------
3405 To reduce the size of the instruction set, certain types of expressions are
3408 1) Unary plus and negation
3409 Unary plus and negation "+(<expression>)" gets converted to "(0 +
3410 (<expression>))", and "-(<expression>)" gets converted to "(0 -
3413 2) Assignment-by operators (+=, -=, etc)
3414 Assignment-by operators are converted to use the SetOp* instructions.
3416 3) List assignment (list)
3417 List assignments are converted to use an unnamed local variable and the QueryM
3418 and SetL instructions. In case of exception, the unnamed local variable is
3419 freed using EH entry.
3421 4) Logical and and logical or operators (and/&&, or/||)
3422 If any of the operands side-effect, these operators are implemented using Jmp*
3423 instructions instead of using the "and" and "or" instructions to implement
3424 short-circuit semantics correctly. All Jmp* instructions used to implement
3425 "and" and "or" operators will be forward jumps.
3427 5) The new expression
3428 The new expression is implemented by using the NewObj*, FCallCtor, and LockObj
3431 6) The ternary operator (?:)
3432 The functionality of the ternary operator is implemented using Jmp*
3433 instructions. All Jmp* instructions used to implement the ternary operator will
3436 7) Silence operator (@)
3437 The silence operator is implemented by using various instructions (including
3438 the Jmp* instructions), unnamed local variables, and an EH catch entry. All Jmp*
3439 instructions used to implement the silence operator will be forward jumps.
3441 8) The $this expression
3442 The $this expression has different effects depending on whether or not $this is
3443 the direct base of a property expression (such as "$this->x") or a method call
3444 expression (such as "$this->foo()"). When the $this expression is the direct
3445 base of a property expression or a method call expression, the This instruction
3448 A bare $this expression within an instance method is handled one of two ways:
3449 general or BareThis-optimized (optional). The general solution accesses a local
3450 variable named "this", which is initialized at the beginning of the method
3451 using the InitThisLoc instruction. The BareThis optimization applies to bare
3452 $this access as long as $this is not passed by reference and there are no
3453 dynamic method variables. In such cases, the BareThis instruction can be used
3454 to directly access $this, and the InitThisLoc instruction is not needed.
3457 Warning and errors at parse time
3458 --------------------------------
3460 Certain syntactically correct source code may cause warnings or errors to be
3461 raised when the source file is parsed. Examples of this include using "$this"
3462 on the left hand side of the assignment, using "$this" with binding assignment,
3463 using "$a[]" in an r-value context, and doing "unset($a[])". HHBC handles these
3464 cases by generating Throw or Fatal instructions at the beginning of the body
3465 for the pseudo-main function.
3471 At the time of this writing, the HipHop bytecode specification is missing the
3474 1) Description of traits
3475 2) Description of metadata for class statements, trait statements, and method
3477 3) Description and examples for the yield generator feature
3478 4) Description of the late static binding feature
3479 5) Description of the resource type
3480 6) Definitions of operators (ex. +, -, !) and other helper functions (ex.
3481 is_null, get_class, strlen)
3482 7) High level description of how namespaces are dealt with and any relevant
3484 8) Description of async function implementation
3487 /* Local Variables: */
3488 /* fill-column: 79 */