Skip to main content

Design of the IR

Introduction

This document is a reference manual for the Hermes High-level IR. The IR is a Static Single Assignment (SSA) based representation that captures the JavaScript language semantics. It features optional types (values may be annotated with types).

The IR representation is designed to be used as an in-memory form. The IR can be dumped to human readable assembly-like format.

Well-Formedness

This section describes the rules that define a valid IR.

  • Instructions must be dominated by their operands.

  • Basic block must end with a terminator, which is a branch instruction or a return instruction.

  • There has to be exactly one terminator for each basic block.

  • AllocStack instructions must appear at the 'entry' basic block (the first basic block in the function).

  • PHI Nodes must appear at the beginning of the basic block and must contain an entry for each predecessor.

Frames:

Every JavaScript function is a closure that can capture variables from its declaration scope. The declaration scope may be the global scope or another function. A closure is a pair of function code, which contains the code of the function, and a context which saves the environment that the closure may access.

Function variables that are captured by a closure are allocated in a scope on the heap and the scope is passed as part of the context to the closure. Closures may access variables at all nest-levels, which means that they can access multiple scopes. We implement this feature by nesting scopes and linking them together. Each scope (the set of captured variables) also has a reference to the scope of the caller function. Closures can access variables at different nesting levels by loading the parent scope for each scope.

At the IR Level we define a few instructions that can load and store frame variables. Functions own variables, that are storage units that represent variables at the source level. These variables can be optimized away or promoted to the stack, etc. We define the AllocStack instruction for allocating variable storage. The only instructions that can access the storage values (Variable and AllocStack) are the Load and Store instructions. It is not possible to save the address of the allocation itself. Depending on the implementation of the virtual machine, the heap allocations may be packed into a single frame.

Types:

The Hermes high-level IR is optionally typed. Values may be annotated with the expected type of the value. The types are optional and untyped programs are correct. The types represent primitive JavaScript types, or refinement of these types. All values can be annotated with types: Functions, Instructions and Parameters. Annotations of functions represent the type of the returned value. The type annotations are not a suggestion or a hint. They must be correct and consistent or else the program may fail at run time. Programs are expected to run and have the same semantics when the type annotations are stripped.

Some instructions in the IR expect operands of specific types, or produce specific types. For example, the CondBranch instruction expects the condition operand to be annotated as a boolean type. The ToBool instruction produces values that are annotated as boolean type.

The optimizer may optimize the IR based on type annotations. For example, if the operand of the instruction ToBool is annotated with the boolean type then the optimizer is free to remove the instruction and replace all uses with the operand of the conversion instruction.

Example:

This is a short example of a valid program in textual IR. The function contains four basic blocks with a few instructions. The code below follow the requirements of a well-formed function defined in the previous section.

  function forEach(cond : boolean, value : number)
%BB0:
%0 = BranchInst %BB1
%BB1:
%2 = CondBranchInst %cond, %BB2, %BB3
%BB2:
%3 = ReturnInst %cond
%BB3:
%4 = ReturnInst %value

Side Effects:

The instructions in the IR are annotated with side effect labels. The labels describe the kind of effect the instruction has on memory, IO state (for example, hardware IO such as drawing to a screen or sending a network packet), and whether they can throw. The two kind of memory side effects are 'read' and 'write'. ('write' actually indicates "read and/or write".) These side effect specifications indicate that the instruction does not have IO effects or throw. The 'unknown' side effect is maximally conservative: it indicates that the instruction may read, write, have IO effects, and/or throw. These side effect annotations allow the optimizer to decide which optimizations are legal. For example, it is not legal to sink instructions that can write to memory past each other. It is not legal to hoist instructions that read to memory outside of a loop if there is another instruction that writes to memory in that loop, because the writer instruction may clobber memory that the reader may read.

Some instructions that allocate memory are marked as not having any side effects. This is because the instructions only touch the newly allocated memory and do not influence the rest of the heap. Notice that we don't model the effect of instructions on the garbage collector or anything like that, just the content of the allocated memory.

Register allocation

In Hermes, register allocation is performed on the IR. An infinite number of virtual registers are allocated while preserving the constraints of the IR and of the low-level target. Registers are allocated in an attempt to reduce the number of registers, values across PhiNodes are coalesced, AllocStack instructions are assigned with a dedicated register and arguments to call instructions are placed in consecutive registers.

