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, an evaluation stack, and a function parameter info (FPI) 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. Values come in three flavors: cells, refs, and classrefs.
104 A "cell" is a structure that contains a type identifier and either data (for
105 non-refcounted types) or a pointer to data (for refcounted types). When a cell
106 containing a pointer is duplicated, the new cell will point to the same data as
107 the original cell. When a cell containing a pointer is duplicated or discarded,
108 the execution engine is responsible for honoring the data's refcount logic.
110 A "ref" is a structure that contains a pointer to a cell container. When a ref
111 is duplicated, the new ref will point to the same container as the original
112 ref. When a ref is duplicated or destroyed, the execution engine is responsible
113 for honoring the container's refcount logic. When the container is destroyed,
114 the cell it contains is also destroyed.
116 A "classref" is a structure that contains a reference to a class. Classrefs are
117 never stored on the stack or in locals. They can only be manipulated via
118 "classref slots". Certain HHBC operations will read or write classref slots as
119 a side-effect. Classref slots have "move semantics" in that reading from one
120 automatically invalidates its contents.
122 Values on the evaluation stack and local variables may only be cells or refs.
128 A unit's bytecode is organized into functions. Each function has its own
129 metadata that provides essential information about the function, such as the
130 name of the function, how many local variables it has, how many iterator
131 variables it has, how many classref slots it has, how many formal parameters it
132 has, the names of the local variables, the names of the formal parameters, how
133 each parameter should be passed (pass by value vs. pass by reference), whether
134 each parameter has a default value, and an upper bound for the maximum depth
135 the evaluation stack can reach at run time.
137 Each local variable, iterator variable, and classref slot has an id, and HHBC
138 instructions can reference these variables using these ids. The id space for
139 local variables, iterator variables, and classref slots are all distinct from
140 each other. Thus local id 1 refers to a different variable than iterator id
141 1. Local variable ids, iterator ids, and classref slots are signed 32-bit
142 integer values. No function may have more than 2^31 - 1 each of local
143 variables, iterator variables, and classref slots.
145 Some local variables have names associated with them (called "named local
146 variables"), while other local variables do not have names associated with them
147 (called "unnamed local variables"). All local variables that reference formally
148 declared parameters have names associated with them. Iterator variables and
149 classref slots do not have names associated with them. Variables that have a
150 name associated with them will appear in the current variable environment (if
151 they are defined), while variables that do not have a name associated with them
152 will never appear in the current variable environment.
154 Formally declared parameters are considered to be local variables. Given a
155 function with n formally declared parameters, local ids 0 through n-1 will be
156 used to reference the formally declared parameters. Formal parameters without
157 default values are called "required parameters", while formal parameters with
158 default values are called "optional parameters".
160 The metadata of each function specifies a set of non-overlapping ranges of
161 bytecode that compose the function body, and it specifies the main entry point
162 and 0 or more DV entry points (entry points are discussed in more detail in
163 the "Entry points" section).
165 The total size of the bytecode for the function body must not exceed 2^31 - 1
166 bytes. The bytecode for a function must be one contiguous range of bytecode.
168 Each function's metadata provides a "line number table" to allow mapping
169 bytecode offsets back to source line numbers. Each row in the line number table
170 consists of a source line number and a range of bytecode. The table is sorted
171 by starting bytecode offset, lowest offset first. The bytecode offset of the
172 beginning of each instruction in the function must belong to exactly one of the
173 ranges of bytecode in the line number table.
179 Functions may be grouped into metadata for classes. Class metadata objects are
180 used to describe several PHP-level language features including traits,
181 interfaces, closures, and (of course) classes.
183 Class metadata includes information about the properties on the class, special
184 functions on the class such as constructors or internal property initialization
185 routines (86sinit, 86pinit), class constants, list of used traits, list of
186 extended classes, list of implemented interfaces, etc.
188 Classes also include a flag indicating their "hoistability". For now this isn't
189 documented much here. See class.h.
195 Closures are implemented in hhbc as subclasses of Closure, in conjunction with
196 the CreateCl opcode. It is legal hhbc to create other subclasses of Closure (to
197 represent user code that attempts to do the same), but attempting to
198 instantiate one will result in a fatal error. The documentation of the CreateCl
199 opcode below lists the requirements for a closure subclass to be usable with
206 The basic compilation strategy for generators is to create bytecode functions
207 consisting of two parts.
209 The first part, executed when the generator function is called, must consist
210 of a CreateCont, which is responsible for suspending execution state into a new
211 Generator object (includes resume offset pointing to the start of the second
212 part of the function) and returning it back to the caller.
214 The second part is where the real user-level code of the generator should be
215 placed. ContEnter and ContRaise opcodes used in Generator's next(), send()
216 and raise() methods resume execution and transfer control to the resume offset
217 stored in the Generator object. The user-level code yields values using
218 Yield and YieldK opcodes and returns using RetC opcode.
224 Async functions are special type of functions representing asynchronous
225 execution. They can suspend while waiting for other asynchronous operations to
226 finish. This is achieved using Await opcode, which suspends execution into
227 an AsyncFunctionWaitHandle object. Once the given dependency is finished,
228 the scheduler resumes async function at the next opcode.
230 The async function body can be executed in 2 different modes. If the execution
231 was never suspended, we are in "eager execution" mode. The code executed after
232 the resume is executed in "resumed execution" mode.
234 The "eager execution" can end in 3 different ways. If a RetC opcode is reached,
235 the result is wrapped into a succeeded StaticWaitHandle and returned to the
236 caller. If an exception is thrown, it is wrapped into a failed StaticWaitHandle
237 and returned to the caller. Otherwise, if an Await opcode was reached and the
238 provided child WaitHandle has not finished, the current execution state is
239 suspended into an AsyncFunctionWaitHandle object and returned to the caller.
240 This mechanism allows fast execution if no blocking asynchronous operation was
243 The "resumed execution" mode is always entered from the scheduler. In this mode,
244 the async function either gets blocked on another dependency, or gets finished.
245 The scheduler is notified of these events using Await and RetC opcodes (or via
246 the unwinder if an exception was thrown) and the control is given back.
248 The async function implementation is still changing and the implementation may
249 change significantly, so this spec is staying light on details for now.
255 Entry points come in four varieties: the main entry point, DV entry points, and
258 Every function has exactly one main entry point. When a function is called, the
259 dispatcher will set the PC of the new frame to point to the main entry point if
260 either (1) the function does not have any optional parameters or (2) the caller
261 provides values for all of the optional parameters.
263 DV entry points are normally used to handle initializing optional parameters
264 that the caller did not provide. Generally the DV entries contain blocks that
265 initialize parameters, and then fall through directly into one another, with
266 the last block ending with a jump to the main entry point. This is not a
267 requirement, however. The dispatcher selects the appropriate DV entry point
268 based on the number of arguments passed into the function.
270 The main entry point and DV entry points are used by the dispatcher when
271 handling a function call. Each function's metadata provides an "entry point
272 table". Each row in the entry point table consists of a number of arguments and
273 the bytecode offset of the entry point that should be used by the dispatcher
274 (either the main entry point or a DV entry point).
276 Catch entry points are used by the unwinder to resume normal execution once a
277 matching "catch" block has been found and all the necessary cleanup has been
278 performed. When catch entry points are entered, the stack contains a single
281 More details about the unwinder and catch entry points can be found in the
282 "Exception handler (EH) table" and "Processing exceptions" sections.
288 Every compilation unit has a litstr table, a scalar array table, a function
289 table, and a class table.
291 The litstr table maps litstr ids to literal strings. Bytecodes that refer to
292 literal strings do so by litstr id. Litstr ids are signed 32-bit integer
293 values, which must be between 0 and 2^31 - 2 inclusive. In addition to the
294 per-unit litstr tables, a global table is built when generating an
295 "authoritative" repo (one in which all the PHP code is known at bytecode
296 generation time, and is guaranteed not to change). Global litstr ids can be
297 used in any unit, and are encoded in the range [2^30..2^31-2].
299 The scalar array table maps scalar array ids to a description of the contents
300 of a scalar array. An array is a scalar array if and only if each element of
301 the array is a null, boolean, integer, double, string, or a scalar array.
302 Furthermore, each element of a scalar array must be a cell. Finally, scalar
303 arrays may not recurse infinitely. Each scalar array id must be between 0 and
306 Each row in the function table contains a unique function id, a function name
307 specified by a litstr id, the bytecode offset for the corresponding function, a
308 flag that indicates if the function is unconditionally declared in the
309 outermost scope, and the function metadata. Note that there may be multiple
310 rows in the function table with same function name. However, there may not be
311 multiple rows that are marked as being unconditionally declared in the
312 outermost scope with the same function name. Each function id must be between 0
313 and 2^31 - 2 inclusive.
315 Each row in the class table contains a unique class id, a class name specified
316 by a litstr id, a flag that indicates if the class declaration is hoisted to
317 the prelude of pseudo-main, and the class metadata. Note that there may be
318 multiple rows in the class table with same class name. However, there may not
319 be multiple rows that are marked as being hoisted with the same class name.
320 Each class id must be between 0 and 2^31 - 2 inclusive.
323 Function parameter info (FPI) structures and the FPI stack
324 ----------------------------------------------------------
326 Every function has a function parameter info (FPI) structure associated with it
327 that can be retrieved at run time. The FPI structure contains the bytecode
328 address of the function, the number of parameters the function has, and a
329 parameter table that indicates whether each parameter is pass by value or pass
332 In addition to the evaluation stack, each frame also contains another stack
333 called the FPI stack. Each entry on the FPI stack consists of a reference to an
334 FPI structure and a bytecode address of entry point into the corresponding
335 function. The entry on the top of the FPI stack is called the "current FPI".
337 Arguments are pushed on the stack either as cells or as refs, but they may be
338 refs only if the parameter is passed by ref. Then, the FPush* instructions push
339 a new entry onto the FPI stack, initializing the entry with a reference to the
340 FPI structure for a given function and the bytecode address of the appropriate
341 entry point. Finally, the FCall instruction look at the current FPI to get the
342 bytecode address of the function (the callee), transfers the parameters from the
343 evaluation stack to the callee, pops the current FPI off of the FPI stack, and
344 then invokes the dispatcher to call the function.
346 Calls to builtin functions may be optimized to avoid pushing an entry on the
347 FPI stack if it is known that the builtin function does not need access to the
348 call stack. In this case, the arguments to the builtin are pushed on stack as
349 Cells and Vars, and the builtin can be invoked with the FCallBuiltin
350 instruction. Unless otherwise noted, subsequent references to the FCall
351 instruction should be meant to refer to non-optimized FCall instruction, i.e.
352 all FCall instructions other than FCallBuiltin.
358 The caller may pass any number of parameters to the callee by pushing zero or
359 more cells or refs on the stack prior to executing an FPush*/FCall instruction
360 sequence. The caller must pass the parameters in forward order, i.e. the first
361 pushed value corresponds to the first parameter, and so forth.
363 The FPush*/FCall instructions can be used to call a global function, a method
364 on an object, or a method from a class. The caller is responsible for
365 evaluating all of the parameters in forward order. When the caller executes the
366 FCall instruction, the dispatcher creates a new frame and moves the parameters
367 prepared by the caller into the callee's variable environment. The dispatcher
368 then transfers control to the appropriate entry point of the callee (either the
369 main entry point or a DV entry point) based on the number of parameters passed.
371 When the callee executes the Ret* instruction, the dispatcher pushes the return
372 value onto the caller's evaluation stack. Then the dispatcher destroys the
373 callee's frame and transfers control back to the caller.
376 Exception handler (EH) table
377 ----------------------------
379 The metadata for each function provides an "exception handler (EH) table".
380 Each row in the EH table (called an "EH entry") consists of a non-negative
381 integer "region depth", a set of non-overlapping ranges of bytecode that
382 compose the "protected region", and an offset of a catch entry point.
384 Each range of bytecode is given by a starting offset and an ending offset,
385 where the starting offset is the bytecode offset of the first byte of the first
386 instruction in the range and the ending offset is the bytecode offset after the
387 last byte of the last instruction in the range.
389 Note that two or more EH entries may refer to the same catch entry point.
390 Regardless of whether multiple EH entries share the same catch entry point,
391 each EH entry in the EH table will be considered to declare a distinct
394 The EH entries in each EH table must honor the following rules:
396 1) For each EH entry with a region depth of D and a protected region P, for all
397 other protected regions Q that overlap with P, one of the following must be
398 true: (i) Q has a region depth that is greater than D and P is a superset of
399 (or equal to) Q; or (ii) Q has a region depth that is less than D and P is a
400 subset of (or equal to) Q.
402 2) For each EH entry with a region depth of D and a protected region P, for
403 each integer I where 0 <= I < D there must be exactly one protected region Q in
404 the EH table where Q's region depth equals I and P overlaps with Q.
407 Processing exceptions
408 ---------------------
410 The unwinder maintains a stack of exception infos called the "exception stack".
411 An "exception info" is a record that contains an exception object, a reference
412 to a frame on the call stack, a program counter (PC), and a non-negative
413 integer "region depth". When a thread of execution first begins, the exception
414 stack is initially empty.
416 HHBC allows programs to throw exceptions via the Throw instruction. When a
417 Throw instruction executes, it pushes a new exception info to the top of the
418 exception stack that contains the thrown exception object, a reference to the
419 frame that threw the exception, the PC at the time the exception was thrown,
420 and a region depth of D where D equals the number of protected regions in the
421 current frame's EH table that cover PC. Then it transfers control to the
422 unwinder which starts processing the exception info at the top of the exception
423 stack by following the steps given at the end of this section starting with
424 step 1 until control is transferred elsewhere.
426 Here are the steps that the unwinder follows to process the exception info at
427 the top of the stack (called the "current exception info"):
429 Step 1) Consult the EH table of the current exception info's function. Check if
430 there are any EH entries that cover the current exception info's PC and
431 have a region depth that is less than the current exception info's
432 region depth. If one or more matching EH entries are found, choose the
433 EH entry with the greatest region depth and continue on to step 2. If
434 no matching EH entries are found go to step 4.
436 Step 2) Let E be the EH entry found in step 1, and let D be the region depth of
437 E. Set the current exception info's region depth to D (overwriting the
438 previous value). Continue on to step 3.
440 Step 3) Pop the current exception info off of the exception stack and push the
441 exception object implementing the Throwable interface on the evaluation
442 stack, then transfer control to E's catch entry point. If this catch
443 entry point corresponds to a PHP try/catch statement, it is responsible
444 for finding the matching PHP catch clause (e.g. by using the InstanceOfD
445 opcode) and rethrowing the exception if no matching clause was found.
447 Step 4) Pop the current frame off of the call stack and then check if the call
448 stack is empty. If the call stack is empty, read the current exception
449 info's exception X, clear the exception stack, and transfer control to
450 the unhandled exception facility passing along exception X. If the call
451 stack is not empty continue to step 5.
453 Step 5) Update the current exception info to refer to the new current frame at
454 the top of the call stack, and set the current exception info's PC to
455 point to the FCall* instruction which immediately precedes the PC of
456 the current frame. Next, set the current exception info's region depth
457 to D, where D equals the number of protected regions in the current
458 frame's EH table that cover the current exception info's PC. Then go to
465 As object properties are accessed during execution, the execution engine is
466 responsible for following certain rules to honor each property's accessibility
469 The accessibility and visibility of a property in a given class is determined
470 by that class's definition and the definitions of all of that class's
471 ancestors. When a property is declared in a class definition (a "declared
472 property") it may be specified as being "public", "protected", or "private".
473 Accessibility and visibility are two related but distinct concepts. Depending
474 on the current context, a property may be visible and accessible, visible but
475 inaccessible, or invisible and inaccessible.
477 If a property P is declared with the "public" qualifier in the definition of
478 class C, for instances of class C and descendent classes the property P will be
479 visible and accessible in all contexts. If C has an ancestor that declares a
480 public property with the same name as P, C is said to "redeclare" property P,
481 and the declaration of P in class C is considered to refer to the same property
482 as the declaration in the ancestor class.
484 If a property P is declared as "protected" in the definition of class C, for
485 instances of class C the property P will be visible in all contexts, but only
486 accessible in the context of class C, an ancestor class, or descendent class.
487 When class C is loaded at run time, a semantic check must be performed to
488 ensure that all ancestor classes of C do not declare a property as "public"
489 with the same name as P. If C has an ancestor that declares a public property
490 with the same name as P, the execution engine must throw a fatal error when
491 class C is loaded. If C has an ancestor that declares a protected property with
492 the same name as P, C is said to "redeclare" property P, and the declaration of
493 P in class C is considered to refer to the same property as the declaration in
494 the ancestor class. Note that there may exist a class D that is a descendent of
495 C and declares a property as "public" with the same name as P. In such cases
496 the new "public" declaration in D is considered to refer to the same property
497 as the original "protected" declaration in C, and the "protected" qualifier
498 from the original declaration is effectively overridden by the "public"
499 qualifier from the new declaration. Class D is said to "redeclare" property P
500 with the "public" qualifier. Thus, for instances of class D and descendent
501 classes of D, property P will be visible and accessible in all contexts.
502 Finally, if a class E that is descendent of C does not redeclare P as public
503 and does not have an ancestor class that redeclares P as public, for instances
504 of class E the property P will be visible in all contexts, but only accessible
505 in the context of class E, an ancestor class of E, or a descendent class of E.
507 If a property P is declared with the "private" qualifier in the definition of
508 class C, for instances of class C the property P will be visible in all
509 contexts, but only accessible in the context of class C. For instances of
510 descendent classes of C, the property P will be visible and accessible in the
511 context of the class C, and in all other contexts property P will be invisible
512 and inaccessible. When class C is loaded at run time, a semantic check must be
513 performed to ensure that all ancestor classes of C do not declare a property as
514 "public" or "protected" with the same as P. If C has an ancestor that declares
515 a public or protected property with the same name as P, the execution engine
516 must throw a fatal error when class C is loaded. Note that descendent classes
517 of C may declare another property with the same name as P. The declaration of
518 property P as "private" in class C is considered to define a separate property
519 that is distinct from all other properties of the same name declared in
520 ancestor classes and descendent classes of C.
522 An instruction that accesses a property specifies the property by a name N via
523 a litstr id, a local variable id, or a cell consumed from the evaluation stack.
524 As noted above, it is possible for a class to have multiple distinct properties
525 named N. In cases where there are multiple distinct properties named N, the
526 visibility rules are used to determine which property is retrieved. If there is
527 a visible private property P named N, then property P is retrieved. Otherwise,
528 if there is a visible non-private property Q named N, then property Q is
529 retrieved. If there is no visible property named N, the behavior is determined
530 by the specific instruction. The semantic checks and the visibility rules
531 ensure that for any context there cannot be more than one visible private
532 property, and there cannot be more than one visible non-private property.
534 Some instructions can create a new property at run time with a name that is
535 different than the names of all declared properties that are visible in the
536 current context. Such properties are called "non-declared properties" or
537 "dynamic properties". Dynamic properties are considered to be visible and
538 accessible in all contexts.
540 If a declared property is unset, and then re-accessed/re-created, then it is
541 treated the same way as an invisible property with the same attributes as the
542 original declared property. Specifically, if the property gets created again,
543 it must have the same access attributes as the original declared property.
546 Magic property access methods
547 -----------------------------
549 Instructions that access properties may in some cases invoke a magic property
550 access method (__get, __set, __isset, or __unset) if an object implements the
551 method and the method is considered eligible for invocation. A magic property
552 access method is considered "eligible" for a given object if there is not a
553 frame on the call stack that corresponds to an invocation of the same method on
557 Static property access
558 ----------------------
560 As a class's static properties are accessed during execution, the execution
561 engine is responsible for following certain rules to honor each static
562 property's accessibility and visibility.
564 The accessibility and visibility of a static property in a given class is
565 determined by that class's definition and the definitions of all of that
566 class's ancestors. When a static property is declared in a class definition it
567 may be specified as being "public", "protected", or "private". Depending on the
568 current context, a static property may be visible and accessible, visible but
569 inaccessible, or invisible and inaccessible.
571 Conceptually, each class has a "static store" associated with it at run time
572 that provides storage for the static properties declared in the class's
573 definition. Static properties are accessed at run time by name through the
574 scope of a class. When an instruction accesses a static property through the
575 scope of class C, it will search the static store of C and then the static
576 stores of C's ancestors (starting with C's base class and moving up the
577 inheritance chain) for the first static property with the given name that is
578 visible in the current context.
580 If a static property S is declared with the "public" qualifier in the
581 definition of class C, the static property S when accessed through the scope of
582 class C or a descendent of C will be visible and accessible in all contexts.
583 Note that descendent classes of C may declare another static property with the
584 same name as S. The declaration in class C is considered to define a separate
585 static property that is distinct from all other static properties declared in
586 descendent classes of C.
588 If a static property S is declared with the "protected" qualifier in the
589 definition of class C, the static property S when accessed through the scope of
590 class C or a descendent of C will be visible in all contexts, but only
591 accessible in the context of class C, an ancestor class of C, or descendent
592 class of C. When class C is loaded at run time, a semantic check must be
593 performed to ensure that all ancestor classes of C do not declare a static
594 property as "public" with the same name as S. If C has an ancestor that
595 declares a public static property with the same name as S, the execution engine
596 must throw a fatal error when class C is loaded. Note that descendent classes
597 of C may declare another static property with the same name as S. The
598 declaration in class C is considered to define a separate static property that
599 is distinct from all other static properties declared in descendent classes of
602 If a static property S is declared with the "private" qualifier in the
603 definition of class C, the static property S when accessed through the scope of
604 class C will be visible in all contexts, but only accessible in the context of
605 class C. The static property S when accessed through the scope of a descendent
606 of C will only be visible and accessible in the context of class C. When class
607 C is loaded at run time, a semantic check must be performed to ensure that all
608 ancestor classes of C do not declare a static property as "public" or
609 "protected" with the same name as S. If C has an ancestor that declares a
610 public or protected static property with the same name as S, the execution
611 engine must throw a fatal error when class C is loaded. Note that descendent
612 classes of C may declare another static property with the same name as S. The
613 declaration in class C is considered to define a separate static property that
614 is distinct from all other static properties declared in descendent classes of
617 Note that instructions cannot create new static properties in a class that were
618 not declared in the class definition.
624 An FPI region is a contiguous range of bytecode that constitutes a call site.
625 Each FPI region begins immediately after an FPush* instruction that pushes an
626 FPI structure onto the FPI stack and should normally end with the corresponding
627 FCall instruction that pops that FPI structure off of the FPI stack. Since there
628 are no other instructions between FPush* and FCall, only the FCall instruction
629 is considered to be a part of the FPI region.
631 Each function has an "FPI region table". Each row in the FPI region table
632 consists of offset of the FPush* instruction that begins the region, the FCall
633 instruction that ends the region, and the number of parameters being passed.
639 Any given value on the stack must either be a cell or ref at run time. However,
640 at bytecode generation time the specific flavor of a value on the stack is not
641 always known. HipHop bytecode uses symbols called "flavor descriptors" to
642 precisely describe what is known at bytecode generation about the state of the
643 evaluation stack at each instruction boundary.
645 Each instruction description specifies the flavor descriptor produced for each
646 of its outputs. Each description also specifies the flavor descriptor consumed
647 for each of the instruction's inputs.
649 Here is a description of each flavor descriptor:
651 C - cell; specifies that the value must be a cell at run time
652 V - ref; specifies that the value must be a ref at run time
653 U - uninit; specifies that the value must be an uninitialized null at run
654 time; this is only used for FCallBuiltin, CreateCl, and CUGetL.
656 Classrefs are not assigned a flavor as they only can appear within classref
657 slots and thus are implicit.
662 Because instructions specify constraints on the flavor descriptor of each
663 input, it is important to be able to determine if a given HHBC program
664 satisfies these constraints. A program that satisfies the constraints on the
665 inputs to each instruction is said to be "flavor-safe".
667 HHBC provides a set of verification rules that can be mechanically applied to
668 verify that an HHBC program is flavor-safe. All valid HHBC programs must be
669 verifiably flavor-safe, and the execution engine may refuse to execute HHBC
670 programs that cannot be verified.
672 At bytecode generation time, what is known about the state of the evaluation
673 stack at a given instruction boundary can be precisely described using flavor
676 In addition to being flavor-safe, there are other invariants that valid HHBC
677 programs must uphold with respect to metadata and how certain instructions are
680 Below is the complete list of verifiability rules. If the bytecode to be
681 executed does not come from a trusted source, it is the responsibility of the
682 bytecode execution engine to verify that these invariants hold.
684 1) The depth of the evaluation stack at any given point in the bytecode must be
685 the same for all possible control flow paths. The flavor descriptor of any
686 given slot on the evaluation stack at any given point in the bytecode must be
687 the same for all possible control flow paths.
689 2) No instruction may consume more values from the evaluation stack than are
690 available at that given point in the bytecode. Likewise, the flavor descriptor
691 of each slot on the evaluation stack must be compatible with the instruction's
692 inputs' flavor descriptors.
694 3) The evaluation stack must be empty and all classref slots must be
695 uninitialized at any offset listed as a catch entry point.
697 4) If a given instruction is not the target of a forward branch and it follows
698 a Jmp, Switch, SSwitch, RetC, Fatal, Throw, or NativeImpl instruction, the
699 evaluation stack before executing the given instruction must be empty, and all
700 classref slots must be uninitialized.
702 5) Before executing the RetC instruction, the evaluation stack must contain
703 exactly one value and the flavor descriptor of the value must be cell.
704 Finally, before executing the NativeImpl instruction, the evaluation stack must
705 be empty. In all the above cases, all classref slots must be uninitialized.
707 6) The code for the function body must be laid out in one contiguous block.
709 7) The last instruction of the function body must be either a control flow
710 without fallthrough or a terminal instruction.
712 8) Each FPI region enumerated in the FPI region table must start immediately
713 after an FPush* instruction and it must end with the FCall instruction. Each
714 use of the FPush* instruction must be the instruction immediately before
715 exactly one FPI region. Likewise, each use of the FCall instruction must be
716 the last instruction in exactly one FPI region.
718 9) Each FPI region may not contain any other instruction than FCall, with the
719 exception of assertion instructions. There may not be jumps anywhere in the
720 function that transfer control from the outside of a given FPI region to the
721 inside of that region. Finally, an entry point may not point to an instruction
722 inside an FPI region.
724 10) The initialization state of each iterator variable must be known at every
725 point in the code and must be the same for all control paths. There are two
726 possible states: (1) uninitialized, and (2) "iter-initialized" (initialized
727 via IterInit*). Every range of bytecode for which an iterator variable i is
728 initialized must be protected by an EH entry with a catch handler that unsets
729 i by calling IterFree.
731 11) The iterator variable referenced by IterInit* must be in the uninitialized
732 state when the instruction executes. An iterator variable referenced by
733 IterNext* and IterFree must be in the "iter-initialized" state. Note that
734 IterInit* conditionally initialize the iterator variable, and IterNext*
735 conditionally free the iterator variable.
737 12) Each EH table must follow all of the rules specified in the "Exception
738 handler (EH) table" section.
740 13) The initialization state of each classref slot must be known at every point
741 in the code and must be the same for all control paths. A classref slot must be
742 initialized before being read and becomes uninitialized after being read. A
743 classref slot must be uninitialized before being written to and becomes
744 initialized after being written.
746 14) Assertion (AssertRATL and AssertRATStk) instructions cannot be separated
747 from the following instruction by control flow. Practically speaking, this means
748 that the instruction immediately following an assertion cannot be a jump target.
750 15) Sequences of member instructions should be consistent and continuous. That
751 is, only member instructions and asserts may appear in the sequence, control
752 flow cannot interrupt the sequence, and the member op mode should be consistent
753 across all instructions in the sequence. This is because in the case of
754 exceptions the unwinder decides whether the member state is live by looking at
755 the instruction that threw.
760 Each instruction description below consists of a mnemonic, followed by 0 or
761 more immediate operands, followed by a stack transition description of the form
762 "[xn,...,x2,x1] -> [ym,...,y2,y1]", where "[xn,...,x2,x1]" is a list of flavor
763 descriptors describing what the instruction consumes from the evaluation stack
764 and "[ym,...,y2,y1]" is the list of flavor descriptors describing what the
765 instruction pushes onto the stack. x1 and y1 represent the topmost stack
766 elements before and after execution, respectively.
768 Each element of a stack transition may also contain an optional type
769 annotation. Here is the list of the type annotations used in instruction
772 Null - denotes the null type
773 Bool - denotes the boolean type
774 Int - denotes the integer type
775 Dbl - denotes the double-precision floating-point type
776 Str - denotes the string type
777 Arr - denotes the array type
778 Vec - denotes the vec type
779 Dict - denotes the dict type
780 Keyset - denotes the keyset type
781 Obj - denotes the object type
782 ArrLike - denotes array, vec, dict, or keyset
784 Multiple type annotations may be combined together using the "|" symbol. For
785 example, the type annotation "Int|Dbl" means that a value is either integer or
788 Some instructions may contain multiple stack transition descriptions to express
789 the relationship between the types of the values consumed from the stack and
790 types of the values pushed onto the stack. Also, in some stack transition
791 descriptions, "<T>" is used as shorthand to represent any one specific type.
792 For example, a transition such as "[C:<T>] -> [C:<T>]" indicates that the type
793 of value that the instruction pushes onto the stack will match the type of
794 value that it consumed from the stack. Likewise, "<F>" is used as shorthand to
795 represent any one specific flavor descriptor.
797 $1 is used to refer to the value at the top of the evaluation stack, $2 is used
798 to refer to the value directly below $1 on the evaluation stack, $3 is used to
799 refer to the value directly below $2, and so forth. Also, %1 is used to refer
800 to the first immediate argument, and %2 is used to refer to the second
803 Note that the relative offset immediate used by a Jmp*, Iter*, Switch,
804 or SSwitch instruction is relative to the beginning of the instruction.
806 There are numerous instructions that operate on different kinds of locations.
807 Locations are specified using "location descriptors". The complete list of
808 location descriptors is given below:
810 L - local id; location is the local variable whose id is given by an
812 N - local name; location is the local variable whose name is given by the
814 G - global name; location is the global variable whose name is given by the
816 S - static property; location is the static property whose class is given by
817 a classref and whose name is given by value of a cell.
818 C - cell; location is a temporary value given by a cell.
819 H - $this; location is the $this pointer in the current frame. Must only be
820 used in a frame that is known to have a non-null $this pointer; CheckThis
821 is most commonly used to ensure this.
823 There are several groups of similarly named instructions where the name of each
824 instruction ends with a different location descriptor (for example, Set*). Each
825 instruction in the group perform similar actions but take different kinds of
826 inputs to specify the location to access.
828 The member instructions provide functionality to operate on elements and
829 properties. Many of these instructions incorporate an immediate argument which
830 specifies a one of the following member descriptors:
832 EC - consume a cell from the evaluation stack as an element
833 EL:<id> - consume a local given by an immediate id as an element
834 ET:<id> - consume a litstr given by an immediate id as an element
835 EI:<int> - consume a immediate integer as an element
836 PC - consume a cell from the evaluation stack as a property
837 PL:<id> - consume a local given by an immediate id as a property
838 PT:<id> - consume a litstr given by an immediate id as a property
839 QT:<id> - a nullsafe version of PT:<id>. The null-base doesn't issue
840 a warning, and no stdClass promotion in write context for the
841 base happens. Consume a litstr given by an immediate id
843 W - synthesize a new element (no corresponding local variable or
844 evaluation stack slot)
846 The instruction set is organized into the following sections:
847 1. Basic instructions
848 2. Literal and constant instructions
849 3. Operator instructions
850 4. Control flow instructions
852 6. Isset, Empty and type querying instructions
853 7. Mutator instructions
856 10. Member instructions
857 11. Iterator instructions
858 12. Include, eval, and define instructions
859 13. Miscellaneous instructions
860 14. Generator creation and execution
864 1. Basic instructions
865 ---------------------
869 No operation. This instruction does nothing.
873 No operation. This instruction is occasionally inserted by the emitter to
874 avoid having jumps to the entry of a function. Contrary to a Nop, EntryNop
875 is guaranteed to not be optimized away.
877 DiscardClsRef <class-ref slot> [] -> []
879 Discard the class in %1.
885 Pop. Discards the value on the top of the stack.
887 PopU2 [U C:<T>] -> [C:<T>]
889 Pop two. Discards the uninit underneath the cell on top of the stack.
891 PopL <local variable id> [C] -> []
893 Teleport value from the stack into a local. This instruction marks the local
894 variable given by %1 as defined and pops and stores the value $1 into the
895 local variable. This instruction behaves as if it was a SetL PopC pair, but
896 might be implemented more efficiently.
898 Dup [C:<T>] -> [C:<T> C:<T>]
900 Duplicate. Duplicates the cell $1 and pushes it onto the stack.
902 Box [C:<T>] -> [V:<T>]
904 Box. Creates a new ref, sets the new ref to point at a copy of cell $1, and
905 pushes the ref onto the stack.
907 CGetCUNop [C|U:<T>] -> [C:<T>]
909 Convert a cell or uninit value to a cell, no op. This is a flavor-safety only
910 opcode and should only be used when $1 is statically known to be a cell.
912 UGetCUNop [C|U:<T>] -> [U:<T>]
914 Convert a cell or uninit value to an uninit, no op. This is a flavor-safety
915 only opcode and should only be used when $1 is statically known to be an
918 2. Literal and constant instructions
919 ------------------------------------
925 Push constant. Null pushes null onto the stack, True pushes true onto the
926 stack, and False pushes false onto the stack.
930 Push an uninitialized null on the stack.
932 Int <signed 64-bit integer value> [] -> [C:Int]
933 Double <double value> [] -> [C:Dbl]
934 String <litstr id> [] -> [C:Str]
935 Array <scalar array id> [] -> [C:Arr]
936 Vec <scalar vec id> [] -> [C:Vec]
937 Dict <scalar dict id> [] -> [C:Dict]
938 Keyset <scalar keyset id> [] -> [C:Keyset]
940 Push immediate. Pushes %1 onto the stack.
942 NewArray <capacity hint> [] -> [C:Arr]
944 New array, with a capacity hint. Creates a new array and pushes it onto the
945 stack. The implementation may make use of the hint in %1 to pre-size the
946 array. The hint %1 must be greater than or equal to 0.
948 NewMixedArray <capacity hint> [] -> [C:Arr]
950 New array in mixed mode, with a capacity hint. Creates a new array and pushes
951 it onto the stack. The implementation may make use of the hint in %1 to
952 pre-size the array. The hint %1 must be greater than or equal to 0.
954 NewDictArray <capacity hint> [] -> [C:Dict]
956 New dict, with a capacity hint. Creates a new dict and pushes
957 it onto the stack. The implementation may make use of the hint in %1 to
958 pre-size the array. The hint %1 must be greater than or equal to 0.
960 NewLikeArrayL <local variable id> <capacity hint> [] -> [C:Arr]
962 New array with the same kind as the array stored in the local variable %1.
963 If %1 is not an array, returns an array in mixed mode. The implementation
964 may make use of the hint in %2 to pre-size the array. If %2 == 0, the
965 implementation may instead use the size of %1 as the hint.
967 NewPackedArray <num elems> [C..C] -> [C]
969 New array. Creates a new array from the top %1 cells on the stack, pops those
970 cells, then pushes the new array onto the stack. Elements are pushed on the
971 stack in array insertion order and are implicitly numbered from 0 to %1 - 1.
972 $1 is at index %i - 1, $2 at %1-2, and so on; $(%1) is at index 0.
974 NewStructArray <litstr id vector> [C..C] -> [C]
976 New array. Creates a new array from the names given in %1 and values from the
977 stack. The vector of litstr ids gives the element names, one value for each
978 name is popped from the stack. Names are in array insertion order, and values
979 were pushed onto the stack in insertion order, so are added to the array in
980 reverse order (the topmost value will become the last element in the array).
983 NewStructArray < "a" "b" > [ 1 2 ] -> [ array("a"=>1, "b"=>2) ]
985 NewStructDArray <litstr id vector> [C..C] -> [C]
987 New dict-like array. Creates a new dict-like array from the names given in %1
988 and values from the stack. The vector of litstr ids gives the element names,
989 one value for each name is popped from the stack. Names are in array
990 insertion order, and values were pushed onto the stack in insertion order, so
991 are added to the array in reverse order (the topmost value will become the
992 last element in the array). For example:
994 NewStructDArray < "a" "b" > [ 1 2 ] -> [ darray("a"=>1, "b"=>2) ]
996 NewStructDict <litstr id vector> [C..C] -> [C:Dict]
998 New dict array. Creates a new dict array from the names given in %1 and
999 values from the stack. The vector of litstr ids gives the element names, one
1000 value for each name is popped from the stack. Names are in array insertion
1001 order, and values were pushed onto the stack in insertion order, so are added
1002 to the array in reverse order (the topmost value will become the last element
1003 in the array). For example:
1005 NewStructDict < "a" "b" > [ 1 2 ] -> [ dict("a"=>1, "b"=>2) ]
1007 NewVecArray <num elems> [C..C] -> [C:Vec]
1009 New vec. Creates a new vec from the top %1 cells on the stack, pops those
1010 cells, then pushes the new vec onto the stack. Elements are pushed on the
1011 stack in vec insertion order.
1013 NewKeysetArray <num elems> [C..C] -> [C:Keyset]
1015 New keyset. Creates a new keyset from the top %1 cells on the stack, pops
1016 those cells, then pushes the new keyset onto the stack. Elements are pushed
1017 on the stack in keyset insertion order.
1019 NewVArray <num elems> [C..] -> [C:Arr]
1021 New vec-like array. Creates a new vec-like array from the top %1 cells on the
1022 stack, pops those cells, then pushes the new array onto the stack. Elements
1023 are pushed on the stack in array insertion order.
1025 NewDArray <capacity hint> [] -> [C:Arr]
1027 New dict-like array with a capacity hint. Creates a new dict-like array and
1028 pushes it onto the stack. The implementation may make use of the hint in %1
1029 to pre-size the array. The hint %1 must be greater than or equal to 0.
1031 AddElemC [C C C] -> [C:Arr|Dict]
1033 Add element. If $3 is an array or dict, this instruction executes $3[$2] = $1
1034 and then pushes $3 onto the stack.
1036 If $3 is not an array or dict, this instruction throws a fatal error.
1038 AddElemV [C C V] -> [C:Arr]
1040 Add element. If $3 is an array, this instruction executes $3[$2] = &$1 and
1041 then pushes $3 onto the stack.
1043 If $3 is not an array, this instruction throws a fatal error.
1045 AddNewElemC [C C] -> [C:Arr|Vec|Keyset]
1047 Add new element. If $2 is an array, vec, or keyset this instruction executes
1048 $2[] = $1 and then pushes $2 onto the stack.
1050 If $2 is not an array, vec, or keyset, this instruction throws a fatal error.
1052 AddNewElemV [C V] -> [C:Arr]
1054 Add new element. If $2 is an array, this instruction executes $2[] = &$1 and
1055 then pushes $2 onto the stack.
1057 If $2 is not an array, this instruction throws a fatal error.
1059 NewCol <coll type> [] -> [C:Obj]
1061 New collection. Creates a empty new collection of type %1, and pushes it
1062 onto the stack. %1 must be one of the values of the CollectionType enum other
1065 NewPair [C C] -> [C:Obj]
1067 New Pair collection. Creates a Pair from the top 2 cells on the stack, and
1068 pushes it onto the stack. Values were pushed onto the stack in the order
1069 they exist in the pair, so are added to it in reverse order (the top value
1070 on the stack will become the second element of the pair).
1072 ColFromArray <coll type> [C:Arr] -> [C:Obj]
1074 Create a collection of type %1 from array $1, and pushes the collection onto
1075 the stack. %1 must be one of the values of the CollectionType enum other
1076 than Pair. The array will be used to implement the collection without
1077 conversion or duplication, thus it should not contain references. $1 must be
1078 in packed mode if %1 is Vector or ImmVector, and must be in mixed mode
1081 Note that integer-like string keys are converted to integers in array, but
1082 not in collections; thus not all collections can be created using this
1085 CnsE <litstr id> [] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
1087 Get constant. Pushes the value of the global constant named %1 onto the stack
1088 as a cell. If there is no constant named %1, throws a fatal error.
1090 ClsCns <litstr id> <class-ref slot> [] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
1092 Get class constant. This instruction pushes the value of the class constant
1093 named %1 from class %2 onto the stack. If there is no class constant named %1
1094 in class %2, this instruction throws a fatal error.
1096 ClsCnsD <litstr id> <litstr id> [] -> [C:Null|Bool|Int|Dbl|Str|Arr|Vec|Dict|Keyset|Resource]
1098 Get class constant (direct). This instruction first checks if %2 matches the
1099 name of a defined class. If %2 does not match the name of a defined class,
1100 this instruction will invoke the autoload facility passing in the class name
1101 %2, and then it will again check if %2 matches the name of a defined class.
1102 If %2 still does not match the name of a defined class this instruction
1103 throws a fatal error.
1105 Next, this instruction pushes the value of the class constant named %1 from
1106 class %2 onto the stack. If there is no class constant named %1 in class %2,
1107 this instruction throws a fatal error.
1109 File [] -> [C:Static Str]
1110 Dir [] -> [C:Static Str]
1111 Method [] -> [C:Static Str]
1113 Push string. File pushes __FILE__ onto the stack, Dir pushes __DIR__ onto
1114 the stack, and Method pushes __METHOD__.
1116 ClsRefName <class-ref slot> [] -> [C:Static Str]
1118 Push the name of the class in %1 as a string.
1121 3. Operator instructions
1122 ------------------------
1124 Concat [C C] -> [C:Str]
1126 Concatenation (.). Pushes ((string)$2 . (string)$1) on the stack.
1128 ConcatN <n> [C..C] -> [C:Str]
1130 Concatenation (.). Pushes ((string)$n . ... . (string)$1) on the stack.
1132 Abs [C] -> [C:Int|Dbl|Bool]
1134 Absolute value. Computes the absolute value of $1 and pushes the result onto
1137 Add [C:Arr C:Arr] -> [C:Arr]
1138 [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1139 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl &&
1140 (T1 != Arr || T2 != Arr))
1142 Addition (+). Performs addition (or plus-merge if $1 and $2 are both arrays).
1143 Pushes ($2 + $1) onto the stack. This instruction throws a fatal error if
1144 is_array($1) xor is_array($2) is true.
1146 Sub [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1147 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl)
1149 Subtraction (-). Pushes ($2 - $1) onto the stack. This instruction throws a
1150 fatal error if is_array($1) || is_array($2) is true.
1152 Mul [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1153 [C:<T2> C:<T1>] -> [C:Int] (where T1 != Dbl && T2 != Dbl)
1155 Multiplication (*). Pushes ($2 * $1) onto the stack. This instruction throws
1156 a fatal error if is_array($1) || is_array($2) is true.
1158 AddO [C:Arr C:Arr] -> [C:Arr]
1159 [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1160 [C:<T2> C:<T1>] -> [C:Int|dbl] (where T1 != Dbl && T2 != Dbl &&
1161 (T1 != Arr || T2 != Arr))
1163 Same behavior as Add, except for when both inputs have type Int and the
1164 result would not fit in a 64-bit integer. Then this instruction will push
1165 (double)$1 + (double)$2.
1167 SubO [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1168 [C:<T2> C:<T1>] -> [C:Int|Dbl] (where T1 != Dbl && T2 != Dbl)
1170 Same behavior as Sub, except for when both inputs have type Int and the
1171 result would not fit in a 64-bit integer. Then this instruction will push
1172 (double)$2 - (double)$1.
1174 MulO [C:<T2> C:<T1>] -> [C:Dbl] (where T1 == Dbl || T2 == Dbl)
1175 [C:<T2> C:<T1>] -> [C:Int|Dbl] (where T1 != Dbl && T2 != Dbl)
1177 Same behavior as Mul, except for when both inputs have type Int and the
1178 result would not fit in a 64-bit integer. Then this instruction will push
1179 (double)$1 * (double)$2.
1181 Div [C C] -> [C:Bool|Int|Dbl]
1182 [C:Dbl C:Int] -> [C:Bool|Dbl]
1183 [C:Int C:Dbl] -> [C:Bool|Dbl]
1184 [C:Dbl C:Dbl] -> [C:Bool|Dbl]
1186 Division (/). Pushes ($2 / $1) onto the stack. This instruction throws a
1187 fatal error if is_array($1) || is_array($2) is true.
1189 Mod [C C] -> [C:Bool|Int]
1191 Modulus (%). Pushes ((int)$2 % (int)$1) onto the stack. This instruction
1192 never throws a fatal error.
1194 Pow [C C] -> [C:Int|Dbl]
1196 Power. Pushes $2 raised to the power of $1 onto the stack. This instruction
1197 never throws a fatal error.
1199 Sqrt [C] -> [C:Null|Dbl]
1201 Square root. Computes the square root of $1 and pushes the result onto the
1202 stack. If $1 is not null, a bool, an int, a double, or a numeric string, it
1203 raises a warning and pushes null onto the stack.
1205 If $1 is a negative number, this instruction pushes a floating-point value
1206 representing NAN onto the stack.
1208 Xor [C C] -> [C:Bool]
1210 Logical xor (xor). Pushes ((bool)$2 xor (bool)$1) onto the stack.
1214 Logical not (!). Pushes (!(bool)$1) onto the stack.
1216 Same [C C] -> [C:Bool]
1218 Same (===). Pushes ($2 === $1) onto the stack.
1220 NSame [C C] -> [C:Bool]
1222 Not same (!==). Pushes ($2 !== $1) onto the stack.
1224 Eq [C C] -> [C:Bool]
1226 Equals (==). Pushes ($2 == $1) onto the stack.
1228 Neq [C C] -> [C:Bool]
1230 Not equal (!=). Pushes ($2 != $1) onto the stack.
1232 Lt [C C] -> [C:Bool]
1234 Less than (<). Pushes ($2 < $1) onto the stack.
1236 Lte [C C] -> [C:Bool]
1238 Less than or equal to (<=). Pushes ($2 <= $1) onto the stack.
1240 Gt [C C] -> [C:Bool]
1242 Greater than (>). Pushes ($2 > $1) onto the stack.
1244 Gte [C C] -> [C:Bool]
1246 Greater than or equal to (>=). Pushes ($2 >= $1) onto the stack.
1248 Cmp [C C] -> [C:Int]
1250 Comparison. Pushes either -1, 0, or 1 onto the stack if ($1 < $2), ($1 ==
1251 $2), or ($1 > $2), respectively.
1253 BitAnd [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1254 [C:Str C:Str] -> [C:Str]
1256 Bitwise and (&). Pushes ($2 & $1) onto the stack. If either $1 or $2 is an
1257 object, this instruction throws a fatal error.
1259 BitOr [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1260 [C:Str C:Str] -> [C:Str]
1262 Bitwise or (|). Pushes ($2 | $1) onto the stack. If either $1 or $2 is an
1263 object, this instruction throws a fatal error.
1265 BitXor [C:<T2> C:<T1>] -> [C:Int] (where T1 != Str || T2 != Str)
1266 [C:Str C:Str] -> [C:Str]
1268 Bitwise xor (^). Pushes ($2 ^ $1) onto the stack. If either $1 or $2 is an
1269 object, this instruction throws a fatal error.
1271 BitNot [C:<T>] -> [C:Int] (where T != Str)
1274 Bitwise not (~). Pushes (~$1) onto the stack. If $1 is null, a boolean, an
1275 array, or an object, this instruction throws a fatal error.
1277 Shl [C C] -> [C:Int]
1279 Shift left (<<). Pushes ((int)$2 << (int)$1) onto the stack. This instruction
1280 never throws a fatal error.
1282 Shr [C C] -> [C:Int]
1284 Shift right (>>). Pushes ((int)$2 >> (int)$1) onto the stack. This
1285 instruction never throws a fatal error.
1287 Floor [C] -> [C:Dbl]
1289 Round $1 to nearest integer value not greater than $1. Converts $1 to numeric
1290 as appropriate and then takes floor of resulting numeric value.
1294 Round $1 to nearest integer value not less than $1. Converts $1 to numeric as
1295 appropriate and then takes ceil of resulting numeric value.
1297 CastBool [C] -> [C:Bool]
1299 Cast to boolean ((bool),(boolean)). Pushes (bool)$1 onto the stack.
1301 CastInt [C] -> [C:Int]
1303 Cast to integer ((int),(integer)). Pushes (int)$1 onto the stack.
1305 CastDouble [C] -> [C:Dbl]
1307 Cast to double ((float),(double),(real)). Pushes (double)$1 onto the stack.
1309 CastString [C] -> [C:Str]
1311 Cast to string ((string),(binary)). Pushes (string)$1 onto the stack. If $1
1312 is an object that implements the __toString method, the string cast returns
1313 $1->__toString(). If $1 is an object that does not implement __toString
1314 method, the string cast throws a fatal error.
1316 CastArray [C] -> [C:Arr]
1318 Cast to array ((array)). Pushes (array)$1 onto the stack.
1320 CastObject [C] -> [C:Obj]
1322 Cast to object ((object)). Pushes (object)$1 onto the stack.
1324 CastVec [C] -> [C:Vec]
1326 Cast to vec array. Pushes vec($1) onto the stack.
1328 CastDict [C] -> [C:Dict]
1330 Cast to dict. Pushes dict($1) onto the stack.
1332 CastKeyset [C] -> [C:Keyset]
1334 Cast to keyset. Pushes keyset($1) onto the stack.
1336 CastVArray [C] -> [C:Arr]
1338 Cast to vec-like array. Performs an array cast, but drops any keys from the
1339 input and handles object inputs like CastVec.
1341 CastDArray [C] -> [C:Arr]
1343 Cast to dict-like array. Performs an array cast, but handles object inputs
1346 InstanceOf [C C] -> [C:Bool]
1348 Instance of (instanceof). If $1 is a string and it matches the name of a
1349 defined class and $2 is an object that is an instance of $1, this instruction
1350 pushes true onto the stack. If $1 is an object and get_class($1) matches the
1351 name of a defined class and $2 is an object that is an instance of
1352 get_class($1), this instruction pushes true onto the stack. If $1 is not a
1353 string or an object, this instruction throws a fatal error.
1355 InstanceOfD <litstr id> [C] -> [C:Bool]
1357 Instance of direct (instanceof). If %1 matches the name of a defined class
1358 and $1 is an instance of the %1, this instruction pushes true onto the stack,
1359 otherwise it pushes false onto the stack.
1361 Select [C C C] -> [C]
1363 Pushes (bool)$1 ? $2 : $3 onto the stack.
1365 DblAsBits [C] -> [C]
1367 If $1 is a double, reinterpret it as an integer (with the same bit-pattern)
1368 and push it onto the stack. Otherwise, push 0.
1370 IsLateBoundCls [C] -> [C:Bool]
1372 If $1 is a subtype of the current late-bound class, this instruction pushes
1373 true onto the stack, otherwise it pushes false onto the stack.
1375 IsTypeStructC <type struct resolve op> [C C] -> [C:Bool]
1377 If $1 matches the type structure of a defined type and $2 is a subtype of $1,
1378 this instruction pushes true onto the stack, otherwise it pushes false onto
1380 If the type struct resolve op is Resolve, then resolves the type structure in
1381 $1 before performing the subtype check.
1382 If the type struct resolve op is DontResolve and the given type structure is
1383 unresolved, then this instruction raises an error.
1385 AsTypeStructC <type struct resolve op> [C C] -> [C]
1387 If $1 matches the type structure of a defined type and $2 is a subtype of $1,
1388 this instruction pushes $1 onto the stack, otherwise it throws an exception.
1389 If the type struct resolve op is Resolve, then resolves the type structure in
1390 $1 before performing the subtype check.
1391 If the type struct resolve op is DontResolve and the given type structure is
1392 unresolved, then this instruction raises an error.
1394 CombineAndResolveTypeStruct <num type structures> [C..C] -> [C]
1396 Consumes a type structure from the stack that potentially has holes in it,
1397 and (%1 - 1) amount of type structures from the stack and merges these type
1398 structures into the first type structure. Merging means that the hole on the
1399 first type structure denoted by the reified type kind will be replaced by the
1400 type structure whose id matches the id provided at this field. If the id at
1401 this field does not match that of any given type structures or the provided
1402 inputs are not valid type structures, this instruction throws a fatal error.
1403 After merging, this instruction resolves the final type structure and pushes
1406 Print [C] -> [C:Int]
1408 Print (print). Outputs (string)$1 to STDOUT and pushes the integer value 1
1411 Clone [C] -> [C:Obj]
1413 Clone (clone). Clones $1 and pushes it onto the stack. If $1 is not an
1414 object, this instruction throws a fatal error.
1416 Exit [C] -> [C:Null]
1418 Exit (exit). Terminates execution of the program.
1420 If $1 is an integer, this instruction will set the exit status to $1, push
1421 null onto the stack, and then it will terminate execution.
1423 If $1 is not an integer, this instruction will output (string)$1 to STDOUT,
1424 set the exit status to 0, push null onto the stack, and then it will
1425 terminate execution.
1427 Fatal <fatal subop> [C] -> []
1429 Fatal. This instruction throws a fatal error using $1 as the error message.
1430 If $1 is not a string, this instruction throws a fatal error with an error
1431 message that indicates that the error message was not a string. Setting %1 to
1432 0 will throw a runtime fatal error with a full backtrace. Setting %1 to 1
1433 will throw a parse fatal error with a full backtrace. Setting %1 to 2 will
1434 throw a runtime fatal error with the backtrace omitting the top frame.
1437 4. Control flow instructions
1438 ----------------------------
1440 Jmp <rel offset> [] -> []
1442 Jump. Transfers control to the location specified by %1.
1444 JmpNS <rel offset> [] -> []
1446 Jump, with no surprise flag checks (NS means "no surprise"). This behaves
1447 identically to the Jmp instruction, except that internal VM checks for things
1448 like OOM and timeouts do not need to be performed even if the offset is
1449 negative. This instruction cannot have a zero offset (i.e. it cannot jump to
1452 JmpZ <rel offset> [C] -> []
1454 Jump if zero. Conditionally transfers control to the location specified by %1
1455 if (bool)$1 == (bool)0.
1457 JmpNZ <rel offset> [C] -> []
1459 Jump if not zero. Conditionally transfers control to the location specified
1460 by %1 if (bool)$1 != (bool)0.
1462 Switch <bounded> <base> <offset vector> [C] -> []
1464 Switch over integer case values. If bounded == SwitchKind::Unbounded, the
1465 implementation will assume that $1 is an integer in the range [0,
1466 length(vector)) and unconditionally transfer control to the location
1467 specified by vector[$1]. Undefined behavior will result if $1 is not an
1468 integer inside this range. If bounded == SwitchKind::Bounded, the following
1471 For a bounded Switch, the last two elements of the offset vector are special:
1472 they represent the first non-zero case and the default case, respectively.
1473 base + length(vector) - 2 must not be greater than 2^63-1. If $1 === true,
1474 control will be transferred to the location specified by
1475 vector[length(vector) - 2]. If $1 is equal (as defined by Eq) to any integer
1476 $n in the range [base, base + length(vector) - 2), control will be
1477 transferred to the location specified by vector[$n - base]. Otherwise,
1478 control will be transferred to the location specified by
1479 vector[length(vector) - 1].
1481 SSwitch <litstr id/offset vector> [C] -> []
1483 Switch over string case values. This instruction will search the
1484 string/offset vector from the beginning until it finds a string that is equal
1485 to $1. If one is found, control will be transferred to the location specified
1486 by the offset corresponding to that string. If a matching string is not
1487 found, control is transferred to the location specified by the final element
1488 in the vector, which must have a litstr id of -1.
1492 Return a cell. Returns $1 to the caller.
1494 If this instruction is used inside an async function executed in an "eager
1495 execution" mode, the $1 is wrapped into a StaticResultWaitHandle prior to
1496 return. In a "resumed execution" mode, the control is given back to the
1497 scheduler and it is informed that the async function has finished.
1499 If used in a generator, the Generator object is marked as finished and
1500 the control is given back to the next instruction after ContEnter or
1501 ContRaise instruction in a previous frame. The $1 must be Null.
1503 RetCSuspended [C] -> []
1505 Return a cell. Returns $1, which is an already suspended wait-handle, to the
1506 caller. This instruction can only be used within async functions. This is
1507 meant to be used within memoized async functions where the memoized value to
1508 be returned is already wrapped in a wait-handle.
1510 RetM <num returns> [C..C] -> []
1512 RetM is a variant of RetC that allows multiple cells to be returned. The RetM
1513 bytecode must be the only form of return used in a single function, and all
1514 callers must use FCall with the matching number of returned values to invoke
1519 Throw. Throws the object $1. If $1 is not an object that extends the
1520 Exception class, this instruction throws a fatal error.
1526 CGetL <local variable id> [] -> [C]
1528 Get local as cell. If the local variable given by %1 is defined, this
1529 instruction gets the value of the local variable and pushes it onto the stack
1530 as a cell. If the local variable is not defined, this instruction raises a
1531 warning and pushes null onto the stack.
1533 CGetQuietL <local variable id> [] -> [C]
1535 Get local as cell. If the local variable given by %1 is defined, this
1536 instruction gets the value of the local variable and pushes it onto the stack
1537 as a cell. If the local variable is not defined, this instruction pushes null
1540 CGetL2 <local variable id> [<F>:<T>] -> [C <F>:<T>]
1542 Get local as cell. If the local variable given by %1 is defined, this
1543 instruction gets the value of the local variable, pushes it onto the stack as
1544 a cell, and then pushes $1 onto the stack.
1546 If the local variable is not defined, this instruction raises a warning,
1547 pushes null onto the stack, and then pushes $1 onto the stack.
1549 CUGetL <local variable id> [] -> [C|U]
1551 Get local as cell or uninit. If the local variable given by %1 is defined,
1552 this instruction gets the value of the local variable and pushes it onto the
1553 stack as a cell. If the local variable is not defined, this instruction pushes
1554 uninit onto the stack.
1556 PushL <local variable id> [] -> [C]
1558 Teleport local value to eval stack. The local variable given by %1 must be
1559 defined and must not contain a reference. This instruction pushes the local's
1560 value on the stack, then unsets it, equivalent to the behavior of UnsetL.
1564 Get global as cell. This instruction first computes x = (string)$1. Next,
1565 this instruction reads the global variable named x pushes its value onto the
1568 If there is not a global variable defined named x, this instruction pushes
1569 null onto the stack and raises a warning.
1571 CGetQuietG [C] -> [C]
1573 Get global as cell. This instruction first computes x = (string)$1. Next,
1574 this instruction reads the global variable named x pushes its value onto the
1577 If there is not a global variable defined named x, this instruction pushes
1578 null onto the stack.
1580 CGetS <class-ref slot> [C] -> [C]
1582 Get static property as cell. This instruction first checks if class %1 has a
1583 visible and accessible static property named (string)$1. If it doesn't, this
1584 instruction throws a fatal error. Otherwise, this instruction pushes the
1585 static property onto the stack as a cell.
1587 VGetL <local variable id> [] -> [V]
1589 Get local as ref. This instruction boxes the local variable given by %1 if
1590 necessary and pushes it onto the stack as a ref. If the given local variable
1591 is not defined, this instruction defines it, sets it to null, boxes it, and
1592 pushes a the value of the local variable onto the stack as a ref.
1594 VGetS <class-ref slot> [C] -> [V]
1596 Get static property as ref. This instruction first checks if class %1 has a
1597 visible and accessible static property named (string)$1. If it doesn't, this
1598 instruction throws a fatal error. Otherwise, this instruction boxes the
1599 static property and pushes it onto the stack as a ref.
1601 ClsRefGetC <class-ref slot> [C] -> []
1602 ClsRefGetTS <class-ref slot> [C] -> []
1604 Fetch class. This instruction first loads a value into x as shown by the
1608 ---------------+----
1610 ClsRefGetTS | $1['classname']
1612 If the flavor is TS, then this instruction checks whether $1 is a type
1613 structure. If not, it throws a fatal error. Loads the classname field onto
1614 x and checks to see whether the type structure contains generics. If it does,
1615 then mangles the name of those generics and performs the duties of the
1616 RecordReifiedGeneric instruction.
1618 Next this instruction checks if x is a string or an object. If x is not a
1619 string or object, this instruction throws a fatal error. Otherwise, this
1620 instruction executes y = (is_object(x) ? get_class(x) : (string)x) and checks
1621 if y matches the name of a defined class. If y does not match the name of a
1622 defined class, this instruction will invoke the autoload facility passing in
1623 the class name y, and then it will again check if y matches the name of a
1624 defined class. If y still does not match the name of a defined class this
1625 instruction throws a fatal error.
1627 Next, this instruction writes a classref that refers to the class named y to
1630 6. Isset, Empty, and type querying instructions
1631 -----------------------------------------------
1633 IssetC [C] -> [C:Bool]
1635 Isset. If $1 is null this instruction pushes false onto the stack, otherwise
1638 IssetL <local variable id> [] -> [C:Bool]
1640 Isset local. This instruction reads the local variable given by %1. If the
1641 local variable is undefined or null, this instruction pushes false onto the
1642 stack, otherwise it pushes true.
1644 IssetG [C] -> [C:Bool]
1646 Isset global. This instruction reads the global variable named (string)$1. If
1647 the global variable is undefined or null, this instruction pushes false onto
1648 the stack, otherwise it pushes true.
1650 IssetS <class-ref slot> [C] -> [C:Bool]
1652 Isset static property. This instruction first computes x = (string)$1. Next
1653 it checks if class %1 has an accessible static property named x. If it
1654 doesn't, this instruction pushes false.
1656 If class %1 does have an accessible property named x, this instruction reads
1657 the static property named x. If the static property is null, this instruction
1658 pushes false onto the stack, otherwise it pushes true.
1660 EmptyL <local variable id> [] -> [C:Bool]
1662 Empty local. This instruction reads the local variable named %1 into x. If
1663 the local variable is defined this instruction pushes !(x) onto the stack,
1664 otherwise it pushes true.
1666 EmptyG [C] -> [C:Bool]
1668 Empty global. This instruction reads the global variable named (string)$1
1669 into x. If the global variable is defined this instruction pushes !(x) onto
1670 the stack, otherwise it pushes true.
1672 EmptyS <class-ref slot> [C] -> [C:Bool]
1674 Empty static property. This instruction first checks if class %1 has an
1675 accessible static property named (string)$1. If it doesn't, this instruction
1676 pushes true, otherwise this instruction reads the static property into x and
1677 pushes !(x) onto the stack.
1679 IsTypeC <op> [C] -> [C:Bool]
1681 Is type. This instruction checks the type of a value on the stack, according
1682 to the following table:
1696 ArrLike | Arr or Vec or Dict or Keyset
1697 Scalar | Int or Dbl or Str or Bool
1700 If t is Obj, this instruction checks if the operand in an object.
1701 Instances of a special class __PHP_Incomplete_Class are not considered
1703 Otherwise, the result is true if $1 is of type t and false otherwise.
1704 The result is pushed on the stack.
1706 IsTypeL <local variable id> <op> [] -> [C:Bool]
1708 Is type. This instruction checks the type of a local, according to the
1723 ArrLike | Arr or Vec or Dict or Keyset
1724 Scalar | Int or Dbl or Str or Bool
1727 If the local variable given by %1 is defined, the logic is the same as for
1728 IsTypeC (see above).
1729 If the local is of kind reference, then the inner value is used to determine
1731 If the local variable given by %1 is not defined, this instruction raises a
1732 warning and pushes false onto the stack, unless if the operand is Null, in
1733 which case it pushes true.
1736 7. Mutator instructions
1737 -----------------------
1739 SetL <local variable id> [C] -> [C]
1741 Set local. This instruction marks the local variable given by %1 as defined,
1742 stores the value $1 into the local variable, and then pushes $1 onto the
1747 Set global. This instruction marks the global variable named (string)$2 as
1748 defined, assigns the value $1 to the global variable, and then pushes $1 onto
1751 SetS <class-ref slot> [C C] -> [C]
1753 Set static property. First this instruction checks if class %1 has an
1754 accessible static property named (string)$2. If it doesn't, this instruction
1755 throws a fatal error. Otherwise, this instruction assigns the value $1 to the
1756 static property, and then it pushes $1 onto the stack.
1758 SetOpL <local variable id> <op> [C] -> [C]
1760 Set op local. If the local variable given %1 is not defined, this instruction
1761 marks it as defined, sets it to null, and raises a warning.
1763 Next, this instruction reads the local variable into x, then executes y = x
1764 <op> $1, assigns y into local variable %1, and then pushes y onto the stack.
1765 The immediate value must be one of the following opcodes:
1766 Add, AddO, Sub, SubO, Mul, MulO, Div, Mod, Shl, Shr, Concat, BitAnd,
1769 SetOpG <op> [C C] -> [C]
1771 Set op global. This instruction first computes x = (string)$2. If the global
1772 variable named n is not defined, this instruction marks it as defined, sets
1773 it to null, and raises a warning.
1775 Next, this instruction reads the global variable named x into y, executes z =
1776 y <op> $1, assigns z into the global variable named x, and then pushes z onto
1777 the stack as a cell. The immediate value must be one of the following
1779 Add, Sub, Mul, Div, Mod, Shl, Shr, Concat, BitAnd, BitOr, BitXor.
1781 SetOpS <op> <class-ref slot> [C C] -> [C]
1783 Set op static property. This instruction first computes x = (string)$2. Next
1784 it checks if class %2 has an accessible static property named x. If it
1785 doesn't, this instruction throws a fatal error. Otherwise, this instruction
1786 reads the static property named x into y, executes z = y <op> $1, assigns z
1787 into the static property, and then pushes z onto the stack. The immediate
1788 value must be one of the following opcodes:
1789 Add, Sub, Mul, Div, Mod, Shl, Shr, Concat, BitAnd, BitOr, BitXor.
1791 IncDecL <local variable id> <op> [] -> [C]
1793 Increment/decrement local. If the local variable given by %1 is not defined,
1794 this instruction marks it as defined, sets it to null, and raises a warning.
1796 Where x is the local given by %1, this instruction then does the following:
1798 If op is PreInc, this instruction executes ++x and then pushes x onto the
1801 If op is PostInc, this instruction pushes x onto the stack and then it
1804 If op is PreDec, this instruction executes --x and then pushes x onto the
1807 If op is PostDec, this instruction pushes x onto the stack and then it
1810 IncDecG <op> [C] -> [C]
1812 Increment/decrement. This instruction first computes x = (string)$1. Next, if
1813 the global variable named x is not defined, this instruction first defines it,
1814 sets it to null, and raises a warning.
1816 Where v is the local variable or global variable named x, this instruction
1817 performs the following:
1819 If op is PreInc, this instruction executes ++v and then pushes v onto the
1822 If op is PostInc, this instruction pushes v onto the stack and then it
1825 If op is PreDec, this instruction executes --v and then pushes v onto the
1828 If op is PostDec, this instruction pushes v onto the stack and then it
1831 IncDecS <op> <class-ref slot> [C] -> [C]
1833 Increment/decrement static property. This instruction first computes x =
1834 (string)$1. Next it checks if class %1 has an accessible static property
1835 named x. If it doesn't, this instruction throws a fatal error.
1837 Where s is the static property named x, this instruction performs the
1840 If op is PreInc, this instruction increments the ++s and then pushes s onto
1843 If op is PostInc, this instruction pushes s onto the stack and then it
1846 If op is PreDec, this instruction executes --s and then pushes s onto the
1849 If op is PostDec, this instruction pushes s onto the stack and then it
1852 UnsetL <local variable id> [] -> []
1854 Unset local. Breaks any bindings the local variable given by %1 may have and
1855 marks the local variable as undefined.
1859 Unset global. This instruction breaks any bindings the global variable named
1860 (string)$1 may have and marks the global variable as undefined.
1862 CheckProp <propName> [] -> [C:Bool]
1864 Check non-scalar property initializer. This instruction checks the
1865 initializer for property named %1 in the context class, and pushes
1866 true on the stack if it is initialized, and false otherwise.
1868 InitProp <propName> <op> [C] -> []
1870 Initialize non-scalar property. If %2 is 'NonStatic', this instruction sets
1871 the initializer for the property named %1 in the context class to $1. If %2
1872 is 'Static', this instruction sets the initializer for the static property
1873 named %1 in the context class to $1.
1875 The CheckProp and InitProp opcodes should only be used in 86pinit methods.
1876 86pinit methods are HHVM-internal property initialization methods that
1877 cannot be called from user-land. After 86pinit runs, no declared properties
1878 of the class can be of type NullUninit.
1880 8. Call instructions
1881 --------------------
1883 NewObj <class-ref slot> <has-generics-op> [] -> [C:Obj]
1884 NewObjD <litstr id> [] -> [C:Obj]
1885 NewObjS <mode> [] -> [C:Obj]
1887 New object. First, these instructions load a value into x as given
1888 by the following table:
1896 When loading %1 into x, NewObjD will perform the work performed by the
1897 ClsRefGetC instruction to convert the name given by %1 into a classref.
1898 NewObjS will perform the same work as LateBoundCls/Self/Parent depending on
1901 This instruction pushes a default-initialized object onto the stack. The
1902 initialization will complete by running a constructor with FPushCtor/FCall.
1904 If HasGenerics is passed to NewObj, this indicates that the data at cls-ref
1905 slot's reified generics portion is valid.
1906 If MaybeGenerics is passed to NewObj, this indicates that data at cls-ref
1907 slot's reified generics portion will be nulled out when there are no reified
1913 FPushFunc <num params> [U U U C|V..C|V C] -> [C|V..C|V]
1914 FPushFuncD <num params> <litstr id> [U U U C|V..C|V] -> [C|V..C|V]
1916 FPI push function. First, these instructions load a value into x as given by
1917 the following table:
1924 If x is a string, this instruction attempts to lookup a function named x. If
1925 no function named x is defined, this instruction throws a fatal error.
1926 Otherwise this instruction pushes a new entry on the FPI stack, initializing
1927 it with the number of parameters being passed (given by %1) and a reference
1928 to the FPI structure for the function named x. With FPushFuncD the litstr in
1929 %2 must not start with a '\' character, or be of the form "Class::Method".
1930 Function names should be normalized with respect to namespace and never start
1933 If x is an object, this instruction checks if the object has an __invoke
1934 method. If the object does not have an __invoke method, this instruction
1935 throws a fatal error. Otherwise this instruction pushes a new entry on the
1936 FPI stack, initializing it with the number of parameters being passed (given
1937 by %1) and a reference to the FPI structure for the __invoke method from
1940 if x is an array, this instruction will check that the first array element is
1941 either the name of a class, or an instance of one, and that the second array
1942 element is the name of a method. If no such class exists, or no such method
1943 on that class exists, then this instruction throws a fatal error. Otherwise
1944 this instruction does the same FPI manipulation mentioned above.
1946 If x is a func, this instruction will push a new entry on the FPI stack using
1947 the function pointer contained in x.
1949 If x is not a string, object, array, or func, this instruction throws a fatal
1952 FPushFuncU <num params> <litstr id> <litstr fallback>
1953 [U U U C|V..C|V] -> [C|V..C|V]
1955 FPI push function unqualified. Identical to FPushFuncD except first tries to
1956 lookup the function named %2 and if it isn't defined calls the function named
1957 %3. As for FPushFuncD the litstr in %2 and %3 must not start with a '\'
1960 FPushObjMethod <num params> <nullsafe>
1961 [C U U C|V..C|V C] -> [C|V..C|V]
1962 FPushObjMethodD <num params> <litstr id> <nullsafe>
1963 [C U U C|V..C|V] -> [C|V..C|V]
1965 FPI push object-based method. First, these instructions load values into x
1966 and y as given by the following table:
1969 -------------------+-------------------+-----
1970 FPushObjMethod | $(num params + 4) | $1
1971 FPushObjMethodD | $(num params + 3) | %2
1973 If x is not an object and nullsafe != ObjMethodOp::NullThrows, or if y is not
1974 a string, this instruction throws a fatal error. Next, this instruction
1975 checks if object x has an accessible method named y. If it does, this
1976 instruction pushes a new entry on the FPI stack, initializing it with the
1977 number of parameters being passed (given by %1) and a reference to the FPI
1978 structure for the method named y from object x.
1980 If object x does not have an accessible method named y, this instruction
1981 checks if object x has a __call method. If a __call method is found, this
1982 instruction pushes a new entry on the FPI stack, initializing it with the
1983 number of parameters being passed (given by %1) and a reference to the FPI
1984 structure for the __call from object x, and stores the original name y in the
1987 If object x does not have an accessible method named y and it does not have a
1988 __call method, this instruction throws a fatal error.
1990 FPushClsMethod <num params> <class-ref slot>
1991 [U U U C|V..C|V C] -> [C|V..C|V]
1992 FPushClsMethodD <num params> <litstr id> <litstr id>
1993 [U U U C|V..C|V] -> [C|V..C|V]
1994 FPushClsMethodS <num params> <mode>
1995 [U U U C|V..C|V C] -> [C|V..C|V]
1996 FPushClsMethodSD <num params> <mode> <litstr id>
1997 [U U U C|V..C|V] -> [C|V..C|V]
1999 FPI push class-based method. First, these instructions load values into x and
2000 y as given by the following table:
2003 -------------------+----+-----
2004 FPushClsMethod | %2 | $1
2005 FPushClsMethodD | %3 | %2
2006 FPushClsMethodS | %2 | $1
2007 FPushClsMethodSD | %2 | %3
2009 When loading %3 into x, FPushClsMethodD will perform the work performed by
2010 the ClsRefGetC instruction to convert the name given by %3 into a classref.
2012 When loading %2 into x, FPushClsMethodS and FPushClsMethodSD will perform the
2013 work performed by LateBoundCls/Self/Parent depending on the specified mode.
2015 If y is not a string, this instruction throws a fatal error. Next, this
2016 instruction checks if class x has an accessible method named y. If it does,
2017 this instruction pushes a new entry on the FPI stack, initializing it with
2018 the number of parameters being passed (given by %1) and a reference to the
2019 FPI structure for the method named y from class x.
2021 If class x does not have an accessible method named y, this instruction
2022 checks if the current function's $this is non-null, if the class of $this is
2023 the same or derived from class x, and if $this has a __call method. If no
2024 suitable __call method is found, this instruction will check if class x has a
2025 __callStatic method. If a suitable __call method or a __callStatic method is
2026 found, this instruction pushes a new entry on the FPI stack, initializing it
2027 with the number of parameters being passed (given by %1) and a reference to
2028 the FPI structure for the __call or __callStatic method that was found, and
2029 stores the original name y in the FPI stack entry.
2031 If class x does not have an accessible method named y, and if a suitable
2032 __call method or a __callStatic method could not be found, this instruction
2033 throws a fatal error.
2035 FPushCtor <num params> [C:Obj U U C|V..C|V] -> [C|V..C|V]
2037 FPI push constructor.
2039 This instruction pushes a new entry on the FPI stack, initializing it with
2040 the number of parameters being passed (given by %1) and a reference to the
2041 FPI structure for the constructor for class of the object given by
2047 FCall* opcodes are responsible for invoking the callee determined by the
2048 specific opcode and performing operations related to the function call as
2049 specified by the FCA (FCall arguments) immediate consisting of the following
2052 <flags> <num args> <num returns> <reffiness bool vector> <async eager offset>
2053 [C|V..C|V] -> [C..C]
2055 FCall* first looks up the callee function according to the specific opcode.
2057 The vector %4 must be either empty or it must contain exactly %2 booleans.
2058 If it is non-empty, FCall* checks whether reffiness of parameters 0..(%2-1)
2059 of the callee matches the corresponding reffiness values specified by the
2060 vector %4. Throws an exception if there is a mismatch.
2062 Finally, FCall* transfers the top %2 values from the stack to the callee as
2063 parameters and invokes the callee. When the callee returns, it will transfer
2064 %3 return values onto the caller's evaluation stack using the C flavor. The
2065 callee must return the matching number of values using either RetC opcode
2066 (if %3 was one) or RetM opcode (otherwise).
2068 If the optional offset %5 was specified, the callee supports async eager
2069 return and it would return a finished Awaitable, it may instead return the
2070 unpacked result of the Awaitable and continue execution of the caller at
2073 If %5 was specified and the callee raised an exception, the exception will
2074 continue to propagate thru the caller instead of being wrapped into Awaitable.
2075 Note that for the purposes of exception handling inside the caller, the PC
2076 will point after the FCall rather than %5 so it is not advised to have
2077 different EH entries for these two locations.
2079 Async eager offset feature is used to avoid the cost of construction of short
2080 lived Awaitables that are produced by eagerly finishing asynchronous code and
2081 then immediately awaited by the caller.
2083 The %1 contains a list of boolean flags:
2085 Unpack: if enabled, the elements of the last value on the stack, which must be
2086 an array, are transferred to the callee as parameters, following the regular
2089 SupportsAER: hint from static analysis indicating whether the callee is known
2090 to support async eager return. Requires specified async eager offset in %5.
2092 FCall <fca> <class name> <func name> [C|V..C|V] -> [C..C]
2094 FPI call. This instruction pops the current FPI off the FPI stack and calls
2095 the function associated with it. The strings in %2 and %3 provide hints from
2096 static analysis to assist the region selector in determining the callee:
2099 ----------+-----------+--------------
2100 empty | empty | unknown
2101 empty | non-empty | function %3
2102 non-empty | non-empty | method %2::%3
2104 FCallBuiltin <total params> <passed params> <litstr id> [C|V|U..C|V|U] -> [C]
2106 Optimized builtin call without an ActRec. This instruction attempts to lookup
2107 a builtin function named %3. If no function named %3 is defined, this
2108 instruction throws a fatal error. Otherwise, this function gets address of
2109 the builtin function named %3, transfers the top %1 values from the stack to
2110 the callee as parameters, and then invokes the dispatcher to call the callee.
2111 %2 denotes the number of non-default parameters pushed onto stack by user
2112 level code. When the callee returns, it will transfer the return value onto
2113 the caller's evaluation stack using the C flavor.
2116 9. Member operations
2117 --------------------
2119 Member operations represent one part of a member expression such as
2120 "$a[0]['name'] = $foo". Each operation corresponds to one bytecode instruction,
2121 but the operations are described separately from their instruction mapping to
2122 separate them from any concerns about instruction encoding.
2124 Operations can produce and consume intermediate values called "bases". A "base"
2125 is a pointer to a memory location that is occupied by a cell or a ref, typically
2126 a local variable, array element, or object property. The current base is stored
2127 in a VM register called the member base register, or MBR for short. Bases are
2128 never stored on the evaluation stack or in any VM location other than the MBR.
2130 A base never owns a reference to the value it points to. It may point to a
2131 temporary value in a scratch register, but the lifetime of the value is always
2134 There are three categories of member operations: base, intermediate, and
2135 final. Base operations produce a base, intermediate operations consume the
2136 current base and produce a new base, and final operations consume the current
2137 base without producing a new one.
2139 Operations are specified as if they directly operate on the top of the
2140 evaluation stack in the name of consistency and clarity, but in fact their
2141 inputs and outputs may reside elsewhere. The symbol 'B' is used in the input
2142 descriptions and output descriptions of operations to indicate that a given
2143 operation consumes a base as input or produces a base as output.
2145 9.1 Member base operations
2146 --------------------------
2150 Get base from value. This operation outputs a base that points to the value
2153 BaseL <local variable id> [] -> [B]
2155 Get base from local. This operation outputs a base that points to the local
2156 given by %1. If the local is not defined, this operation outputs a base that
2159 BaseLW <local variable id> [] -> [B]
2161 Get base from local. This operation outputs a base that points to the local
2162 given by %1. If the local is not defined, this operation raises a warning and
2163 outputs a base that points to null.
2165 BaseLD <local variable id> [] -> [B]
2167 Get base from local. This operation outputs a base that points to the local
2168 given by %1, whether or not it is defined.
2171 BaseGL <local variable id> [] -> [B]
2173 Get base from global name. This operation outputs a base that points to the
2174 global variable whose name is given by (string)%1 or (string)$1. If the
2175 global is not defined, this operation produces a base that points to null.
2178 BaseGLW <local variable id> [] -> [B]
2180 Get base from global name. This operation outputs a base that points to the
2181 global variable whose name is given by (string)%1 or (string)$1. If the
2182 global is not defined, this operation raises a warning and outputs a base
2183 that points to null.
2186 BaseGLD <local variable id> [] -> [B]
2188 Get base from global name. This operation outputs a base that points to the
2189 global variable whose name is given by (string)%1 or (string)$1, defining it
2192 BaseSC <class-ref slot> [C] -> [B]
2194 Get base from static property. First, this operation computes x = (string)$1.
2195 Then this instruction checks if class in %1 has an accessible property named
2196 x. If it does, this operation outputs a base that points to the static
2197 property. Otherwise, this operation throws a fatal error.
2201 Get base from $this. This operation assumes that the current frame contains a
2202 valid $this pointer and outputs a base pointing to the object in $this.
2204 9.2 Intermediate member operations
2205 ----------------------------------
2208 ElemL <local variable id> [B] -> [B]
2210 Fetch element if it exists. First, these operations load a value into x and a
2211 base into y, as given by the following table:
2214 ----------+----+-----
2218 Then, if y is an array, this operation outputs a base that points to the
2219 element at index x from array y. If there is no element at index x, this
2220 operation outputs a base that points to null.
2222 If y is an object that implements the ArrayAccess interface, this operation
2223 outputs a base that points to the result of y->offsetGet(x).
2225 If y is an object that does not implement the ArrayAccess interface, this
2226 operation throws a fatal error.
2228 If y is a string, this operation computes z = (int)x. If z >= 0 and z <
2229 strlen(z), this operation builds a new string consisting of the character at
2230 offset z from y and outputs a base that contains the new string. Otherwise,
2231 this operation outputs a base that points to the empty string.
2233 If y is not a string, array, or object, this operation will output a base
2237 ElemLW <local variable id> [B] -> [B]
2239 Fetch element; warn if it doesn't exist.
2241 First, these operations load a value into x and a base into y, as given by
2242 the following table:
2245 ----------+----+-----
2249 If y is an array, this operation outputs a base that points to the element at
2250 index x from array y. If there is no element at index x, this operation
2251 outputs a base that points to null and raises a warning.
2253 If y is an object that implements the ArrayAccess interface, this operation
2254 outputs a base that points to the result of y->offsetGet(x).
2256 If y is an object that does not implement the ArrayAccess interface, this
2257 operation throws a fatal error.
2259 If y is a string, this operation continues to compute z = (int)x. If z >= 0
2260 and z < strlen(z), this operation builds a new string consisting of the
2261 character at offset z from y and outputs a base that points to the new string.
2262 Otherwise, this operation raises a warning and outputs a base that points to
2265 If y is not a string, array, or object, this operation will output a base
2269 ElemLD <local variable id> [B] -> [B]
2271 Fetch element; define it if it doesn't exist.
2273 First, these operations load a value into x and a base into y, as given by
2274 the following table:
2277 ----------+----+-----
2281 If y is an array, this operation outputs a base that references the element
2282 at index x. If there is no element at index x, this operation creates an
2283 element at index x, and outputs a base that references the element.
2285 If y is an object that implements the ArrayAccess interface, this operation
2286 outputs a base that contains the result of y->offsetGet(x).
2288 If y is non-empty string or an object that does not implement the ArrayAccess
2289 interface, this operation throws a fatal error.
2291 If y is null, the empty string, or false, this operation will set y to a new
2292 empty array, create an element at index x, and output a base that points to
2295 If y is true, integer, double, this operation raises a warning and outputs a
2296 base that points to null.
2299 ElemLU <local variable id> [B] -> [B]
2301 Fetch element for unset.
2303 First, these operations load a value into x and a base into y, as given by
2304 the following table:
2307 ----------+----+-----
2311 If y is an array, this operation outputs a base that points to the element
2312 at index x from array y. If there is no element at index x, this operation
2313 outputs a base that points to null.
2315 If y is an object that implements the ArrayAccess interface, this operation
2316 outputs a base that points to the result of y->offsetGet(x).
2318 If y is an object that does not implement the ArrayAccess interface, this
2319 operation throws a fatal error.
2321 If y is a string, this operation throws a fatal error.
2323 If y is not a string, array, or object, this operation will output a base
2328 Fetch new element. If $1 is an array, this operation creates a new element
2329 with the next available numeric key in array $1 and outputs a base that
2330 points to the new element.
2332 If $1 is an object that implements the ArrayAccess interface, this operation
2333 outputs a base that points to the result of $1->offsetGet(null).
2335 If $1 is a non-empty string or an object that does not implement the
2336 ArrayAccess interface, this operation throws a fatal error.
2338 If $1 is null, false, or the empty string, this operation sets $1 to a new
2339 empty array, creates a new element with the next available numeric key in
2340 array $1, and then outputs a base that points to the new element.
2342 If $1 is true, integer, or double, this operation raises a warning and
2343 outputs a base that points to null.
2346 PropL <local variable id> [B] -> [B]
2348 Fetch property if it exists.
2350 First, these operations load a value into x and a base into y, as given by
2351 the following table:
2354 ----------+----+-----
2358 Next, produce a base pointing to:
2363 y has eligible __get method
2364 y->x has been unset previously
2365 ------+---------------------------------------------------------------------
2369 1100X | throw fatal error
2376 PropLW <local variable id> [B] -> [B]
2378 Fetch property; warn if it doesn't exist.
2380 First, these operations load a value into x and a base into y, as given by
2381 the following table:
2384 ----------+----+-----
2388 Next, produce a base pointing to:
2393 y has eligible __get method
2394 y->x has been unset previously
2395 ------+---------------------------------------------------------------------
2396 0XXXX | raise warning; null
2397 10X0X | raise warning; null
2399 1100X | throw fatal error
2402 11101 | raise warning; null
2406 PropLD <local variable id> [B] -> [B]
2408 Fetch property; define it if it doesn't exist.
2410 First, these operations load a value into x and a base into y, as given by
2411 the following table:
2414 ----------+----+-----
2418 Next, produce a base pointing to:
2424 y has eligible __get method
2425 y->x has been unset previously
2426 -------+--------------------------------------------------------------------
2428 01XXXX | y = new stdclass; create property y->x; y->x
2429 1X0X0X | create property y->x; y->x
2430 1X0X1X | y->__get(x)
2431 1X100X | throw fatal error
2432 1X101X | y->__get(x)
2434 1X1101 | re-create property y->x, y->x
2435 1X1111 | y->__get(x)
2438 PropLU <local variabld id> [B] -> [B]
2440 Fetch property for unset.
2442 First, these operations load a value into x and a base into y, as given by
2443 the following table:
2446 ----------+----+-----
2450 Next, produce a base pointing to:
2455 y->x has been unset previously
2456 -----+----------------------------------------------------------------------
2458 10XX | create property y->x; y->x
2459 110X | throw fatal error
2461 1111 | re-create property y->x; y->x
2463 9.3 Final member operations
2464 ---------------------------
2466 CGetElemC [C B] -> [C]
2467 CGetElemL <local variable id> [B] -> [C]
2469 Get element as cell.
2471 These instructions first load a value into x and a base into y, as given by
2472 the following table:
2475 ------------+----+-----
2479 If y is an array, this operation retrieves the element at index x from array
2480 y and pushes it onto the stack as a cell. If there is no element at index x,
2481 this operation raises a warning and pushes null onto the stack.
2483 If y is an object that implements the ArrayAccess interface, this operation
2484 pushes x->offsetGet($2) onto the stack.
2486 If y is an object that does not implement the ArrayAccess interface, this
2487 operation throws a fatal error.
2489 If y is a string, this operation continues to compute z = (int)x. If z >= 0
2490 and z < strlen(z), this operation builds a new string consisting of the
2491 character at offset z from y and pushes it onto the stack. Otherwise, this
2492 operation raises a warning and pushes the empty string onto the stack.
2494 If y is not a string, array, or object, this operation will push null onto
2497 VGetElemC [C B] -> [V]
2498 VGetElemL <local variable id> [B] -> [V]
2502 These instructions first load a value into x and a base into y, as given by
2503 the following table:
2506 ------------+----+-----
2510 If y is an array, this operation retrieves the element at index x from array
2511 y and pushes it onto the stack as a ref. If there is no element at index x,
2512 this operation creates a new element at index x, and pushes it onto the stack
2515 If y is an object that implements the ArrayAccess interface, this operation
2516 pushes y->offsetGet(x) onto the stack as a ref.
2518 If y is a non-empty string or an object that does not implement the
2519 ArrayAccess interface, this operation throws a fatal error.
2521 If y is null, false, or the empty string, this operation sets y to a new
2522 empty array. Then this operation retrieves the element at index x from array
2523 y and pushes it onto the stack as a ref. If there is no element at index x,
2524 this operation creates a new element at index x, and pushes it onto the stack
2527 If y is true, integer, or double, this operation raises a warning and pushes
2528 null onto the stack.
2530 IssetElemC [C B] -> [C:Bool]
2531 IssetElemL <local variable id> [B] -> [C:Bool]
2535 These instructions first load a value into x and a base into y, as given by
2536 the following table:
2539 ------------+----+-----
2540 IssetElemC | $2 | $1
2541 IssetElemL | %1 | $1
2543 If y is an array, this operation pushes !is_null(y[x]) onto the stack.
2545 If y is an object that implements the ArrayAccess interface, this operation
2546 pushes y->offsetExists(x) onto the stack.
2548 If y is an object that does not implement the ArrayAccess interface, this
2549 operation throws a fatal error.
2551 If y is a string, this operation computes z = (int)x and then it pushes (z >=
2552 0 && z < strlen(y)) onto the stack.
2554 If y is a not a string, array, or object, this operation pushes false onto
2557 EmptyElemC [C B] -> [C]
2558 EmptyElemL <local variable id> [B] -> [C]
2562 These instructions first load a value into x and a base into y, as given by
2563 the following table:
2566 ------------+----+-----
2567 EmptyElemC | $2 | $1
2568 EmptyElemL | %1 | $1
2570 If y is an array, this operation pushes !(y[x]) onto the stack.
2572 If y is an object that implements the ArrayAccess interface, this operation
2573 first calls y->offsetExists(x); if that returns false this operation pushes
2574 true onto the stack, otherwise it pushes !(y->offsetGet(x)) onto the stack.
2576 If y is an object that does not implement the ArrayAccess interface, this
2577 operation throws a fatal error.
2579 If y is a string, this operation computes z = (int)x, then pushes true if (z
2580 < 0 || z >= strlen(y)), !(y[z]) otherwise.
2582 If y is, not an array, object, or string, this operation pushes true onto the
2585 SetElemC [C C B] -> [C]
2587 Set element. If $1 is an array, this operation executes $1[$3] = $2 and then
2588 pushes $2 onto the stack.
2590 If $1 is an object that implements the ArrayAccess interface, this operation
2591 executes $1->offsetSet($3, $2) and then pushes $2 onto the stack.
2593 If $1 is an object that does not implement the ArrayAccess interface, this
2594 operation throws a fatal error.
2596 If $1 is null, the empty string, or false, this operation sets $1 to a new
2597 empty array, executes $1[$3] = $2, and then pushes $2 onto the stack.
2599 If $1 is a non-empty string, this operation first computes x = (int)$3. If x
2600 is negative, this operation raises a warning and does nothing else. If x is
2601 non-negative, this operation appends spaces to the end of $1 as needed to
2602 ensure that x is in bounds, then it computes y = substr((string)$2,0,1), and
2603 then it sets the character at index x in $1 equal to y (if y is not empty) or
2604 it sets the character at index x in $1 to "\0" (if y is empty). Then this
2605 operation pushes y on to the stack.
2607 If $1 is true, integer, or double, this operation raises a warning and pushes
2608 null onto the stack as a cell.
2610 SetElemL <local variable id> [C B] -> [C]
2612 Set element. If $1 is an array, this operation executes $1[%1] = $2 and then
2613 pushes $2 onto the stack.
2615 If $1 is an object that implements the ArrayAccess interface, this operation
2616 executes $1->offsetSet(%1, $2) and then pushes $2 onto the stack.
2618 If $1 is an object that does not implement the ArrayAccess interface, this
2619 operation throws a fatal error.
2621 If $1 is null, the empty string, or false, this operation sets $1 to a new
2622 empty array, executes $1[%1] = $2, and then pushes $2 onto the stack.
2624 If $1 is a non-empty string, this operation first computes x = (int)%1. If x
2625 is negative, this operation raises a warning and does nothing else. If x is
2626 non-negative, this operation appends spaces to the end of $1 as needed to
2627 ensure that x is in bounds, then it computes y = substr((string)$2,0,1), and
2628 then it sets the character at index x in $1 equal to y (if y is not empty) or
2629 it sets the character at index x in $1 to "\0" (if y is empty). Then this
2630 operation pushes y on to the stack.
2632 If $1 is true, integer, or double, this operation raises a warning and pushes
2633 null onto the stack as a cell.
2635 SetOpElemC <op> [C C B] -> [C]
2637 Set element op. If $1 is an array, this operation first checks $1 contains an
2638 element at offset $2. If it does not, this operation creates an element at
2639 offset $2, sets it to null, and raises a warning. Next, this operation
2640 executes x = $1[$3], y = x <op> $2, and $1[$3] = y, and then it pushes y onto
2641 the stack as a cell.
2643 If $1 is null, false, or the empty string, this operation first sets $1 to a
2644 new empty array. Then it follows the rules described in the case above.
2646 If $1 is an object that implements the ArrayAccess interface, this operation
2647 executes x = $1->offsetGet($3), y = x <op> $2, and $1->offsetSet($3, y), and
2648 then it pushes y onto the stack as a cell.
2650 If $1 is a non-empty string or an object that does not implement the
2651 ArrayAccess interface, this operation throws a fatal error.
2653 If $1 is true, integer, or double, this operation raises a warning and pushes
2654 null onto the stack.
2656 SetOpElemL <op> <local variable id> [C B] -> [C]
2658 Set element op. If $1 is an array, this operation first checks $1 contains an
2659 element at offset $2. If it does not, this operation creates an element at
2660 offset $2, sets it to null, and raises a warning. Next, this operation
2661 executes x = $1[%1], y = x <op> $2, and $1[%1] = y, and then it pushes y onto
2662 the stack as a cell.
2664 If $1 is null, false, or the empty string, this operation first sets $1 to a
2665 new empty array. Then it follows the rules described in the case above.
2667 If $1 is an object that implements the ArrayAccess interface, this operation
2668 executes x = $1->offsetGet(%1), y = x <op> $2, and $1->offsetSet(%1, y), and
2669 then it pushes y onto the stack as a cell.
2671 If $1 is a non-empty string or an object that does not implement the
2672 ArrayAccess interface, this operation throws a fatal error.
2674 If $1 is true, integer, or double, this operation raises a warning and pushes
2675 null onto the stack.
2677 IncDecElemC <op> [C B] -> [C]
2679 Increment/decrement element. If $1 is an array, this operation checks if $1
2680 contains an element at offset $2. If it does not, this operation creates an
2681 element at offset $2, sets it to null, and raises a warning. Next, this
2682 operation executes x = $1[$2], y = x, and either ++y (if op is PreInc or
2683 PostInc) or --y (if op is PreDec or PostDec). Then it assigns y to $1[$2] and
2684 pushes either y (if op is PreInc or PreDec) or x (if op is PostInc or
2685 PostDec) onto the stack.
2687 If $1 is null, false, or the empty string, this operation first sets $1 to an
2688 empty array. Then it follows the rules described in the case above.
2690 If $1 is a non-empty string or an object that does not implement the
2691 ArrayAccess interface, this operation throws a fatal error.
2693 If $1 is an object that implements ArrayAccess, this operation executes x =
2694 $1->offsetGet($2), y = x, and either ++y (if op is PreInc or PostInc) or --y
2695 (if op is PreDec or PostDec). Then it pushes either y (if op is PreInc or
2696 PreDec) or x (if op is PostInc or PostDec) onto the stack.
2698 If $1 is true, integer, or double, this operation raises a warning and pushes
2699 null onto the stack.
2701 IncDecElemL <op> <local variable id> [B] -> [C]
2703 Increment/decrement element. If $1 is an array, this operation checks if $1
2704 contains an element at offset %1. If it does not, this operation creates an
2705 element at offset %1, sets it to null, and raises a warning. Next, this
2706 operation executes x = $1[%1], y = x, and either ++y (if op is PreInc or
2707 PostInc) or --y (if op is PreDec or PostDec). Then it assigns y to $1[%1] and
2708 pushes either y (if op is PreInc or PreDec) or x (if op is PostInc or
2709 PostDec) onto the stack.
2711 If $1 is null, false, or the empty string, this operation first sets $1 to an
2712 empty array. Then it follows the rules described in the case above.
2714 If $1 is a non-empty string or an object that does not implement the
2715 ArrayAccess interface, this operation throws a fatal error.
2717 If $1 is an object that implements ArrayAccess, this operation executes x =
2718 $1->offsetGet(%1), y = x, and either ++y (if op is PreInc or PostInc) or --y
2719 (if op is PreDec or PostDec). Then it pushes either y (if op is PreInc or
2720 PreDec) or x (if op is PostInc or PostDec) onto the stack.
2722 If $1 is true, integer, or double, this operation raises a warning and pushes
2723 null onto the stack.
2725 UnsetElemC [C B] -> []
2726 UnsetElemL <local variable id> [B] -> []
2730 These instructions first load a value into x and a base into y, as given by
2731 the following table:
2734 ------------+----+-----
2735 UnsetElemL | %1 | $1
2736 UnsetElemC | $2 | $1
2738 If y is an array, this operation removes the element at index x from array y.
2740 If y is an object that implements ArrayAccess interface, this operation
2741 executes y->offsetUnset(x).
2743 If y is an object that does not implement the ArrayAccess interface, this
2744 operation throws a fatal error.
2746 If y is a string, this operation throws a fatal error.
2748 If y is not a string, array, or object, this operation does nothing.
2750 VGetNewElem [B] -> [V]
2752 Get new element as ref.
2754 If $1 is an array, this operation creates a new element with the next
2755 available numeric key in array $1 and pushes it onto the stack as a ref.
2757 If $1 is an object that implements the ArrayAccess interface, this operation
2758 pushes $1->offsetGet($2) onto the stack as a ref.
2760 If $1 is a non-empty string or an object that does not implement the
2761 ArrayAccess interface, this operation throws a fatal error.
2763 If $1 is null, false, or the empty string, this operation first sets $1 to a
2764 new empty array. Then it creates a new element with the next available
2765 numeric key in array $1 and pushes it onto the stack as a ref.
2767 If $1 is true, integer, or double, this operation raises a warning and pushes
2768 null onto the stack.
2770 SetNewElem [C B] -> [C]
2772 Set new element. If $1 is an array, this operation executes $1[] = $2 and
2773 then pushes $2 onto the stack.
2775 If $1 is null, false, or the empty string, this operation sets $1 to a new
2776 empty array, and then it executes $1[] = $2 and pushes $2 onto the stack.
2778 If $1 is a non-empty string or an object that does not implement the
2779 ArrayAccess interface, this operation throws a fatal error.
2781 If $1 is an object that implements the ArrayAccess interface, this operation
2782 executes $1->offsetSet(null, $2) and then pushes $2 onto the stack.
2784 If $1 is true, integer, or double, this operation raises a warning and pushes
2785 null onto the stack.
2787 SetOpNewElem <op> [C B] -> [C]
2789 Set op new element. If $1 is an array, this operation first determines the
2790 next available integer offset k in array $1. Next, this operation executes
2791 $1[k] = null, x = $1[k], and y = x <op> $2. Then it assigns y to $1[k] and
2792 pushes y onto the stack.
2794 If $1 is null, false, or the empty string, this operation first sets $1 to an
2795 empty array. Then it follows the rules described in the case above.
2797 If $1 is a non-empty string or an object that does not implement the
2798 ArrayAccess interface, this operation throws a fatal error.
2800 If $1 is an object that implements ArrayAccess, this operation executes x =
2801 $1->offsetGet(null), y = x <op> $2, and $1->offsetSet(null, y). Then it
2802 pushes y onto the stack.
2804 If $1 is true, integer, or double, this operation raises a warning and pushes
2805 null onto the stack.
2807 IncDecNewElem <op> [B] -> [C]
2809 Increment/decrement new element. If $1 is an array, this operation first
2810 determines the next available integer offset k in array $1. Next, this
2811 operation executes $1[k] = null, x = $1[k], y = x, and either ++y (if op is
2812 PreInc or PostInc) or --y (if op is PreDec or PostDec). Then it assigns y to
2813 $1[k] and pushes either y (if op is PreInc or PreDec) or x (if op is PostInc
2814 or PostDec) onto the stack.
2816 If $1 is null, false, or the empty string, this operation first sets $1 to an
2817 empty array. Then it follows the rules described in the case above.
2819 If $1 is a non-empty string or an object that does not implement the
2820 ArrayAccess interface, this operation throws a fatal error.
2822 If $1 is an object that implements ArrayAccess, this operation executes x =
2823 $1->offsetGet(null), y = x, and either ++y (if op is PreInc or PostInc) or
2824 --y (if op is PreDec or PostDec). Then it pushes either y (if op is PreInc or
2825 PreDec) or x (if op is PostInc or PostDec) onto the stack.
2827 If $1 is true, integer, or double, this operation raises a warning and pushes
2828 null onto the stack.
2830 CGetPropC [C B] -> [C]
2831 CGetPropL <local variable id> [B] -> [C]
2833 Get property as cell.
2835 These instructions first load a value into x and a base into y, as given by
2836 the following table:
2839 ------------+----+-----
2843 If y is an object that does not have an eligible __get method, this operation
2844 first checks if y has a visible property named x. If it does not, this
2845 operation raises a warning and pushes null. Otherwise, this operation
2846 continues to check if the property named x is accessible. If the property
2847 named x is accessible this operation pushes it onto the stack as a cell,
2848 otherwise this operation throws a fatal error.
2850 If y is an object that has an eligible __get method, this operation checks if
2851 y has a visible and accessible property named x. If it does, this operation
2852 pushes the property onto the stack. Otherwise, this operation pushes
2853 y->__get(x) onto the stack.
2855 If y is not an object, this operation will raise a warning and push null onto
2858 VGetPropC [C B] -> [V]
2859 VGetPropL <local variable id> [B] -> [V]
2861 Get property as ref.
2863 These instructions first load a value into x and a base into y, as given by
2864 the following table:
2867 ------------+----+-----
2871 If y is an object that does not have an eligible __get method, this operation
2872 first checks if y has a visible property named x. If it does not, this
2873 operation will create a new property named x and push it onto the stack as a
2874 ref. Otherwise this operation continues to check if the property named x is
2875 accessible. If it the property named x is accessible this operation pushes it
2876 onto the stack as a ref, otherwise this operation throws a fatal error.
2878 If y is an object has an eligible __get method, this operation checks if y
2879 has a visible and accessible property named x. If it does, this operation
2880 pushes the property onto the stack. Otherwise, this operation pushes
2881 y->__get(x) onto the stack.
2883 If y is null, false, or the empty string, this operation will set y to a new
2884 object of type stdclass, create a new property named x, and pushes it onto
2887 If y is true, integer, double, a non-empty string, or an array, this
2888 operation raises a warning and pushes null.
2890 IssetPropC [C B] -> [C:Bool]
2891 IssetPropL <local variable id> [B] -> [C:Bool]
2895 These instructions first load a value into x and a base into y, as given by
2896 the following table:
2899 -------------+----+-----
2900 IssetPropC | $2 | $1
2901 IssetPropL | %1 | $1
2903 If y is an object that does not have an eligible __isset method, this
2904 operation checks if y has a visible accessible property named x. If it does,
2905 this operation pushes !is_null(y->x) onto the stack. Otherwise this operation
2906 pushes false onto the stack.
2908 If y is an object that has an eligible __isset method, this operation checks
2909 if y has a visible and accessible property named x. If it does, this
2910 operation pushes !is_null(y->x) onto the stack. Otherwise this operation
2911 pushes y->__isset(x) onto the stack.
2913 If y is an array, this operation pushes !is_null(y[x]) onto the stack.
2915 If y is not an object or array, this operation pushes false.
2917 EmptyPropC [C B] -> [C:Bool]
2918 EmptyPropL <local variable id> [B] -> [C:Bool]
2922 These instructions first load a value into x and a base into y, as given by
2923 the following table:
2926 -------------+----+-----
2927 EmptyPropC | $2 | $1
2928 EmptyPropL | %1 | $1
2930 If y is an object that does not have an eligible __isset method, this
2931 operation first checks if y has a visible and accessible property named x.
2932 If it does, this operation pushes !(y->x) onto the stack. Otherwise this
2933 operation pushes true onto the stack.
2935 If y is an object that has an eligible __isset method but it does not have an
2936 eligible __get method, this operation checks if y has a visible and
2937 accessible property named x. If it does, this operation pushes !(y->x) onto
2938 the stack. Otherwise this operation pushes !(y->__isset(x)) onto the stack.
2940 If y is an object that has an eligible __isset method and an eligible __get
2941 method, this operation checks if y has a visible and accessible property
2942 named x. If it does, this operation pushes !(y->x) onto the stack. Otherwise
2943 this operation continues to execute x = y->__isset(x). If x is false this
2944 operation pushes true onto the stack, otherwise this operation pushes
2945 !(y->__get(x)) onto the stack.
2947 If y is an array, this operation pushes !(y[x]) onto the stack.
2949 If y is not an object or array, this operation pushes true.
2951 SetPropC [C C B] -> [C]
2952 SetPropL <local variable id> [C B] -> [C]
2954 Set property. Perform one of the following actions:
2956 First, these operations load values into k and x, and a base into y, as given
2957 by the following table:
2960 ----------+----+----+----
2961 SetPropC | $3 | $2 | $1
2962 SetPropL | %1 | $2 | $1
2964 Next, performs one of the following actions:
2970 y has eligible __set method
2971 y->k has been unset previously
2972 -------+--------------------------------------------------------------------
2973 00XXXX | raise warning; push null
2974 01XXXX | y = new stdclass; y->k = x; push x
2975 1X0X0X | create property y->k; y->k = x; push x
2976 1X0X1X | y->__set(k, x); push x
2977 1X100X | throw fatal error
2978 1X101X | y->__set(k, x); push x
2979 1X11X0 | y->k = x; push x
2980 1X1101 | re-create property y->k; y->k = x; push x
2981 1X1111 | y->__set(k, x); push x
2983 SetOpPropC <op> [C C B] -> [C]
2984 SetOpPropL <op> <local variable id> [C B] -> [C]
2988 First, these operations load values into k and x, and a base into y, as given
2989 by the following table:
2992 ------------+----+----+----
2993 SetOpPropC | $3 | $2 | $1
2994 SetOpPropL | %1 | $2 | $1
2996 Next, perform one of the following actions:
3002 y has eligible __get method
3003 y has eligible __set method
3004 y->k has been unset previously
3005 --------+-------------------------------------------------------------------
3006 00XXXXX | raise warning; push null
3007 01XXXXX | y = new stdclass; z = null <op> x; y->k = z; push z
3008 100X0XX | z = null <op> x; y->k = z; push z
3009 100X10X | w = y->__get(k); z = w <op> x; y->k = z; push z
3010 100X11X | w = y->__get(k); z = w <op> x; y->__set(k, z), push z
3011 10100XX | throw fatal error
3012 101010X | throw fatal error
3013 101011X | w = y->__get(k); z = w <op> x; y->__set(k, z), push z
3014 1011XX0 | w = y->k; z = w <op> x; y->k = z; push z
3015 10110X1 | z = null <op> x; re-create y->k; y->k = z; push z
3016 1011101 | w = y->__get(k); z = w <op> x; re-create y->k; y->k = z; push z
3017 1011111 | w = y->__get(k); z = w <op> x; y->__set(k, z); push z
3019 IncDecPropC <op> [C B] -> [C]
3020 IncDecPropL <op> <local variable id> [B] -> [C]
3022 Increment/decrement property.
3024 First, these operations load a value into x and a base into y, as given by
3025 the following table:
3028 -------------+----+----
3029 IncDecPropC | $2 | $1
3030 IncDecPropL | %1 | $1
3032 Next, perform one of the following actions:
3038 y has eligible __get method
3039 y has eligible __set method
3040 y->x has been unset previously
3041 --------+-------------------------------------------------------------------
3042 00XXXXX | raise warning; push null
3043 01XXXXX | y = new stdclass; b = null; a = b; <op>a; y->x = a;
3044 | push a (Pre*) or b (Post*)
3045 100X0XX | b = null; a = b; <op>a; y->x = a; push a (Pre*) or b (Post*)
3046 100X10X | b = y->__get(x); a = b; <op>a; y->x = a;
3047 | push a (Pre*) or b (Post*)
3048 100X11X | b = y->__get(x); a = b, <op>a; y->__set(x, a);
3049 | push a (Pre*) or b (Post*)
3050 10100XX | throw fatal error
3051 101010X | throw fatal error
3052 101011X | b = y->__get(x); a = b, <op>a; y->__set(x, a);
3053 | push a (Pre*) or b (Post*)
3054 1011XX0 | b = y->x; a = b; <op>a; y->x = a; push a (Pre*) or b (Post*)
3055 10110X1 | b = null; a = b; <op>a; re-create y->x; y->x = a;
3056 | push a (Pre*) or b (Post*)
3057 1011101 | b = y->__get(x); a = b; <op>a; re-create y->x; y->x = a;
3058 | push a (Pre*) or b (Post*)
3059 1011111 | b = y->__get(x); a = b; <op>a; y->__set(x, a);
3060 | push a (Pre*) or b (Post*)
3062 UnsetPropC [C B] -> []
3063 UnsetPropL <local variable id> [B] -> []
3067 These instructions first load a value into x and a base into y, as given by
3068 the following table:
3071 -------------+----+-----
3072 UnsetPropC | $2 | $1
3073 UnsetPropL | %1 | $1
3075 Next, performs one of the following actions:
3080 y has eligible __unset method
3081 -----+----------------------------------------------------------------------
3084 10X1 | y->__unset(x)
3085 1100 | throw fatal error
3086 1101 | y->__unset(x)
3090 10. Member instructions
3091 -----------------------
3093 Each instruction in this section corresponds to one member operation from the
3094 previous section. The same bytecode may represent multiple different member
3095 operations, differentiating between the options using MOpMode immediates.
3097 Since they represent member operations, these instructions produced and/or
3098 consume a base in the member base register. The MBR is live starting after a
3099 Base* bytecode, modified by zero or more Dim* bytecodes, then finally consumed
3100 by a final operation:
3102 bytecode | MBR in-state | MBR out-state
3103 ----------+--------------+--------------
3106 Final Ops | live | dead
3108 Finally, many of these instructions have a <member key> immediate. This is
3109 described in the "Instruction set" introduction section.
3111 10.1 Base Operations
3112 ---------------------
3114 BaseGC <stack index> <member op mode> [] -> []
3115 BaseGL <local id> <member op mode> [] -> []
3117 BaseG{C,L}{,W,D} member operation.
3119 BaseSC <stack index> <class-ref slot> <member op mode> [] -> []
3121 BaseSC member operation. %1 gives the location of the static property
3122 name, and %2 gives the class input. The class is consumed.
3124 BaseL <local id> <member op mode> [] -> []
3126 BaseL{,W,D} member operation.
3128 BaseC <stack index> <member op mode> [] -> []
3130 BaseC member operation.
3134 BaseH member operation.
3136 10.2 Intermediate operations
3137 -----------------------------
3139 Dim <member op mode> <member key> [] -> []
3141 {Prop,Elem}{L,C,I,T}{W,D,U} member operation.
3145 10.3 Final operations
3146 ----------------------
3148 All final operations take a <stack count> immediate, which indicates the number
3149 of elements on the eval stack that must be consumed before pushing the final
3150 result. These are elements read by Base*C instructions, and member keys.
3152 QueryM <stack count> <query op> <member key> [...] -> [C]
3154 {CGet,Isset,Empty}{Prop,Elem} member operation.
3156 VGetM <stack count> <member key> [...] -> [V]
3158 {VGet}{Prop,Elem} or VGetNewElem member operation.
3160 SetM <stack count> <member key> [... C] -> [C]
3162 Set{Prop,Elem} or SetNewElem member operation.
3164 SetRangeM <stack count> <op> <elem size> [... C C C] -> []
3166 Store raw data into a string, optionally reversing the order of elements
3167 based on op, which may be Forward or Reverse.
3169 The current member base must be a string (if this or any other required
3170 conditions are violated, an exception will be thrown). $3, and $1 are cast to
3171 Int before inspecting their values. $3 gives the offset within the base
3172 string to begin copying data into. The data comes from a source value in $2;
3173 supported types are described below. $1 is the count of items to copy from
3174 $2, and it maybe be -1 to request that an appropriate value is inferred from
3175 $2. The range [$3, count * size) must fit within [0, length of base).
3177 The following types are supported as data sources (the value in $2):
3179 - Bool: op must be Forward, count is ignored, and size must be 1. Stored as a
3180 1-byte value, either 0 or 1.
3182 - Int: op must be Forward, count is ignored, and size must be 1, 2, 4, or
3183 8. The value is truncated to the requested size and stored using the
3184 current machine's byte ordering.
3186 - Dbl: op must be Forward, count is ignored, and size must be 4 or 8. The
3187 value is converted to the requested size and stored using the current
3188 machine's byte ordering.
3190 - Str: count indicates the number of characters to copy, starting at the
3191 beginning of $2, and size must be 1. If op is Reverse, the characters are
3192 copied in reverse order. Note that characters are still copied starting at
3193 the beginning of $2, so Forward vs. Reverse never affects which characters
3194 are copied, just their order as they're written to the base string.
3196 - Vec: count indicates the number of elements to copy, and size indicates the
3197 size of each element. All elements of the vec must have the same type,
3198 which must be Bool, Int, or Dbl. The operation may modify the base string
3199 before failing if there are elements with mismatched types. Size must be
3200 one of the allowed values for the contained type, described above. Count
3201 must not be greater than the size of the vec. If op is Reverse, the
3202 elements will be copied in reverse order (always starting from offset 0 of
3203 the vec, as with string sources).
3205 IncDecM <stack count> <op> <member key> [...] -> [C]
3207 IncDec{Prop,Elem} or IncDecNewElem member operation.
3209 SetOpM <stack count> <op> <member key> [... C] -> [C]
3211 SetOp{Prop,Elem} or SetOpNewElem member operation.
3213 UnsetM <stack count> <member key> [...] -> []
3215 Unset{Prop,Elem} member operation.
3217 11. Iterator instructions
3218 -------------------------
3220 IterInit <iterator id> <rel offset> <local id> [C] -> []
3221 IterInitK <iterator id> <rel offset> <local id> <local id> [C] -> []
3223 Initialize iterator. If $1 is an array, these instructions create an array
3224 iterator, rewind the array iterator to point to the beginning of the array,
3225 and store the array iterator in the iterator variable %1. Then these
3226 instructions check if the iterator is at the end, and if it is, these
3227 instructions free the iterator and transfer control to the location specified
3230 If $1 is an object that is an instance of an extension class that implements
3231 the Traversable interface, these instructions create an extension class
3232 iterator and store it in the iterator variable %1. Then these instructions
3233 check if the iterator is at the end, and if it is these instructions free the
3234 iterator and transfer control the location specified by %2.
3236 If $1 is an object that implements the Iterator interface, these instructions
3237 create an user class iterator, call $1->rewind(), and store the user class
3238 iterator in the iterator variable %1. Then these instructions check if
3239 $1->valid() returns false, and if it does these instructions free the
3240 iterator and transfer control to the location specified by %2.
3242 If $1 is an object that implements the IteratorAggregate interface, these
3243 instructions call $1->getIterator() and inspect the object x that is
3244 returned. If x is an instance of IteratorAggregate, these instructions will
3245 repeatedly execute "x = x->getIterator()" until x is not an object that is an
3246 instance of IteratorAggregate. If x is an object that implements the
3247 Traversable interface, then this instruction will behave according to the
3248 appropriate case described above. Otherwise, these instructions will throw an
3249 exception of type Exception.
3251 If $1 is an object that does not match any of the three cases above, these
3252 instructions create a default class iterator, rewind the default class
3253 iterator to point to the first accessible property, and store the default
3254 class iterator in the iterator variable %1. Then these instructions check if
3255 the iterator is at the end, and if it is these instructions free the iterator
3256 and transfer control the location specified by %2.
3258 If $1 is not an array or an object, these instructions raise a warning and
3259 transfer control to the location specified by %2.
3261 The local ids in %3 (and %4, for the *K variants) represent the locals that
3262 should receive the value (in %3) and key (in %4) for the iteration, in
3263 accordance with the type of iterator initialized in %1.
3265 The locals are stored to with the same semantics as SetL (non-binding
3268 The logical value is computed differently depending on the iterator type that
3269 is initialized in %1:
3271 If the iterator specified by %1 is a non-mutable array iterator or an
3272 extension class iterator, these instructions store a copy of the current
3275 If the iterator specified by %1 is a user class iterator for object $x,
3276 these instructions store the return value of $x->current() in %3.
3278 If the iterator specified by %1 is a non-mutable default class iterator,
3279 these instructions store a copy of the current property in %3.
3281 For the *K variants, the logical key to be stored in %4 is computed
3282 differently depending on the iterator type initialized in %1:
3284 If the iterator specified by %1 is an array iterator or an extension class
3285 iterator, this instruction stores a copy of the current key in %4.
3287 If the iterator specified by %1 is a user class iterator for object $x,
3288 this instruction stores the return value of $x->key() in %4.
3290 If the iterator specified by %1 is a non-mutable default class iterator,
3291 this instruction stores a copy of the name of the current property in %4.
3293 LIterInit <iterator id> <local id> <rel offset> <local id> [] -> []
3294 LIterInitK <iterator id> <local id> <rel offset>
3295 <local id> <local id> [] -> []
3297 Initialize iterator with local. If the local specified by %2 is not an
3298 array-like, behave as IterInit or IterInitK, except loading the base value
3299 from %2 instead of from the stack. Otherwise, create an array iterator,
3300 rewind the array iterator to point to the beginning of the array in %2, but
3301 do not store the value in %2 within the iterator. These instructions then
3302 check if the iterator is at the end, and if it is, these instructions free
3303 the iterator and transfer control to the location specified by %3. Since the
3304 array-like in %2 was not stored within the iterator, all operations on this
3305 iterator must use the LIter variants and provide the same local (containing
3306 the same array-like).
3308 IterNext <iterator id> <rel offset> <local id> [] -> []
3309 IterNextK <iterator id> <rel offset> <local id> <local id> [] -> []
3311 Iterator next. If the specified iterator is a non-mutable array iterator or
3312 an extension class iterator, advance the iterator to point to the next
3313 element. If the iterator is not at the end, these instructions transfer
3314 control to the location specified by %2.
3316 If the specified iterator is a user class iterator for object $x, this
3317 instruction executes $x->next(). Then these instructions check if $x->valid()
3318 returns true, and if it does these instructions transfer control to the
3319 location specified by %2.
3321 If the specified iterator is a non-mutable default class iterator, advance
3322 the iterator to point to the next accessible property in the object. If the
3323 iterator is not at the end, these instructions transfer control to the
3324 location specified by %2.
3326 If the specified iterator is at the end, free the iterator variable with an
3327 implicit IterFree, then fall through to the next instruction.
3329 If the specified iterator is not at the end, the local ids in %3 (and %4, for
3330 the *K variants) represent the locals that should receive the value (in
3331 %3) and key (in %4) for the iteration, in accordance with the type of
3332 iterator initialized in %1.
3334 These locals are stored to with the same semantics as SetL (non-binding
3337 The semantics of how to determine what the key and value are depend on %1 in
3338 an analogous way to IterInit{K,}.
3340 LIterNext <iterator id> <local id> <rel offset> <local id> [] -> []
3341 LIterNextK <iterator id> <local id> <rel offset>
3342 <local id> <local id> [] -> []
3344 Iterator next with local. The iterator specified by %1 must have been
3345 initialized with LIterInit or LIterNext. These instructions behave similarily
3346 to IterNext and IterNextK, except they might use the value in local %2 as the
3347 base, instead of one stored in the iterator. If the value in local %2 is a
3348 non-array-like, the base stored in the iterator is used, otherwise the value
3349 in the local is used.
3351 IterFree <iterator id> [] -> []
3353 Iterator free. This instruction frees the specified iterator variable.
3354 Typically an iterator gets freed by IterNext, so IterFree is only needed for
3355 guarding against exceptions and implementing break and return control flow
3356 statements inside iterator loops.
3358 LIterFree <iterator id> <local id> [] -> []
3360 Iterator free with local. This instruction frees the specified iterator
3361 variable, which has been initialized with local %2.
3363 IterBreak <rel offset> <iter-vec> [] -> []
3365 Iterator break. Frees vectors in %2 in left to right order then transfers
3366 control to the location specified by %1. Surprise checks are performed before
3367 iterators are freed so that in the event of an exception iterators are not
3368 double freed. Note that as with normal jumps surprise checks will only be
3369 performed if %1 is non-positive.
3372 12. Include, eval, and define instructions
3373 ------------------------------------------
3377 Include. Includes the compilation unit containing the file (string)$1. The
3378 instruction eagerly marks all functions and classes that are unconditionally
3379 declared in the outermost scope as defined. Next this instruction calls the
3380 pseudo-main function from the file (string)$1. The pseudo-main function
3381 inherits the caller's variable environment. If the execution engine cannot
3382 find a compilation unit containing the file (string)$1, this instruction
3387 Include once. Include the compilation unit containing the file (string)$1 if
3388 it hasn't been included already. This instruction eagerly marks all functions
3389 and classes that are unconditionally declared in the outermost scope as
3390 defined, and then calls the pseudo-main function from (string)$1 if it hasn't
3391 run already. The pseudo-main function inherits the caller's variable
3392 environment. If the execution engine cannot find a compilation unit
3393 containing the file (string)$1, this instruction raises a warning.
3397 Require. Includes the compilation unit containing the file (string)$1. The
3398 instruction eagerly marks all functions and classes that are unconditionally
3399 declared in the outermost scope as defined. Next this instruction calls the
3400 pseudo-main function from the file (string)$1. The pseudo-main function
3401 inherits the caller's variable environment. If the execution engine cannot
3402 find a compilation unit containing the file (string)$1, this instruction
3403 throws a fatal error.
3407 Require once. Include the compilation unit containing the file (string)$1 if
3408 it hasn't been included already. This instruction eagerly marks all functions
3409 and classes that are unconditionally declared in the outermost scope as
3410 defined, and then calls the pseudo-main function from (string)$1 if it hasn't
3411 run already. The pseudo-main function inherits the caller's variable
3412 environment. If the execution engine cannot find a compilation unit
3413 containing the file (string)$1, this instruction throws a fatal error.
3417 As ReqOnce except the string is always taken to be relative to the document
3418 root (ie SourceRoot).
3422 Eval. Executes the source code in (string)$1. This instruction eagerly marks
3423 all functions and classes that are unconditionally declared in the outermost
3424 scope as defined, and then calls the pseudo-main function from (string)$1.
3425 The pseudo-main function from (string)$1 inherits the caller's variable
3428 DefCls <class id> [] -> []
3430 Define class. Bind the class specified by %1. If the class specified by %1 is
3431 already bound, this instruction does nothing. If another class is already
3432 bound to the associated name, this instruction throws a fatal error.
3434 DefClsNop <class id> [] -> []
3436 For always-hoistable classes (which are automatically defined when the unit
3437 is loaded). This instruction is used as a marker for the location in a
3438 pseudo-main where a DefCls would've existed, but doesn't need to be. (It is
3439 used as a place to raise errors from if the class fails to define.)
3441 AliasCls <class-name, alias-name> [C] -> [C:bool]
3443 This instruction will attempt to bind the name alias-name as an alias for the
3444 class class-name. If class-name is not an existing class, and $1 is true,
3445 this instruction will attempt to autoload the class. If class-name is still
3446 not an existing class, this instruction will raise a warning and return
3447 false. If alias-name is already bound, this instruction will raise a warning
3448 and return false. Otherwise it binds the name and returns true.
3450 DefCns <litstr id> [C] -> [C]
3452 Define constant. If there is already a global constant named %1, raises a
3453 notice and pushes false. If $1 isn't a scalar, array, vec, dict, or keyset,
3454 raises a notice, and pushes false. Otherwise defines the constant named %1 to
3455 have the value $1, and pushes true.
3457 DefTypeAlias <litstr id> [] -> []
3459 Define type alias. Type aliases are a hhvm extension to PHP that allow
3460 declaring new names for existing types. The unit contains a table of the type
3461 aliases it was compiled with. This instruction looks up the type alias given
3462 by %1 in the table. If there is an existing class or type alias defined with
3463 the same name as %1, this function checks whether it is compatible with the
3464 type alias given by %1, and if it isn't it throws a fatal error.
3467 13. Miscellaneous instructions
3468 ------------------------------
3472 This. This instruction checks the current instance, and if it is null, this
3473 instruction throws a fatal error. Next, this instruction pushes the current
3474 instance onto the stack.
3476 BareThis <notice> [] -> [C:Obj|Null]
3478 This. This instruction pushes the current instance onto the stack. If %1 is
3479 BareThisOp::Notice, and the current instance is null, emits a notice. If %1
3480 is BareThisOp::NeverNull the current value of $this is guaranteed to be
3481 available and can be loaded with no null check.
3485 Check existence of this. This instruction checks the current instance, and if
3486 it is null, throws a fatal error.
3488 InitThisLoc <local variable id> [] -> []
3490 Initialize this local variable. This instruction checks the current instance,
3491 and if it is not null this instruction stores it to the specified local
3492 variable. If the current instance is null, or if this bytecode appears in a
3493 function body that is not a class method, this instruction does nothing.
3495 FuncNumArgs [] -> [C:Int]
3497 Push the number of arguments the current function was called with.
3499 ChainFaults [C C] -> [C]
3501 Chain exception objects. If either $1 or $2 is not an object that implements
3502 Throwable, raise a fatal error. Otherwise, start at $1 and walk the chain of
3503 "previous" properties until an unset one is found. Set that property to $2,
3504 unless the previous chain of $1 or $2 forms a cycle. In either case, $1 is
3505 left on the top of the stack.
3507 OODeclExists <Class|Interface|Trait> [C C] -> [C:Bool]
3509 Check for class/interface/trait existence. If $1 cannot be cast to a bool or
3510 $2 cannot be cast to a string, this instruction will throw a fatal error.
3511 Otherwise, it will check for existence of the entity named by $2, invoking
3512 the autoloader if needed and if $1 is true. The result of the existence check
3513 will be pushed on the stack.
3515 VerifyParamType <parameter id> [] -> []
3517 Verify parameter type. Functions and methods can optionally specify the types
3518 of arguments they will accept. These type constraints are memoized into each
3519 function's FPI structure.
3521 VerifyParamType checks the specified parameter against the enclosing
3522 function's corresponding parameter constraints. In case of a mismatch, a
3523 recoverable error is raised.
3525 VerifyRetTypeC [C] -> [C]
3527 Verify return type. This instruction pops $1 off of the stack, checks if $1
3528 is compatible with the current function's return type annotation and raises
3529 a warning if there is a mismatch, and then it pushes $1 back onto the stack.
3531 VerifyRetNonNullC [C] -> [C]
3533 This is intended to provide the same behavior as VerifyRetTypeC, except in
3534 only checks that $1 is non null. This should only be emitted by HHBBC if it
3535 can statically verify that return value will pass the function's type
3536 annotation if it is non null.
3538 VerifyParamTypeTS <parameter id> [C] -> []
3540 VerifyParamTypeTS pops a type structure from the stack and checks the
3541 specified parameter against this type structure. In case of a mismatch, a
3542 recoverable error is raised. If the popped cell is not a type structure,
3543 an error is raised. This instruction also verifies the reified generic type
3544 parameters of the specified parameter.
3546 VerifyRetTypeTS [C C] -> [C]
3548 VerifyRetTypeTS pops a type structure from the stack and checks whether
3549 $2 is compatible with this type structure. In case of a mismatch, a
3550 recoverable error is raised. If the popped cell is not a type structure,
3551 an error is raised. This instruction also verifies the reified generic type
3554 Self <class-ref slot> [] -> []
3556 Creates a classref that refers to the class in which the current function is
3557 defined. This instruction throws a fatal error if the current method is
3558 defined outside of a class, otherwise it writes a classref to %1.
3560 Parent <class-ref slot> [] -> []
3562 Creates a classref that refers to the parent of the class in which the
3563 current method is defined. This instruction throws a fatal error if the
3564 current method is defined outside of a class or if the class in which the
3565 current method is defined has no parent, otherwise it writes a classref to
3568 LateBoundCls <class-ref slot> [] -> []
3570 Late-bound class. Creates a classref that refers to the current late-bound
3571 class and writes it to %1.
3573 RecordReifiedGeneric <num args> [C..C] -> [C:Arr|Vec]
3575 Takes %1 amount of type structures from the stack and unless the entry already
3576 exists adds a mapping from the grouped name of these type structures to a
3577 static array that contains the runtime representation of these type structures
3578 to the global reified generics table. Returns the resulting static list
3581 ReifiedName <num args> <name> [C..C] -> [C:Str]
3583 Takes %1 type structures from the stack and mangles the type structures into
3584 the name given by %2. Returns the mangled name.
3585 This instruction also performs RecordReifiedGeneric instruction's recording
3586 duty but it can be implemented more efficiently subsumed in this instruction.
3588 CheckReifiedGenericMismatch [C:Arr|Vec] -> []
3590 Throws a fatal error unless whether each generic in $1 is reified or erased
3591 matches exactly to the expectations of the current class. If there is
3592 no class in the current context, throws a fatal error as well.
3596 Native implementation. This instruction invokes the native implementation
3597 associated with current function and returns the return value to the caller
3598 of the current function.
3600 AKExists [C C] -> [C:Bool]
3602 Checks if array (object) in $1 contains key (property) in $2 and pushes the
3603 resulting boolean onto the stack. If $2 is null, uses the empty string as
3604 key. Throws a fatal error if $1 is not an array or object, and raises a
3605 warning if $2 is not a string, integer, or null.
3607 CreateCl <num args> <class id> [C|U..C|U] -> [C]
3609 Creates an instance of the class specified by <class id> and pushes it on the
3612 The specified class must be a subclass of "Closure", must have a single
3613 public method named __invoke, and must be defined in the same unit as the
3616 If there is more than one CreateCl opcode in the unit for the Closure
3617 subclass named by %2, all of the opcodes must be possible to associate with
3618 the same class (or trait), or none if the closure will not inherit a class
3619 context at runtime. This is intended to mean that CreateCl opcodes for a
3620 given closure may only occur in bytecode bodies of functions that are
3621 generated to represent a single user-visible PHP function, async function,
3622 async closure, generator, or generator closure.
3624 Moreover, for normal (non-async, non-generator) functions and methods, there
3625 must be at most a single CreateCl opcode in the unit for a given Closure
3626 subclass contained in the unit.
3630 Checks if object in $3 contains key in $2 and pushes the result onto the
3631 stack if found. Otherwise, $1 is pushed onto the stack. $3 must be an object
3632 that supports array or indexed access (e.g. arrays, collections,
3633 implementations of ArrayAccess).
3635 ArrayIdx [C C C] -> [C]
3637 Checks if array in $3 contains key in $2 and pushes the result onto the stack
3638 if found. Otherwise, $1 is pushed onto the stack. A fatal error will be
3639 thrown if $3 is not an array.
3641 AssertRATL <local id> <repo auth type> [] -> []
3642 AssertRATStk <stack offset> <repo auth type> [] -> []
3644 Assert known "repo authoritative type", for locals or stack offsets.
3646 These opcodes may be used to communicate the results of ahead of time static
3647 analysis (hhbbc) to the runtime. They indicate that the value in the
3648 specified local or stack offset is statically known to have a particular
3649 type. The "repo auth type" immediate is an encoded RepoAuthType struct (for
3650 details see runtime/base/repo-auth-type.h).
3652 As suggested by the name, these opcodes are generally for use with
3653 RepoAuthoritative mode. They may appear in non-RepoAuthoritative mode with
3654 one restriction: "specialized" array type information may not be asserted,
3655 because the global array type table may only be present in RepoAuthoritative
3658 BreakTraceHint [] -> []
3660 This opcode has no effects, but is a hint that code immediately following it
3661 is probably not worth including in the same compilation unit as the code in
3662 front of it. In HHVM, this is used to tell the JIT to break a Tracelet when
3663 it sees this opcode.
3665 Silence <local id> <Start|End> [] -> []
3667 With %2 = Start, sets the error reporting level to 0 and stores the previous
3668 one in the local variable %1. The local variable will be overwritten without
3671 With %2 = End, if the error reporting level is 0, restores the error
3672 reporting level to the previous value (stored in local variable %1); if the
3673 error reporting level is not 0, does nothing.
3675 The verifier requires that all code paths to an End on local variable %1
3676 contain a Start on %1, and that all code paths with a Start lead to an End on
3677 the same variable. It additionally requires that none of these paths store
3678 any value in %1 between the Start and End operations. Lastly, the set of
3679 variables storing the error reporting state must be consistent across block
3682 In either case, the local variable %1 must be an unnamed local.
3684 GetMemoKeyL <local id> [] -> [C:<Int/String>]
3686 Push an int or string which is an appropriate memoize cache key for the
3687 specified local. The local should be one of the function's parameters. The
3688 exact scheme for the cache key generation depends on whether the parameter is
3689 constrained by an appropriate type constraint. This op may throw if the input
3690 value is one that cannot be converted to a cache key (IE, an object that does
3691 not implement IMemoizeParam). This op can only be used within a function
3692 marked as being a memoize wrapper.
3694 MemoGet <rel offset> <local range> [] -> [C]
3696 Retrieve a memoization value associated with the current function and push it
3697 onto the stack. The values of the specified range of locals are used as the
3698 keys to perform the lookup (if any). If any of the locals are not ints or
3699 strings, fatal. The number of locals must match the number of formal
3700 parameters to the function. If no value is present, branch to the specified
3701 offset (without pushing anything). This op can only be used within a function
3702 marked as being a memoize wrapper.
3704 MemoGetEager <rel offset> <rel offset> <local range> [] -> [C]
3706 Retrieve a memoization value associated with the current function and push it
3707 onto the stack. This instruction behaves similarily to MemoGet, but is meant
3708 to be used within an async memoize wrapper. If no value is present, branch to
3709 the first specified offset (without pushing anything). If a value is present,
3710 but it is a suspended wait-handle, push it onto the stack and branch to the
3711 second specified offset. If a value is present, and it represents an eagerly
3712 returned value (not a suspended wait-handle), push it without branching.
3714 MemoSet <local range> [C] -> [C]
3716 Store $1 as a memoization value associated with the current function and
3717 leave it on the stack. The values of the specified range of locals are used
3718 as keys to perform the lookup (if any). If any of the locals are not ints or
3719 strings, fatal. The number of locals must match the number of formal
3720 parameters to the function. If there is already a value stored with that
3721 particular set of keys, it is overwritten. This op can only be used within a
3722 function marked as being a memoize wrapper. If the function is an async
3723 memoize wrapper, this marks the value as representing a suspended return
3724 value from the wrapped async function (and therefore must be a wait-handle).
3726 MemoSetEager <local range> [C] -> [C]
3728 Store $1 as a memoization value associated with the current function and
3729 leave it on the stack. This instruction behaves similarily as MemoSet, but is
3730 meant to be used within async memoize wrappers. It indicates that the value
3731 being stored represents an eager return from the wrapped async function (and
3732 is not a suspended wait-handle).
3734 ResolveFunc <litstr id> [] -> [C]
3736 Resolve %1 as a function name to a function pointer value, then push the
3737 pointer onto the top of stack. When resolution fails, raise an error.
3739 ResolveObjMethod [C C] -> [C]
3741 Resolve $1 as a method of $2 to a method array, then push the array onto the
3742 top of stack. When $1 represents a class method of $2, the first element of
3743 the resulting array is the class pointer of $2, otherwise the first element is
3744 always $2. Fatal if the function resolves to a magic __call method. When
3745 resolution fails, raise an error.
3747 ResolveClsMethod [C C] -> [C]
3749 Resolve $1 as a class method of $2 to a method array, then push the array onto
3750 the top of stack. Fatal if there is an invoke name for PHP magic call. When
3751 resolution fails, raise an error.
3753 14. Generator creation and execution
3754 ---------------------------------------
3756 CreateCont [] -> [C:Null]
3758 This instruction may only appear in bodies of generators. Creates a new
3759 Generator object, moves all local variables from the current frame into
3760 the object, sets resume offset at the next opcode and suspends execution by
3761 transferring control flow back to the caller, returning the Generator
3762 object. Once the execution is resumed, the Null value sent by ContEnter
3763 becomes available on the stack. It is illegal to resume newly constructed
3764 Generator using ContEnter with a non-null value or ContRaise opcodes.
3766 ContEnter [C] -> [C]
3768 This instruction may only appear in non-static methods of the Generator
3769 class. It transfers control flow to the saved resume offset of a function
3770 associated with $this Generator object. The $1 will remain available
3771 on the stack after the control is transferred. Once the control is
3772 transferred back, a value determined by suspending opcode (Await, Yield,
3773 YieldK or RetC) will be pushed on the stack. This value corresponds to
3774 the next()/send() return value -- null for non-async generators, and
3775 WaitHandle or null for async generators.
3777 ContRaise [C:Obj] -> [C]
3779 This instruction may only appear in non-static methods of the Generator
3780 class. It transfers control flow to the saved resume offset of a function
3781 associated with $this Generator object. The Exception stored at $1 is
3782 thrown instead of invoking code at the resume offset. Once the control is
3783 transferred back, a value determined by suspending opcode (Await, Yield,
3784 YieldK or RetC) will be pushed on the stack. This value corresponds to
3785 the raise() return value -- null for non-async generators, and WaitHandle
3786 or null for async generators.
3790 This instruction may only appear in bodies of generators. Stores $1
3791 in the generator as the result of the current iteration, sets resume
3792 offset at the next opcode and suspends execution by transferring control
3793 flow back to the ContEnter or ContRaise. Once the execution is resumed,
3794 the value sent by ContEnter becomes available on the stack, or
3795 an exception sent by ContRaise is thrown.
3799 This instruction may only appear in bodies of generators. Stores $1
3800 in the generator as the result and $2 as the key of the current
3801 iteration, sets resume offset at the next opcode and suspends execution
3802 by transferring control flow back to the ContEnter or ContRaise. Once
3803 the execution is resumed, the value sent by ContEnter becomes available
3804 on the stack, or an exception sent by ContRaise is thrown.
3806 ContCheck <check started> [] -> []
3808 Check whether generator can be iterated. $this must be a Generator
3809 object. If the generator is finished, already running, or not yet started
3810 and <check started> is enabled, an exception will be thrown.
3812 ContValid [] -> [C:Bool]
3814 Check generator validity. $this must be a Generator object. Pushes true
3815 onto the stack if the generator can be iterated further, false otherwise.
3819 Get generator key. $this must be a Generator object. Pushes the most
3820 recently yielded key from the generator onto the stack.
3822 ContCurrent [] -> [C]
3824 Get generator value. $this must be a Generator object. Pushes the most
3825 recently yielded value from the generator onto the stack.
3827 ContGetReturn [] -> [C]
3829 Get generator's return value. $this must be a Generator object. Pushes the
3830 return value of the generator onto the stack.
3832 14.1 Generator Delegation
3833 -------------------------
3835 The following bytecodes are used to implement the Generator Delegation feature
3836 of PHP7. Generator Delegation (which is exposed to programmers as `yield from`)
3837 allows generators to yield results from other generators (referred to as their
3838 "delegates") as if they were the ones yielding the value. For a full
3839 explanation of the feature, see https://wiki.php.net/rfc/generator-delegation.
3841 The important part of this feature is how it interacts with different inputs.
3842 The `yield from` pseudo-expression takes two different types of inputs, and
3843 interacts with them very differently. The first is other generators. When
3844 When the delegate is a generator we resume execution of the subgenerator and
3845 return to the caller of the delegating generator (the one containing
3846 `yield from`) when we encounter a yield. All of the features of generators
3847 (`send`, `throw`, etc) are piped through to the delegate, and the result of the
3848 `yield from` expression is the return value of the subgenerator.
3850 The second valid type of input to `yield from` is an object conforming to the
3851 Traversable interface. When the delegate of a generator is a Traversable the
3852 `send()` method does nothing more than continue execution of the delegating
3853 generator. The `throw()` method will throw from the context of the delegating
3854 generator, and the result of the `yield from` expression will always be NULL.
3855 At a high level, you can think of `yield from <traversable>` as being
3856 equivalent to `foreach(<traversable> as $val) { yield $val; }`.
3858 While the bytecodes implementing Generator Delegation have their own API and
3859 well defined contracts, they generally expect to be used in the following
3863 ContAssignDelegate <expr>
3869 ContAssignDelegate [C] -> []
3871 This instruction may only appear in bodies of non-async generators. Stores $1
3872 in the generator as it's delegate, for use later by the ContEnterDelegate
3873 and YieldFromDelegate bytecodes. Throws an exception if $1 is not either a
3874 Traversable or another Generator.
3876 ContEnterDelegate [C] -> []
3878 This instruction may only appear in bodies of non-async generators, and the
3879 delegate property of the current generator must be non-null. If the delegate
3880 is a Generator, control flow is transfered to the saved resume offset of the
3881 delegate. $1 describes the value given to either ContEnter or ContRaise when
3882 execution of the current generator was resumed, and said value is then passed
3883 to the delegate generator for use there.
3885 YieldFromDelegate [] -> [C]
3887 This instruction may only appear in bodies of non-async generators, and the
3888 delegate property of the current generator must be non-null. If the delegate
3889 is a Traversable the current key/value pair is stored in the generator as
3890 the result of the current iteration and the iterator is advanced. When the
3891 delegate is a Generator, the ContCurrent and ContKey opcodes handle
3892 returning the result from the deepest active generator. When iteration has
3893 finished, this opcode continues executing the next instruction, otherwise it
3894 sets the resume offset to the offset specified by its immediate and returns
3895 control to the caller.
3897 ContUnsetDelegate <free iterator> [] -> []
3899 This instruction may only appear in bodies of non-async generators. Removes
3900 the currently assigned delegate of the generator. If <free iterator> is
3901 "FreeIter", and the delegate is not another generator, then this opcode is
3902 responsible for freeing the internal iterator used by this group of opcodes.
3903 If "IgnoreIter" then it is expected that the iterator is freed elsewhere.
3904 When the delegate is another generator then it assumes that the iterator was
3905 never initialized in the first place.
3910 WHResult [C:Obj] -> [C]
3912 If $1 is not a subclass of WaitHandle, throws a fatal error. If $1 succeeded,
3913 this instruction pushes the result value from the WaitHandle. If $1 failed,
3914 this instruction throws the exception stored in the WaitHandle. If $1 is not
3915 finished, throws an Exception.
3919 This instruction may only appear in bodies of async functions. Awaits
3920 a WaitHandle provided by $1, suspending the execution if the WaitHandle
3923 If $1 is not a subclass of WaitHandle, throws a fatal error. If $1 succeeded,
3924 this instruction pushes the result value from the WaitHandle. If $1 failed,
3925 this instruction throws the exception from the WaitHandle. Otherwise the
3926 execution needs to be suspended:
3928 If the async function is executed eagerly, creates an AsyncFunctionWaitHandle
3929 object, moves all local variables and iterators from the current frame into
3930 the object, sets resume offset at the next opcode, marks the
3931 AsyncFunctionWaitHandle as blocked on the WaitHandle provided by $1 and
3932 suspends execution by transferring control flow back to the caller, returning
3933 the AsyncFunctionWaitHandle object.
3935 If the async function is executed in resumed mode, sets resume offset at
3936 the next opcode, marks the AsyncFunctionWaitHandle as blocked on the
3937 WaitHandle provided by $1 and suspends execution by transferring control
3938 flow back to the scheduler.
3940 Once the execution is resumed, the result of the WaitHandle provided by $1
3941 becomes available on the stack.
3943 AwaitAll<local-range> [] -> [C:Null]
3945 Fetches instances of Awaitables from the locals in range %1, and suspends
3946 until all of them have completed, at which point execution is resumed with a
3947 single null on the stack.
3949 Nulls in %1 are ignored, a fatal error is thrown if other non-Awaitables are
3950 encountered. The stack must be empty. Should all of the Awaitables in %1
3951 already be complete a null will be pushed to the stack without suspending
3952 the current function.
3954 Basic statement transformations
3955 -------------------------------
3957 To achieve HHBC's goal of making it straightforward for an interpreter or a
3958 compiler to determine order of execution, control flow statements are
3959 transformed to use the simpler constructs. Most control flow statements such as
3960 "if", "while", and "for" are implemented in a straightforward manner using the
3963 HHBC provides the Switch instruction for implementing very simple switch
3964 statements; most real switch statements are implemented naively using the Eq
3965 and JmpNZ instructions. Also, the functionality of both the echo statement and
3966 the print statement is implemented with the Print instruction.
3968 Foreach statements are implemented using iterator variables and the Iter*
3969 instructions. Each foreach loop must be protected by an EH catch entry to
3970 ensure that the iterator variable is freed when a foreach loop exits abnormally
3971 through an exception.
3973 Simple break statements and continue statements are implemented using the Jmp*
3974 and IterFree instructions. Dynamic break is implemented using an unnamed local
3975 (to store the 'break count') and a chain of basic blocks, where each block
3976 decrements the unnamed local variable and compares it with 0, and then decides
3980 Basic expression transformations
3981 --------------------------------
3983 To reduce the size of the instruction set, certain types of expressions are
3986 1) Unary plus and negation
3987 Unary plus and negation "+(<expression>)" gets converted to "(0 +
3988 (<expression>))", and "-(<expression>)" gets converted to "(0 -
3991 2) Assignment-by operators (+=, -=, etc)
3992 Assignment-by operators are converted to use the SetOp* instructions.
3994 3) List assignment (list)
3995 List assignments are converted to use an unnamed local variable and the SetM
3996 and VGet* instructions. In case of exception, the unnamed local variable is
3997 freed using EH entry.
3999 4) Logical and and logical or operators (and/&&, or/||)
4000 If any of the operands side-effect, these operators are implemented using Jmp*
4001 instructions instead of using the "and" and "or" instructions to implement
4002 short-circuit semantics correctly. All Jmp* instructions used to implement
4003 "and" and "or" operators will be forward jumps.
4005 5) The new expression
4006 The new expression is implemented by using the NewObj*, FPushCtor and FCall
4009 6) The ternary operator (?:)
4010 The functionality of the ternary operator is implemented using Jmp*
4011 instructions. All Jmp* instructions used to implement the ternary operator will
4014 7) Silence operator (@)
4015 The silence operator is implemented by using various instructions (including
4016 the Jmp* instructions), unnamed local variables, and an EH catch entry. All Jmp*
4017 instructions used to implement the silence operator will be forward jumps.
4019 8) The $this expression
4020 The $this expression has different effects depending on whether or not $this is
4021 the direct base of a property expression (such as "$this->x") or a method call
4022 expression (such as "$this->foo()"). When the $this expression is the direct
4023 base of a property expression or a method call expression, the This instruction
4026 A bare $this expression within an instance method is handled one of two ways:
4027 general or BareThis-optimized (optional). The general solution accesses a local
4028 variable named "this", which is initialized at the beginning of the method
4029 using the InitThisLoc instruction. The BareThis optimization applies to bare
4030 $this access as long as $this is not passed by reference and there are no
4031 dynamic method variables. In such cases, the BareThis instruction can be used
4032 to directly access $this, and the InitThisLoc instruction is not needed.
4035 Warning and errors at parse time
4036 --------------------------------
4038 Certain syntactically correct source code may cause warnings or errors to be
4039 raised when the source file is parsed. Examples of this include using "$this"
4040 on the left hand side of the assignment, using "$this" with binding assignment,
4041 using "$a[]" in an r-value context, and doing "unset($a[])". HHBC handles these
4042 cases by generating Throw or Fatal instructions at the beginning of the body
4043 for the pseudo-main function.
4049 At the time of this writing, the HipHop bytecode specification is missing the
4052 1) Description of traits
4053 2) Description of metadata for class statements, trait statements, and method
4055 3) Description and examples for the yield generator feature
4056 4) Description of the late static binding feature
4057 5) Description of the resource type
4058 6) Definitions of operators (ex. +, -, !) and other helper functions (ex.
4059 is_null, get_class, strlen)
4060 7) High level description of how namespaces are dealt with and any relevant
4062 8) Description of async function implementation
4065 /* Local Variables: */
4066 /* fill-column: 79 */