While in SSA form, the IR does not support all of the things that can be done with registers. This is why the Register Allocator introduces MOV instructions that represent a copy of one register to another. We lower some of the load/store instructions into MOVs, and spill registers with MOV instructions.

Generator Overview

When generating the IR for a generator function, we make two functions: an outer GeneratorFunction and an inner function. The outer function calls CreateGenerator on the inner function, and returns the resultant generator.

The inner function assumes that it can store and retrieve state from its own closure. As such, it contains instructions to start, save/yield, and resume generators.

CreateGenerator: An instruction to create a generator given a Function. First, it creates an inner GeneratorInnerFunction, then it wraps it in a Generator object. Used by the GeneratorFunction to create the generator which is returned upon calling it.

StartGenerator: Always the first instruction executed when an inner function is called. Restores values for all local variables in the generator, and jumps to the resume point of the generator if it's suspended. If the generator hasn't been started yet, simply continues execution.

SaveAndYield: Saves necessary state to the closure and yields execution. In practice, this will save state and use the return opcode to allow the caller to get the yield result. Emitting a SaveAndYield also emits its corresponding ResumeGenerator.

ResumeGenerator: Placed at the start of the block following the SaveAndYield to which it corresponds. Resumes execution by loading context from the closure, and then using state stored in the closure, does one of 3 things:

  • Continues execution with the result of the instruction being the argument to .next().
  • Throws a value immediately
  • Sets an %isReturn flag to true, which later instructions may branch on to execute the finally if necessary, and then return.

Instruction semantics

This section describes the semantic of the instruction that are defined in the IR. Please make sure to update this section as new instructions are added to the compiler.

BranchInst

BranchInst_
DescriptionJumps to a different basic block.
Example%0 = BranchInst %BB1
ArgumentsA single operand which is the target basic block.
SemanticsTerminates a basic block and 'jumps' to a different basic block.
EffectsDoes not read or write from memory.

ReturnInst

ReturnInst_
DescriptionLeaves the function and returns a value.
Example%0 = ReturnInst %17
ArgumentsA single operand which is the returned value. Notice the functions that return without an explicit value return the 'undefined' value.
SemanticsTerminates a basic block and transfer the control to the caller of the current function.
EffectsDoes not read or write from memory.

AllocStackInst

AllocStackInst_
DescriptionAllocates a variable on the stack.
Example%0 = AllocStackInst $name
Arguments$name is the textual representation of the variable at the sourcecode level.
SemanticsAllocStack allocates a variable on the stack. Depending on the implementation of the VM, the variables may be packed into a single frame. AllocStack values may be used by instructions in different functions that represent closures created by the current functions. AllocStack values are used to represent local and captured variables. The AllocStack itself needs to be used directly. It is not possible to save a reference to the reference. The lifetime of the AllocStack may not exceed the lifetime of the allocating function.
EffectsDoes not read or write from memory.

LoadFrameInst

LoadFrameInst_
DescriptionLoads a value from a variable.
Example%1 = LoadFrameInst %0
ArgumentsThe variable from which the instruction loads.
SemanticsThe the instruction reads from a variable. The address must be a valid variable.
EffectsReads from memory.

LoadStackInst

LoadStackInst_
DescriptionLoads a value from a stack allocated memory pointed by a reference.
Example%1 = LoadInst %0
ArgumentsThe address from which the instruction loads.
SemanticsThe the instruction reads from memory. The address must be a valid stack address.
EffectsReads from memory.

StoreFrameInst

StoreFrameInst_
DescriptionStores a value to a frame variable.
Example%1 = StoreFrameInst %value, %variable
Arguments%value is the value to be stored. %address is the reference to the variable where the value will be stored.
SemanticsThe the instruction saves a value to memory. The address must be a valid variable.
EffectsWrites to memory.

StoreStackInst

StoreStackInst_
DescriptionStores a value to a stack allocated memory.
Example%1 = StoreStackInst %value, %stack_allocated
Arguments%value is the value to be stored. %address is the reference to stack allocation.
SemanticsThe the instruction saves a value to memory. The address must be a valid stack allocation.
EffectsWrites to memory.

AsNumberInst

AsNumberInst_
DescriptionCasts a JavaScript value into a number value.
Example%1 = AsNumberInst %input
ArgumentsThe value to cast.
SemanticsThe instruction follows the JavaScript rules for converting types into numbers.
EffectsMay read or write to memory.

AsInt32Inst

AsInt32Inst_
DescriptionCasts a JavaScript value into a signed 32-bit integer value.
Example%1 = AsInt32Inst %input
ArgumentsThe value to cast.
SemanticsThe instruction follows the JavaScript rules for converting types into 32-bit signed integers.
EffectsMay read or write to memory.

AddEmptyStringInst

AddEmptyStringInst_
DescriptionConvert a value to string as if evaluating value + ''
Example%1 = AddEmptyStringInst %input
ArgumentsThe value to cast.
SemanticsThe instruction follows the JavaScript rules for adding an empty string to a value (ES5.1 11.6.1).
EffectsMay read or write to memory or throw.

CondBranchInst

CondBranchInst_
DescriptionJumps to one of two blocks depending on a condition value.
Example%1 = CondBranchInst %cond, %BB1, %BB2
Arguments%cond is the condition variable, %BB1 is the 'True' block, %BB2 is the 'False' block.
SemanticsThe instruction observes the value of a typed value and jumps to one of two basic blocks. If the condition is evaluated as 'True' the program jumps to the 'True' block. Otherwise the program jumps to the 'False' block.
EffectsDoes not read or write from memory.

CompareBranchInst

CompareBranchInst_
DescriptionPerforms a binary comparison of the two operands and a conditional branch depending on the result.
Example%0 = CompareBranch %x, %y, %BB1, %BB2
Arguments%x and %y are the operands of the binary operation, %BB1 is the 'True' block, %BB2 is the 'False' block.
SemanticsThe instruction follows the rules of JavaScript for each one of the binary operators defined in the instruction. If the condition is evaluated as 'True' the program jumps to the 'True' block. Otherwise the program jumps to the 'False' block.
EffectsMay read and write memory.

CreateScopeInst

CreateScopeInst_
DescriptionCreate a new function top-level scope.
Example%0 = CreateScopeInst %desc
Arguments%desc describes the function's top-level scope.
SemanticsCreates the top-level scope for its function.
EffectsDoes not read or write to memory.

CreateInnerScopeInst

CreateInnerScopeInst_
DescriptionCreates a new scope with the given parent
Example%0 = CreateInnerScopeInst %parent, %desc
Arguments%parent is the inner scope's parent scope, and %desc describes the scope that is being created.
SemanticsCreates a new inner scope within the given parent.
EffectsDoes not read or write to memory.

CreateFunction

CreateFunction_
DescriptionConstructs a new function into the current scope from its code representation.
Example%0 = CreateFunction %function,
Arguments%function is the function that represents the code of the generated closure.
SemanticsThe instruction creates a new closure that may access the lexical scope of the calling function
EffectsDoes not read or write to memory.

BinaryOperatorInst

BinaryOperatorInst_
DescriptionPerforms the binary operation on the two operands.
Example%0 = BinaryOperatorInst %x, %y
Arguments%x and %y are the operands of the binary operation.
SemanticsThe instruction follows the rules of JavaScript for each one of the binary operators defined in the instruction.
EffectsMay read and write memory.

DirectEvalInst

DirectEvalInst_
DescriptionImplement a syntactical call to eval(arg) where eval is global property.
Example%0 = DirectEvalInst %value1
Arguments%value1 is the value which will be evaluated.
SemanticsImplement the semantics of ES6 PerformEval(%value1, evalRealm, strictCaller=true, direct=true) (ES6 18.2.1.1). Note that we only support "strictCaller=true".
EffectsUnknown

CallInst

CallInst_
DescriptionCalls another function with some arguments.
Example%0 = CallInst %callee, %this, %arg0, %arg1, %arg2, ...
Arguments%callee is the function to execute. %this is a reference to the 'this' value. Arguments %arg0 ... %argN are the arguments passed to the function.
SemanticsThe instruction passes the control to the callee, that must be of closure type. The arguments are mapped to the parameters. Unmapped parameters are initialized to 'undefined'.
EffectsMay read and write memory.

ConstructInst

ConstructInst_
DescriptionConstruct a new object with a constructor
Example%0 = ConstructInst %constructor, #undefined, %arg0, %arg1, %arg2, ...
Arguments%constructor is the constructor function to execute. #undefined is not used. %arg0 ... %argN are the arguments passed to the constructor function.
SemanticsThe instruction performs the steps defined in ES5.1 sec-11.2.2 and sec-13.2.2. It allocates the object and calls the constructor function with the new object and the supplied arguments.
EffectsMay read and write memory.

CallBuiltinInst

CallBuiltinInst_
DescriptionCalls a builtin function passing "undefined" for this
Example%0 = CallBuiltinInst %builtinNumber, %undefined, %arg0, %arg1, %arg2, ...
Arguments%builtinNumber is the builtin to execute. Arguments %arg0 ... %argN are the arguments passed to the function.
SemanticsThe instruction passes the control to the builtin in a VM-specific way. The arguments are mapped to the parameters. Unmapped parameters are initialized to 'undefined'.
EffectsMay read and write memory.

CallIntrinsicInst

CallIntrinsicInst_
DescriptionCalls an unsafe compiler intrinsic, passing "undefined" for this
Example%0 = CallIntrinsicInst %intrinsicsIndex, %undefined, %arg0, %arg1, %arg2, ...
Arguments%intrinsicsIndex is the intrinsic to execute. Arguments %arg0 ... %argN are the arguments passed to the function.
SemanticsThe instruction passes the control to the intrinsics in a VM-specific way. The arguments are mapped to the parameters.
EffectsMay read and write memory.

GetBuiltinClosureInst

GetBuiltinClosureInst_
DescriptionGet a closure of a builtin function
Example%0 = GetBuiltinClosureInst %builtinNumber
Arguments%builtinNumber is the builtin to return the closure of.
Semantics
EffectsReads from memory.

LoadPropertyInst

LoadPropertyInst_
DescriptionLoads the value of a field from a JavaScript object.
Example%0 = LoadPropertyInst %object, %property
Arguments%object is the object to load from. %property is the name of the field.
SemanticsThe instruction follows the rules of JavaScript property access in ES5.1 sec 11.2.1. The operation GetValue (ES5.1. sec 8.7.1) is then applied to the returned Reference.
EffectsMay read and write memory or throw.
TryLoadGlobalPropertyInst_
DescriptionLoads the value of an existing field from the global object or throw if it doesn't exist.
Example%0 = TryLoadGlobalPropertyInst %object, %property
Arguments%object is the global object. %property is the name of the field, which must be a string literal.
SemanticsSimilar to LoadPropertyInst, but throw if the field doesn't exist.
EffectsMay read and write memory or throw.

DeletePropertyInst

DeletePropertyInst_
DescriptionDeletes the value of a field from a JavaScript object.
Example%0 = DeletePropertyInst %object, %property
Arguments%object is the object to modify. %property is the name of the field.
SemanticsThe instruction follows the rules of JavaScript property access.
EffectsMay read and write memory.

StorePropertyInst

StorePropertyInst_
DescriptionStores a value to field in a JavaScript object.
Example%4 = StorePropertyInst %value, %object, %property
Arguments%value is the value to be stored. %object is the object where the field %property will be created or modified.
SemanticsThe instruction follows the rules of JavaScript property access in ES5.1 sec 11.2.1. The operation PutValue (ES5.1. sec 8.7.2) is then applied to the returned Reference.
EffectsMay read and write memory or throw.

TryStoreGlobalPropertyInst

TryStoreGlobalPropertyInst_
DescriptionAttempt to store a value into an existing field of the global object and throw if it doesn't exist.
Example%4 = TryStoreGlobalPropertyInst %value, %object, %property
Arguments%value is the value to be stored. %object is the global object, where the field %property will be stored. %property must be a string literal.
SemanticsSimilar to StorePropertyInst, but throw if the field doesn't exist.
EffectsMay read and write memory or throw.

StoreOwnPropertyInst

StoreOwnPropertyInst_
DescriptionStores a value to an own property of JavaScript object.
Example%4 = StoreOwnPropertyInst %value, %object, %property, %enumerable : boolean
Arguments%value is the value to be stored. %object is the object where the field with name %property will be created or modified. %enumerable determines whether a new property will be created as enumerable or not.
SemanticsThe instruction follows the rules of JavaScript own property access. The property is created or updated in the instance of the object, regardless of whether the same property already exists earlier in the prototype chain.
EffectsMay read and write memory.

StoreNewOwnPropertyInst

StoreNewOwnPropertyInst_
DescriptionCreate a new own property in what is known to be a JavaScript object.
Example%4 = StoreNewOwnPropertyInst %value, %object, %property, %enumerable : boolean
Arguments%value is the value to be stored. %object, which must be an object, is where the field with name %property will be created. %property must be a string literal, otherwise it is impossible to guarantee that it is new. %enumerable determines whether the new property will be created as enumerable or not.
SemanticsThe instruction follows the rules of JavaScript own property access. The property is created in the instance of the object, regardless of whether the same property already exists earlier in the prototype chain.
EffectsMay read and write memory.

StoreGetterSetterInst

StoreGetterSetterInst_
DescriptionAssociates a pair of getter and setter with an own field in a JavaScript object, replacing the previous value.
Example%4 = StoreGetterSetterInst %getter, %setter, %object, %property, %enumerable
Arguments%getter is a getter accessor, or undefined. %setter is a setter accessor, or undefined. %object is the object where the field %property will be created or modified. %enumerable determines whether a new property will be created as enumerable or not.
SemanticsThe instruction follows the rules of JavaScript property access. The property is created or updated in the instance of the object, regardless of whether the same property already exists earlier in the prototype chain. It replaces both accessors even if one or both of the parameters are undefined.
EffectsMay read and write memory.

ThrowIfHasRestrictedGlobalPropertyInst

ThrowIfHasRestrictedGlobalPropertyInst_
DescriptionRaises an exception if the given name is a restricted global property.
ExampleThrowIfHasRestrictedGlobalPropertyInst %name : string
Arguments%name is the name to be checked agains global restricted properties.
SemanticsImplements the semantics of ES2023 9.1.1.4.14 followed by a throw if %name is a restricted global property.
EffectsUnknown.

AllocObjectInst

AllocObjectInst_
DescriptionAllocates a new JavaScript object on the heap.
Example%0 = AllocObjectInst %sizeHint : LiteralNumber, %parent : EmptySentinel or null or Value
Arguments%sizeHint% indicates that the object will need at least that many property slots. %parent is the optional parent to create the object with: EmptySentinel means use Object.prototype, null* means no parent, or otherwise use the specified value.
SemanticsThe instruction creates a new JavaScript object on the heap. If the parent is invalid (not EmptySenyinel, null or object), it is silently ignored.
EffectsDoes not read or write to memory.

AllocObjectLiteralInst

AllocObjectLiteralInst_
DescriptionAllocates a new JavaScript object on the heap. During lowering pass it will be lowered to either an AllocObjectInst or a HBCAllocObjectFromBufferInst.
Example%0 = AllocObjectLiteralInst "prop1" : string, 10 : number
Arguments%prop_map is a vector of (Literal, value) pairs which represents the properties and their keys in the object literal.
SemanticsThe instruction creates a new JavaScript object on the heap with an initial list of properties.
EffectsDoes not read or write to memory.

AllocArrayInst

AllocArrayInst_
DescriptionAllocates a new JavaScript array on the heap.
Example%0 = AllocArrayInst %sizeHint, %value0, %value1, ...
ArgumentssizeHint tells the size of the array that the VM should allocate. It must be equal or larger than the initial list of elements in this instruction. The rest of the values are all literal values as the initial elements of the array. Non-literal values or values after elision will be inserted into the array separately.
SemanticsThe instruction creates a new JavaScript array on the heap with a hinted size and initial list of elements.
EffectsDoes not read or write to memory.

CreateArgumentsInst

CreateArgumentsInst_
DescriptionAllocates the JavaScript arguments array-like object on the heap.
Example%0 = CreateArgumentsInst
ArgumentsNone.
SemanticsThe instruction creates the arguments object, populates it with copies of the values of the arguments (according to "strict mode" semantics) and sets arguments.length to the number of arguments (this isn't copied or counted). There should be only one CreateArgumentsInst in a function.
EffectsDoes not read or write to memory.

CreateRegExpInst

CreateRegExpInst_
DescriptionConstruct a RegExp object from a regexp literal.
Example%0 = CreateRegExpInst "pattern", "flags"
Argumentspattern: LiteralString and flags: LiteralString
SemanticsIt is equivalent to calling RegExp(pattern, flags), except that it calls the built-in constructor, even if RegExp has been overridden.
EffectsDoes not read or write to memory.

SwitchInst

SwitchInst_
DescriptionThe ‘switch‘ instruction is used to transfer control to one of different places.
Example%0 = SwitchInst %input, %default, [%val0, %block0], [%val1, %block1] ..
ArgumentsThe instruction accepts an input, a default block, and one or more pairs of value-destination values. The value must be a primitive JS type, and the destination must be a basic block within the current function.
SemanticsThe semantic of the instruction is identical to a sequence of 'if' statements that compare the value of the input to each of the case statements. Repeating the same value is not allowed.
EffectsMay read and write memory.

GetPNamesInst

GetPNamesInt_
DescriptionGenerates the property enumerator, which is a collection of registers that hold the state of the enumerator (iterator, object base, index, size, etc).
Example%0 = GetPNamesInt %propertyAddr, %baseAddr, %indexAddr, %sizeAddr, %iteratorAddr, %onEmpty, %onLast
ArgumentsThe first 5 parameters are addresses (stack allocated addresses) that represent the state of the property enumerator. The last two argument are jump destination for the two cases: empty object and object with some properties.
SemanticsThis instruction is a terminator instruction and prepares the enumerator for the GetNextPNameInst instruction to consume.
EffectsMay read and write memory.

GetNextPNameInst

GetNextPNameInst_
DescriptionLoads the next property from the object property enumerator.
Example%0 = GetNextPNameInst %propertyAddr, %baseAddr, %indexAddr, %sizeAddr, %iteratorAddr, %onLast, %onSome
ArgumentsThe first argument is the destination where the name of the property is written into. The next 4 arguments are the state of the property enumerator. The last two arguments are the destination blocks for: no next property, or some property available.
SemanticsThis instruction is a terminator instruction that uses the state that was prepared by the GetPNamesInst instruction.
EffectsMay read and write memory.

CatchInst

CatchInst_
DescriptionThis instruction catches an exception, and returns that exception.
Example%0 = CatchInst
ArgumentsThis instruction does not have arguments.
SemanticsThis instruction will be generated for each catch block and for each finally block. The current exception will be returned. CatchInst can only show up at the beginning of a basic block. The coverage and depth information for the CatchInst will be constructed dynamically later during bytecode generation.
EffectsMay read and write memory.

ThrowInst

ThrowInst_
DescriptionThis instruction will throw an exception.
Example%0 = ThrowInst %e
ArgumentsThis instruction takes one parameter, which is the register that contains the exception value
SemanticsThis instruction is a terminator instruction that will transition the control to the CatchInst that covers this instruction with closest scope.
EffectsMay read and write memory.

CheckHasInstanceInst

CheckHasInstanceInst_
DescriptionCheck whether an object has a particular instance.
Example%0 = CheckHasInstanceInst %check_result, %left, %right, %onTrue, %onFalse
ArgumentsThis instruction takes 5 parameters: %check_result will be a write-only stack register and holds the check result, %left and %right are the operands of instanceof, and %onTrue and %onFalse are the jump targets in case of check returns true/false.
SemanticsThis instruction is generated as part of instanceof operator. It checks whether %right could possibly have %left as an instance, and returns the check result. If the checked object is invalid to have the target instance, it will throw an exception. It the check returns false, it jumps to the %jump_label.
EffectsMay read or write memory.

TryStartInst

TryStartInst_
DescriptionMark the beginning of the try blocks.
Example%0 = TryStartInst %catchTargetBlock, %tryBodyBlock
ArgumentsThis instruction takes 2 arguments: %tryBodyBlock is the block where the body of Try starts, %catchTargetBlock is the basic block that contains the CatchInst which covers this try. Both %tryBodyBlock and %catchTargetBlock are successors of this instruction.
SemanticsThis is a nop, used only for tracking the beginning of try blocks.
EffectsDoes not read or write memory.

TryEndInst

TryEndInst_
DescriptionMark the end of the try blocks.
Example%0 = TryEndInst
ArgumentsThis instruction does not have arguments.
SemanticsThis is a nop, used only for tracking the end of try blocks.
EffectsTechnically this instruction itself does not touch memory, however we mark it as may write to prevent optimizations going pass this instruction.

PhiInst

PhiInst_
DescriptionThis is a Phi node instruction.
Example%0 = PhiInst %value0, %block0, [%value1, %block1]
ArgumentsA list of pairs of value and incoming basic block.
SemanticsThe PhiNode needs to have a single entry for each incoming basic block of the block the PHI is located in. The incoming value must dominate the last instruction in the incoming block.
EffectsDoes not read or write memory.

MovInst

MovInst_
DescriptionThe MOV inst represents a low-level operation of moving one register to another.
Example%0 = MovInst %value0
ArgumentsAny value.
SemanticsThe Mov instruction is only valid after Register Allocation in bytecode as we move away from SSA form.
EffectsDoes not read or write memory.

ImplicitMovInst

ImplicitMovInst_
DescriptionThe ImplicitMov inst represents moving one register to another, except the mov will be performed implicitly by an immediately-subsequent instruction. This is used to express to the optimizer instructions which modify registers other than their destination.
Example%0 = ImplicitMovInst %value0
ArgumentsAny value.
SemanticsThe ImplicitMov instruction is only valid after Register Allocation in bytecode as we move away from SSA form.
EffectsDoes not read or write memory.

DebuggerInst

DebuggerInst_
DescriptionThis instruction corresponds to the JavaScript debugger statement.
Example%0 = DebuggerInst
ArgumentsIt takes no arguments and returns no values.
SemanticsIts behavior is implementation-dependent.
EffectsDoes not read or write to memory.

GetNewTargetInst

GetNewTargetInst_
DescriptionObtains the value of new.target in the current function or constructor.
Example%0 = GetNewTargetInst
ArgumentsNone
SemanticsIt must only be called from a ES6 class constructor or ES5 function. If the callee was invoked from new, it returns the function object of the direct constructor, otherwise undefined.
EffectsDoes not read or write memory

ThrowIfEmptyInst

ThrowIfEmptyInst_
DescriptionCheck whether the value is "empty", and if it is, throw ReferenceError, otherwise return it.
Example%_ = ThrowIfEmptyInst %value
ArgumentsThe value to check.
SemanticsIt is used to implement ES6 TDZ functionality. Variables declared with let are poisoned with empty until they are initialized.
EffectsPotentially throws an exception. Has no other side effects.

CoerceThisNS

CoerceThisNS_
DescriptionCoerces its argument using the rules of "this" coercion to object in non-strict mode.
Example%0 = CoerceThisNS %value0
ArgumentsAny value.
Semantics
EffectsDoes not read or write memory (it potentially creates a new object)

CreateGenerator

CreateGenerator_
DescriptionConstructs a new GeneratorInnerFunction from its code representation, and wraps it in a Generator object.
Example%0 = CreateGenerator %function,
Arguments%function is the function that represents the code of the generator's inner function.
SemanticsCreates a new GeneratorInnerFunction closure that may access the environment and wraps it in a generator
EffectsDoes not read or write to memory (creates a new object).

StartGenerator

StartGenerator_
DescriptionJump to the proper first instruction to execute in a GeneratorInnerFunction
Example%0 = StartGenerator
ArgumentsNone
SemanticsJumps to a BasicBlock which begins with a ResumeGenerator and sets the internal generator state to "executing", but does not handle next(), return(), or throw() as requested by the user.
EffectsReads and writes memory. Restores the stack based on saved state, and jumps to another BasicBlock

SaveAndYield

SaveAndYield_
DescriptionSaves information needed to resume generator execution and yield.
Example%0 = SaveAndYield %value, %next
Arguments%value is the value to yield, %next is the next BasicBlock to execute upon resuming, which must begin with a ResumeGeneratorInst (generated alongside SaveAndYield).
SemanticsSaves the frame variables and the next IP to the closure, and yield execution.
EffectsReads and writes to memory, may throw or execute.

ResumeGenerator

ResumeGenerator_
DescriptionPerform the user-requested action on resuming a generator.
Example%0 = ResumeGenerator %isReturn
Arguments%isReturn is an output argument set to true if the user requested a return, false otherwise.
SemanticsIf the user requested next(), continue on. If the user requested throw(), throw. If the user requested return(), set %isReturn to true and continue. Subsequent instructions will check %isReturn and execute any finally handlers, for example, before returning.
EffectsMay read and write memory. (may throw)

IteratorBegin

IteratorBegin_
DescriptionBegins array destructuring on a given iterable source.
Example%0 = IteratorBegin %sourceOrNext
Arguments%sourceOrNext[in/out] is the stack location for source to destructure from. Is set to source if performing array iteration, else set to the .next() method of the iterator.
SemanticsIf %sourceOrNext is an Array then it remains unmodified and the instruction returns 0, but if it is not, it is replaced with the 'next' method so that it can be called on each step of the iteration and the instruction returns the iterator object. If the [Symbol.iterator] function throws, this instruction will throw.
EffectsMay read and write memory, may throw or execute.

IteratorNext

IteratorNext_
DescriptionDestructures the next value from a given iterator.
Example%0 = IteratorNext %iterator %sourceOrNext
Arguments%iterator is the index or the iterator. %sourceOrNext is the input stack location (source to destructure from) or the next method.
SemanticsIf %iterator is an index: if %iterator is less than %sourceOrNext.length, reads the value from %sourceOrNext and increments the index, else sets %iterator to undefined and returns undefined. If %iterator is an actual iterator, calls %sourceOrNext as a next method and evaluates to the result value. When iteration is complete, sets %iterator to undefined as a signal that we're done.
if (typeof %iterator === 'undefined') {
return undefined;
}
if (typeof %iterator === 'number') {
if (%iterator >= %sourceOrNext.length) {
%iterator = undefined;
return undefined;
}
return %sourceOrNext[%iterator];
}
var iterResult = %sourceOrNext();
if (iterResult.done) {
%iterator = undefined;
return undefined;
}
return iterResult.value;

Effects | May read and write memory, may throw or execute.

IteratorClose

IteratorClose_
DescriptionCloses an iterator if it exists.
Example%0 = IteratorClose %iterator %ignoreInnerException
Arguments%iterator is the index or the iterator. %ignoreInnerException is a boolean literal.
SemanticsIf %iterator is an iterator, calls .return() on it to close it. Otherwise, this is a no-op. If .return() throws, the exception is ignored when %ignoreInnerException is true.
EffectsMay read and write memory, may throw or execute.

UnreachableInst

UnreachableInst_
DescriptionCrashes the VM (ifndef NDEBUG).
Example%0 = UnreachableInst
ArgumentsNone.
SemanticsCan be added to stubs and similar to verify that they are never executed.
EffectsMarked as reading/writing memory to avoid reordering.

Target Instructions

Some high-level IR instructions are lowered into a sequence of low-level machine instructions. In order to perform register allocation on these instructions we need to perform lowering, which is a form of instruction selection. The semantic of these instructions are identical to the semantic of the relevant target instructions.

HBCGetGlobalObjectInst

HBCGetGlobalObjectInst_
DescriptionObtain the "global" object
Example%0 = HBCGetGlobalObjectInst
ArgumentsNone.
SemanticsThe instruction returns a reference to the "global" object.
EffectsDoes not read or write to memory.

HBCCreateEnvironment

HBCCreateEnvironment_
DescriptionCreate a new function top-level environment.
Example%0 = HBCCreateEnvironment %desc
Arguments%desc describes the function's top-level environment.
SemanticsCreates the top-level environment for its function.
EffectsDoes not read or write to memory.

HBCCreateInnerEnvironment

HBCCreateInnerEnvironment_
DescriptionCreates a new environment with the given parent
Example%0 = HBCCreateInnerEnvironment %parent, %desc
Arguments%parent is the inner environment's parent environment, and %desc describes the environment that is being created.
SemanticsCreates a new inner environment within the given parent.
EffectsDoes not read or write to memory.

HBCCreateFunction

HBCCreateFunction_
DescriptionCreate a new closure capturing the specified environment and using the specified body
Example%0 = HBCCreateFunction %environment, %body,
Arguments%environment is the closure's environment. %body is the closure's body.
SemanticsThe instruction creates a new closure that may access the specified environment.
EffectsDoes not read or write to memory.

HBCCreateGenerator

CreateGenerator_
DescriptionConstructs a new Generator into the current scope from its code representation.
Example%0 = CreateGenerator %environment, %body,
Arguments%environment is the closure's environment, %body is the closure's body.
SemanticsThe instruction creates a new GeneratorInnerFunction access the environment and wraps it in a Generator.
EffectsDoes not read or write to memory.

HBCAllocObjectFromBufferInst

HBCAllocObjectFromBufferInst_
DescriptionAllocates a new JavaScript object on the heap, and initializes it with values from the object buffer.
Example%0 = HBCAllocObjectFromBufferInst %value0, %value1, ...
ArgumentsThe values are all literal values, with alternating keys and values. Non-literal values will be inserted into the array separately.
SemanticsThe instruction creates a new JavaScript object on the heap with an initial list of properties.
EffectsDoes not read or write to memory.

HBCCallNInst

HBCCallNInst_
DescriptionCalls a function with a fixed number of arguments (from 1 to 4, inclusive).
Example%0 = HBCCallNInst %callee, %this, %arg0, %arg1, %arg2
Arguments%callee is the function to execute. %this is a reference to the 'this' value. Arguments %arg0 ... %argN are the arguments passed to the function.
SemanticsThe instruction copies its arguments (starting from this) into the parameter-passing registers at the end of the frame, and passes the control to the callee, which must be of closure type. The arguments are mapped to the parameters. Unmapped parameters are initialized to 'undefined'.
EffectsMay read and write memory.