Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/jit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 76 kB image not shown  

Quelle  MIROps.yaml   Sprache: unbekannt

 
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# [SMDOC] MIR Opcodes
# =======================
# This file defines all MIR opcodes. It is parsed by GenerateMIRFiles.py
# at build time to create MIROpsGenerated.h. Each opcode consists of a
# name and a set of attributes that are described below. A few of the
# attributes below allow setting the value to "custom", meaning the
# method will be declared for the MIR op, but will need to be implemented
# in C++ (typically done in MIR.cpp). Unless marked as required, attributes
# are optional.
#
# name [required]
# ====
# Opcode name.
# Possible values:
#   - opcode string: used as the name for MIR opcode.
#
# gen_boilerplate
# ===============
# Used to decide to generate MIR boilerplate.
#   - true (default): auto generate boilerplate for this MIR opcode
#   - false: do not generate boilerplate for this MIR opcode
#
# operands
# ========
# A list of operands for the MIR op class constructor. Each operand is a
# MIR node. The operand kind is specified from the one of the kinds from
# the MIRType enum in IonTypes.h. The specified types for the
# operands will decide the type policy for the instruction.
#
# The naming of operands is how the NAMED_OPERANDS macro will define
# its operands.
#
# For example:
#   object: Object
#   id: Value
#   value: Object
#
# Will result in an instruction having the type policy of:
#   MixPolicy<ObjectPolicy<0>, BoxPolicy<1>, ObjectPolicy<2>>
# and a named operands definition that looks like the following:
#   NAMED_OPERANDS((0, object), (1, idValue), (2, value))
#
#   - attribute not specified (default): no code generated
#   - operand list: MIRTypes (See MIRType in jit/IonTypes.h)
#
# arguments
# =========
# A list of non-MIR node arguments to the MIR op class constructor
# that are passed along with the operands. The arguments require
# both a name and a full type signature for each item in the list.
#
# For example:
#   templateObject: JSObject*
#   initialHeap: gc::Heap
#
# For each argument a private variable declaration will be autogenerated
# in the MIR op class, as well as simple accessor for that variable. If
# the type of the variable is a GC pointer it will by automatically
# wrapped by CompilerGCPointer. The above arguments list will result in
# the following declarations and accessors:
#
#   CompilerGCPointer<JSObject*> templateObject_;
#   gc::Heap initialHeap_;
#
#   JSObject* templateObject() const { return templateObject_; }
#   gc::Heap initialHeap() const { return initialHeap_; }
#
#   - attribute not specified (default): no code generated
#   - operand list: argument names and their full type signature
#
# type_policy
# ============
# If this attribute is present, then the type policy for that opcode will be
# NoTypePolicy. This is used for opcode that should have no type policy.
#   - attribute not specified (default): no code generated, type policy
#     is based off of operands
#   - none: defines the type policy as opcode's NoTypePolicy
#
# result_type
# ===========
# Defines the result type of the MIR opcode.
#   - attribute not specified (default): no code is generated
#   - MIRType string: Will add a call to setResultType to the opcode constructor.
#                   This will set the MIR opcodes result type to whatever the
#                   specified MIRType is (See MIRType in jit/IonTypes.h).
#
# guard
# =====
# Set if the opcode is a guard instruction and is used for checks in optimizations
# such as range analysis and value numbering.
#   - attribute not specified (default): no code generated
#   - true: adds setGuard to opcode constructor
#
# movable
# =======
# Defines the movable MIR flag for movable instructions. This is used for knowing
# whether we can hoist an instruction.
#   - attribute not specified (default): no code generated
#   - true: adds setMovable call in opcode constructor
#
# folds_to
# ========
# The foldsTo method is used for determining if an instruction can be folded into
# simpler instruction or for constant folding, depending on its operands.
#   - attribute not specified (default): no code generated, no constants to fold
#   - custom: custom C++ implementation
#
# congruent_to
# ============
# Used by ValueNumbering to determine if two values are congruent.
#   - attribute not specified (default): no code generated, congruentTo(foo) returns
#     false
#   - if_operands_equal: congruentTo(foo) will return congruentIfOperandsEqual(foo)
#   - custom: custom C++ implementation
#
# alias_set
# =========
# Defines the getAliasSet function for a MIR op. The alias set is used for alias
# analysis. The default alias set is Any.
#   - attribute not specified (default): no code generated, alias set is Any
#   - none: this is the most common case, this is will set the alias set to None.
#   - custom: custom C++ implementation in MIR.cpp
#
# possibly_calls
# ==============
# Defines if a opcode can possibly call.
#   - attribute not specified (default): no code generated, opcode does not call
#   - true: possiblyCalls returns true
#   - custom: custom C++ implementation
#
# compute_range
# =============
# Computes and sets the range value for a MIR node, which is then used in range
# analysis.
#   - attribute not specified (default): no code generated, range is not set for node
#   - custom: custom C++ implementation in RangeAnalysis.cpp
#
# can_recover
# ===========
# Indicates whether this instruction can be recovered on bailout.
# Possible values:
#   - attribute not specified (default): no code generated, canRecoverOnBailout
#     returns false
#   - true: canRecoverOnBailout returns true
#   - custom: canRecoverOnBailout has a custom C++ implementation
# If the value is either 'true' or 'custom', writeRecoverData has a custom C++
# implementation.
#
# clone
# =====
# Allows cloning for that MIR op.
#   - attribute not specified (default): no code generated
#   - true: allows cloning
#
# can_consume_float32
# ===================
# Indicates whether this instruction's operands can have MIRType::Float32.
# Possible values:
#   - attribute not specified (default): no code generated
#   - true: canConsumeFloat32 returns true
#
# generate_lir
# ===================
# Controls whether to generate direct 1-1 mapping LIR instruction for the MIR op
# Possible values:
#   - attribute not specified (default): no code generated
#   - true: generates corresponding LIR classes in LIROpsGenerated.h
#
# lir_temps
# ===================
# Specifies the number of temporary virtual registers, LDefinitions, used by
# the corresponding LIR op in case generate_lir is true.
# Possible values:
#   - attribute not specified (default): number of temps is set to 0
#   - number: sets number of temps max 15
#

# TODO(no-TI): try to remove this instruction.
- name: Start

# Instruction marking on entrypoint for on-stack replacement.
# OSR may occur at loop headers (at JSOp::LoopHead).
# There is at most one MOsrEntry per MIRGraph.
- name: OsrEntry
  result_type: Pointer

- name: Nop
  alias_set: none
  clone: true

- name: LimitedTruncate
  gen_boilerplate: false

- name: IntPtrLimitedTruncate
  gen_boilerplate: false

- name: Int64LimitedTruncate
  gen_boilerplate: false

- name: Constant
  gen_boilerplate: false

- name: WasmNullConstant
  gen_boilerplate: false

- name: WasmFloatConstant
  gen_boilerplate: false

- name: Parameter
  gen_boilerplate: false

- name: Callee
  result_type: Object
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: IsConstructing
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: TableSwitch
  gen_boilerplate: false

- name: Goto
  gen_boilerplate: false

- name: Test
  gen_boilerplate: false

- name: Return
  gen_boilerplate: false

- name: Throw
  operands:
    value: Value
  alias_set: custom
  possibly_calls: true

- name: ThrowWithStack
  operands:
    value: Value
    stack: Value
  alias_set: custom
  possibly_calls: true

- name: NewArray
  gen_boilerplate: false

- name: NewArrayDynamicLength
  operands:
    length: Int32
  arguments:
    templateObject: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  # Need to throw if length is negative.
  guard: true
  # Throws if length is negative.
  alias_set: custom

- name: NewTypedArray
  gen_boilerplate: false

- name: NewTypedArrayDynamicLength
  operands:
    length: Int32
  arguments:
    templateObject: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  guard: true
  # Throws if length is negative.
  alias_set: custom

# Create a new TypedArray from an Array (or Array-like object) or a TypedArray.
- name: NewTypedArrayFromArray
  operands:
    array: Object
  arguments:
    templateObject: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  guard: true
  possibly_calls: true

# Create a new TypedArray from an ArrayBuffer (or SharedArrayBuffer).
- name: NewTypedArrayFromArrayBuffer
  operands:
    arrayBuffer: Object
    byteOffset: Value
    length: Value
  arguments:
    templateObject: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  guard: true
  possibly_calls: true

- name: NewMapObject
  arguments:
    templateObject: JSObject*
  result_type: Object
  possibly_calls: true

- name: NewSetObject
  arguments:
    templateObject: JSObject*
  result_type: Object
  possibly_calls: true

- name: NewMapObjectFromIterable
  operands:
    iterable: Value
  arguments:
    templateObject: JSObject*
  result_type: Object
  possibly_calls: true

- name: NewSetObjectFromIterable
  operands:
    iterable: Value
  arguments:
    templateObject: JSObject*
  result_type: Object
  possibly_calls: true

- name: NewObject
  gen_boilerplate: false

- name: NewPlainObject
  gen_boilerplate: false

- name: NewArrayObject
  gen_boilerplate: false

- name: NewIterator
  gen_boilerplate: false

- name: ObjectState
  gen_boilerplate: false

- name: ArrayState
  gen_boilerplate: false

- name: BindFunction
  gen_boilerplate: false

- name: NewBoundFunction
  arguments:
    templateObj: JSObject*
  result_type: Object
  alias_set: none

- name: BoundFunctionNumArgs
  operands:
    object: Object
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  # A bound function's state is immutable, so there is no
  # implicit dependency.
  alias_set: none

- name: GuardBoundFunctionIsConstructor
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  # The is-constructor flag is immutable for a bound function.
  alias_set: none

# Setting __proto__ in an object literal.
- name: MutateProto
  operands:
    object: Object
    value: Value
  result_type: None
  possibly_calls: true

- name: InitPropGetterSetter
  operands:
    object: Object
    value: Object
  arguments:
    name: PropertyName*

- name: InitElemGetterSetter
  operands:
    object: Object
    id: Value
    value: Object

- name: Call
  gen_boilerplate: false

- name: CallClassHook
  gen_boilerplate: false

- name: ApplyArgs
  gen_boilerplate: false

- name: ApplyArgsObj
  gen_boilerplate: false

- name: ApplyArray
  gen_boilerplate: false

- name: ConstructArgs
  gen_boilerplate: false

- name: ConstructArray
  gen_boilerplate: false

- name: Bail
  gen_boilerplate: false

- name: Unreachable
  gen_boilerplate: false

# This op serves as a way to force the encoding of a snapshot, even if there
# is no resume point using it.  This is useful to run MAssertRecoveredOnBailout
# assertions.
- name: EncodeSnapshot
  guard: true

- name: AssertRecoveredOnBailout
  gen_boilerplate: false

- name: AssertFloat32
  gen_boilerplate: false

- name: Compare
  gen_boilerplate: false

- name: SameValueDouble
  operands:
    left: Double
    right: Double
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom
  clone: true

- name: SameValue
  operands:
    left: Value
    right: Value
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom
  clone: true

- name: Box
  gen_boilerplate: false

- name: Unbox
  gen_boilerplate: false

- name: AssertRange
  gen_boilerplate: false

- name: AssertClass
  gen_boilerplate: false

- name: AssertShape
  gen_boilerplate: false

# Caller-side allocation of |this| for |new|:
# Constructs |this| when possible, else MagicValue(JS_IS_CONSTRUCTING).
- name: CreateThis
  operands:
    callee: Object
    newTarget: Object
  result_type: Value
  # Performs a property read from |newTarget| iff |newTarget| is a JSFunction
  # with an own |.prototype| property.
  alias_set: custom
  possibly_calls: true

- name: CreateArgumentsObject
  gen_boilerplate: false

- name: CreateInlinedArgumentsObject
  gen_boilerplate: false

- name: GetInlinedArgument
  gen_boilerplate: false

- name: GetInlinedArgumentHole
  gen_boilerplate: false

- name: GetArgumentsObjectArg
  operands:
    argsObject: Object
  arguments:
    argno: size_t
  result_type: Value
  congruent_to: custom
  alias_set: custom

- name: SetArgumentsObjectArg
  operands:
    argsObject: Object
    value: Value
  arguments:
    argno: size_t
  alias_set: custom

# Load |arguments[index]| from a mapped or unmapped arguments object. Bails out
# when any elements were overridden or deleted. Also bails out if the index is
# out of bounds.
- name: LoadArgumentsObjectArg
  operands:
    argsObject: Object
    index: Int32
  result_type: Value
  guard: true
  congruent_to: if_operands_equal
  alias_set: custom

# Load |arguments[index]| from a mapped or unmapped arguments object. Bails out
# when any elements were overridden or deleted. Returns undefined if the index is
# out of bounds.
- name: LoadArgumentsObjectArgHole
  operands:
    argsObject: Object
    index: Int32
  result_type: Value
  guard: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: InArgumentsObjectArg
  operands:
    argsObject: Object
    index: Int32
  result_type: Boolean
  guard: true
  congruent_to: if_operands_equal
  alias_set: custom

# Load |arguments.length|. Bails out if the length has been overriden.
- name: ArgumentsObjectLength
  operands:
    argsObject: Object
  result_type: Int32
  guard: true
  movable: true
  congruent_to: if_operands_equal
  # Even though the "length" property is lazily resolved, it acts similar to
  # a normal property load, so we can treat this operation like any other
  # property read.
  alias_set: custom

# Create an array from an arguments object.
- name: ArrayFromArgumentsObject
  operands:
    argsObject: Object
  arguments:
    shape: Shape*
  result_type: Object
  possibly_calls: true

# Guard that the given flags are not set on the arguments object.
- name: GuardArgumentsObjectFlags
  operands:
    argsObject: Object
  arguments:
    flags: uint32_t
  result_type: Object
  movable: true
  guard: true
  congruent_to: custom
  # The flags are packed with the length in a fixed private slot.
  alias_set: custom

- name: LoadScriptedProxyHandler
  operands:
    object: Object
  result_type: Object
  guard: true
  congruent_to: if_operands_equal
  alias_set: none

#ifdef JS_PUNBOX64
- name: CheckScriptedProxyGetResult
  operands:
    target: Value
    id: Value
    value: Value
  guard: true
  alias_set: custom
#endif

- name: IdToStringOrSymbol
  operands:
    idVal: Value
  result_type: Value
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom

# Given a MIRType::Value A and a MIRType::Object B:
# If the Value may be safely unboxed to an Object, return Object(A).
# Otherwise, return B.
# Used to implement return behavior for inlined constructors.
- name: ReturnFromCtor
  operands:
    value: Value
    object: Object
  result_type: Object
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none

- name: ToDouble
  gen_boilerplate: false

- name: ToFloat32
  gen_boilerplate: false

- name: ToFloat16
  gen_boilerplate: false

# Converts a uint32 to a double (coming from wasm).
- name: WasmUnsignedToDouble
  operands:
    def: Int32
  type_policy: none
  result_type: Double
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none

- name: WasmUnsignedToFloat32
  gen_boilerplate: false

- name: WrapInt64ToInt32
  gen_boilerplate: false

- name: ExtendInt32ToInt64
  gen_boilerplate: false

- name: WasmBuiltinTruncateToInt64
  gen_boilerplate: false

- name: WasmTruncateToInt64
  gen_boilerplate: false

- name: WasmTruncateToInt32
  gen_boilerplate: false

- name: WasmAnyRefFromJSValue
  operands:
    def: Value
  result_type: WasmAnyRef
  congruent_to: if_operands_equal
  alias_set: none

- name: WasmAnyRefFromJSObject
  operands:
    def: Object
  type_policy: none
  result_type: WasmAnyRef
  congruent_to: if_operands_equal
  alias_set: none

- name: WasmAnyRefFromJSString
  operands:
    def: String
  type_policy: none
  result_type: WasmAnyRef
  congruent_to: if_operands_equal
  alias_set: none

- name: WasmAnyRefIsJSString
  operands:
    input: WasmAnyRef
  type_policy: none
  result_type: Int32
  congruent_to: if_operands_equal
  alias_set: none
  movable: true
  clone: true

- name: WasmTrapIfAnyRefIsNotJSString
  operands:
    input: WasmAnyRef
  arguments:
    trap: wasm::Trap
    trapSiteDesc: wasm::TrapSiteDesc
  type_policy: none
  congruent_to: if_operands_equal
  alias_set: none
  guard: true
  clone: true

- name: WasmAnyRefJSStringLength
  operands:
    input: WasmAnyRef
  arguments:
    trap: wasm::Trap
    trapSiteDesc: wasm::TrapSiteDesc
  type_policy: none
  result_type: Int32
  congruent_to: if_operands_equal
  alias_set: none
  guard: true
  clone: true

- name: WasmNewI31Ref
  operands:
    input: Int32
  type_policy: none
  result_type: WasmAnyRef
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: WasmI31RefGet
  operands:
    input: WasmAnyRef
  arguments:
    wideningOp: wasm::FieldWideningOp
  type_policy: none
  result_type: Int32
  congruent_to: if_operands_equal
  alias_set: none

- name: Int32ToIntPtr
  gen_boilerplate: false

- name: NonNegativeIntPtrToInt32
  gen_boilerplate: false

- name: IntPtrToDouble
  gen_boilerplate: false

- name: AdjustDataViewLength
  gen_boilerplate: false

- name: Int64ToFloatingPoint
  gen_boilerplate: false

- name: BuiltinInt64ToFloatingPoint
  gen_boilerplate: false

- name: ToNumberInt32
  gen_boilerplate: false

- name: BooleanToInt32
  operands:
    input: Boolean
  result_type: Int32
  movable: true
  compute_range: custom
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none

- name: TruncateToInt32
  gen_boilerplate: false

- name: WasmBuiltinTruncateToInt32
  gen_boilerplate: false

- name: ToBigInt
  gen_boilerplate: false

- name: ToInt64
  gen_boilerplate: false

- name: TruncateBigIntToInt64
  gen_boilerplate: false

- name: Int64ToBigInt
  gen_boilerplate: false

- name: Int64ToIntPtr
  gen_boilerplate: false

- name: IntPtrToInt64
  gen_boilerplate: false

- name: ToString
  gen_boilerplate: false

- name: BitNot
  gen_boilerplate: false

- name: TypeOf
  gen_boilerplate: false

- name: TypeOfName
  operands:
    input: Int32
  result_type: String
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none
  can_recover: true

- name: TypeOfIs
  gen_boilerplate: false

- name: ToAsyncIter
  operands:
    iterator: Object
    nextMethod: Value
  result_type: Object

- name: ToPropertyKeyCache
  operands:
    input: Value
  result_type: Value

- name: BitAnd
  gen_boilerplate: false

- name: BitOr
  gen_boilerplate: false

- name: BitXor
  gen_boilerplate: false

- name: Lsh
  gen_boilerplate: false

- name: Rsh
  gen_boilerplate: false

- name: Ursh
  gen_boilerplate: false

- name: SignExtendInt32
  gen_boilerplate: false

- name: SignExtendInt64
  gen_boilerplate: false

- name: SignExtendIntPtr
  gen_boilerplate: false

- name: MinMax
  gen_boilerplate: false

- name: MinMaxArray
  gen_boilerplate: false

- name: Abs
  gen_boilerplate: false

- name: Clz
  gen_boilerplate: false

- name: Ctz
  gen_boilerplate: false

- name: Popcnt
  gen_boilerplate: false

- name: Sqrt
  gen_boilerplate: false

- name: CopySign
  gen_boilerplate: false

# Inline implementation of atan2 (arctangent of y/x).
- name: Atan2
  operands:
    y: Double
    x: Double
  result_type: Double
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true
  can_recover: true
  clone: true

- name: Hypot
  gen_boilerplate: false

- name: Pow
  gen_boilerplate: false

- name: PowHalf
  gen_boilerplate: false

- name: Random
  result_type: Double
  alias_set: custom
  possibly_calls: true
  compute_range: custom
  can_recover: custom
  clone: true

- name: Sign
  gen_boilerplate: false

- name: MathFunction
  gen_boilerplate: false

- name: Add
  gen_boilerplate: false

- name: Sub
  gen_boilerplate: false

- name: Mul
  gen_boilerplate: false

- name: Div
  gen_boilerplate: false

- name: WasmBuiltinDivI64
  gen_boilerplate: false

- name: Mod
  gen_boilerplate: false

- name: WasmBuiltinModD
  gen_boilerplate: false

- name: WasmBuiltinModI64
  gen_boilerplate: false

- name: BigIntAdd
  gen_boilerplate: false

- name: BigIntSub
  gen_boilerplate: false

- name: BigIntMul
  gen_boilerplate: false

- name: BigIntDiv
  gen_boilerplate: false

- name: BigIntMod
  gen_boilerplate: false

- name: BigIntPow
  gen_boilerplate: false

- name: BigIntBitAnd
  gen_boilerplate: false

- name: BigIntBitOr
  gen_boilerplate: false

- name: BigIntBitXor
  gen_boilerplate: false

- name: BigIntLsh
  gen_boilerplate: false

- name: BigIntRsh
  gen_boilerplate: false

- name: BigIntIncrement
  gen_boilerplate: false

- name: BigIntDecrement
  gen_boilerplate: false

- name: BigIntNegate
  gen_boilerplate: false

- name: BigIntBitNot
  gen_boilerplate: false

- name: BigIntToIntPtr
  operands:
    input: BigInt
  result_type: IntPtr
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom
  can_recover: true
  clone: true

- name: IntPtrToBigInt
  operands:
    input: IntPtr
  result_type: BigInt
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom
  can_recover: true
  clone: true

- name: BigIntPtrAdd
  gen_boilerplate: false

- name: BigIntPtrSub
  gen_boilerplate: false

- name: BigIntPtrMul
  gen_boilerplate: false

- name: BigIntPtrDiv
  gen_boilerplate: false

- name: BigIntPtrMod
  gen_boilerplate: false

- name: BigIntPtrPow
  gen_boilerplate: false

- name: BigIntPtrBitAnd
  gen_boilerplate: false

- name: BigIntPtrBitOr
  gen_boilerplate: false

- name: BigIntPtrBitXor
  gen_boilerplate: false

- name: BigIntPtrLsh
  gen_boilerplate: false

- name: BigIntPtrRsh
  gen_boilerplate: false

- name: BigIntPtrBitNot
  gen_boilerplate: false

- name: Int32ToStringWithBase
  operands:
    input: Int32
    base: Int32
  arguments:
    lowerCase: bool
  result_type: String
  movable: true
  congruent_to: custom
  alias_set: none

- name: NumberParseInt
  operands:
    string: String
    radix: Int32
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: DoubleParseInt
  operands:
    number: Double
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: Concat
  gen_boilerplate: false

- name: LinearizeString
  operands:
    string: String
  result_type: String
  movable: true
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none

- name: LinearizeForCharAccess
  operands:
    string: String
    index: Int32
  result_type: String
  movable: true
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none

- name: LinearizeForCodePointAccess
  operands:
    string: String
    index: Int32
  result_type: String
  movable: true
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none

- name: ToRelativeStringIndex
  operands:
    index: Int32
    length: Int32
  result_type: Int32
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none

- name: CharCodeAt
  operands:
    string: String
    index: Int32
  result_type: Int32
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none
  compute_range: custom
  can_recover: true
  clone: true

# Similar to CharCodeAt, but returns a negative value on out-of-bounds access.
- name: CharCodeAtOrNegative
  operands:
    string: String
    index: Int32
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none

- name: CodePointAt
  operands:
    string: String
    index: Int32
  result_type: Int32
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none
  compute_range: custom
  clone: true

# Similar to CodePointAt, but returns a negative value on out-of-bounds access.
- name: CodePointAtOrNegative
  operands:
    string: String
    index: Int32
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  # Strings are immutable, so there is no implicit dependency.
  alias_set: none

# Return the input if non-negative, otherwise return NaN.
- name: NegativeToNaN
  operands:
    input: Int32
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

# Return the input if non-negative, otherwise return undefined.
- name: NegativeToUndefined
  operands:
    input: Int32
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: FromCharCode
  operands:
    code: Int32
  result_type: String
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  can_recover: true
  clone: true

# Similar to FromCharCode, but returns the empty string if the input is negative.
- name: FromCharCodeEmptyIfNegative
  operands:
    code: Int32
  result_type: String
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  can_recover: true
  clone: true

# Similar to FromCharCode, but returns the |undefined| if the input is negative.
- name: FromCharCodeUndefinedIfNegative
  operands:
    code: Int32
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: FromCodePoint
  operands:
    codePoint: Int32
  result_type: String
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  clone: true

- name: StringIncludes
  operands:
    string: String
    searchString: String
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: StringIndexOf
  operands:
    string: String
    searchString: String
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: StringLastIndexOf
  operands:
    string: String
    searchString: String
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: StringStartsWith
  operands:
    string: String
    searchString: String
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: StringEndsWith
  operands:
    string: String
    searchString: String
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  possibly_calls: true

- name: StringConvertCase
  gen_boilerplate: false

- name: CharCodeConvertCase
  gen_boilerplate: false

- name: StringTrimStartIndex
  operands:
    string: String
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: StringTrimEndIndex
  operands:
    string: String
    start: Int32
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: StringSplit
  operands:
    string: String
    separator: String
  result_type: Object
  possibly_calls: true
  # Although this instruction returns a new array, we don't have to mark
  # it as store instruction, see also MNewArray.
  alias_set: none
  can_recover: true

- name: BoxNonStrictThis
  operands:
    def: Value
  arguments:
    globalThis: JSObject*
  result_type: Object
  folds_to: custom
  possibly_calls: true
  # This instruction can allocate a new object for wrapped primitives, but
  # has no effect on existing objects.
  alias_set: none

- name: ImplicitThis
  operands:
    env: Object
  result_type: Value

- name: Phi
  gen_boilerplate: false

- name: Beta
  gen_boilerplate: false

- name: NaNToZero
  gen_boilerplate: false

- name: OsrValue
  gen_boilerplate: false

- name: OsrEnvironmentChain
  gen_boilerplate: false

- name: OsrArgumentsObject
  gen_boilerplate: false

- name: OsrReturnValue
  gen_boilerplate: false

- name: BinaryCache
  gen_boilerplate: false

- name: UnaryCache
  operands:
    input: Value
  result_type: Value

# Checks whether we need to fire the interrupt handler.
- name: CheckOverRecursed
  guard: true
  alias_set: none


# Check whether we need to fire the interrupt handler.
- name: InterruptCheck
  guard: true
  alias_set: none

- name: WasmInterruptCheck
  gen_boilerplate: false

- name: WasmTrap
  gen_boilerplate: false

# Trap if the given ref is null
- name: WasmTrapIfNull
  operands:
    ref: WasmAnyRef
  arguments:
    trap: wasm::Trap
    trapSiteDesc: wasm::TrapSiteDesc
  guard: true
  type_policy: none
  result_type: None

- name: LexicalCheck
  gen_boilerplate: false

# Unconditionally throw an uninitialized let error.
- name: ThrowRuntimeLexicalError
  arguments:
    errorNumber: unsigned
  result_type: None
  guard: true
  alias_set: custom

- name: ThrowMsg
  gen_boilerplate: false

# In the prologues of global and eval scripts, check for redeclarations and
# initialize bindings.
- name: GlobalDeclInstantiation
  guard: true

- name: RegExp
  arguments:
    source: RegExpObject*
    hasShared: bool
  result_type: Object
  possibly_calls: true
  alias_set: none

- name: RegExpMatcher
  operands:
    regexp: Object
    string: String
    lastIndex: Int32
  result_type: Value
  possibly_calls: true

# Note: this instruction writes to cx->regExpSearcherLastLimit.
# See also MRegExpSearcherLastLimit.
- name: RegExpSearcher
  operands:
    regexp: Object
    string: String
    lastIndex: Int32
  result_type: Int32
  possibly_calls: true

# This instruction loads cx->regExpSearcherLastLimit. We don't have a
# specialized alias set for this so just use the default alias set similar to
# the MRegExpSearcher instruction that precedes it.
- name: RegExpSearcherLastLimit
  operands:
  result_type: Int32

- name: RegExpExecMatch
  operands:
    regexp: Object
    string: String
  result_type: Value
  possibly_calls: true

- name: RegExpExecTest
  operands:
    regexp: Object
    string: String
  result_type: Boolean
  possibly_calls: true

- name: RegExpHasCaptureGroups
  operands:
    regexp: Object
    input: String
  result_type: Boolean
  possibly_calls: true

- name: RegExpPrototypeOptimizable
  operands:
    object: Object
  result_type: Boolean
  alias_set: none

- name: RegExpInstanceOptimizable
  operands:
    object: Object
    proto: Object
  result_type: Boolean
  alias_set: none

- name: GetFirstDollarIndex
  gen_boilerplate: false

- name: StringReplace
  gen_boilerplate: false

- name: Substr
  operands:
    string: String
    begin: Int32
    length: Int32
  result_type: String
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none
  can_recover: true

- name: ModuleMetadata
  arguments:
    module: JSObject*
  result_type: Object

- name: DynamicImport
  operands:
    specifier: Value
    options: Value
  result_type: Object

- name: Lambda
  gen_boilerplate: false

- name: FunctionWithProto
  gen_boilerplate: false

- name: SetFunName
  operands:
    fun: Object
    name: Value
  arguments:
    prefixKind: uint8_t
  result_type: None
  possibly_calls: true

# Returns obj->slots.
- name: Slots
  operands:
    object: Object
  result_type: Slots
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  might_alias: custom
  clone: true

# Returns obj->elements.
- name: Elements
  operands:
    object: Object
  result_type: Elements
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  clone: true

# Load the initialized length from an elements header.
- name: InitializedLength
  operands:
    elements: Elements
  type_policy: none
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  compute_range: custom
  clone: true

- name: SetInitializedLength
  operands:
    elements: Elements
    index: Int32
  type_policy: none
  alias_set: custom
  clone: true

# Load the array length from an elements header.
- name: ArrayLength
  operands:
    elements: Elements
  type_policy: none
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: custom
  compute_range: custom
  clone: true

# Store to the length in an elements header. Note the input is an *index*, one
# less than the desired length.
- name: SetArrayLength
  operands:
    elements: Elements
    index: Int32
  type_policy: none
  alias_set: custom

# Load the function length. Bails for functions with lazy scripts or a
# resolved "length" property.
- name: FunctionLength
  operands:
    function: Object
  result_type: Int32
  guard: true
  congruent_to: if_operands_equal
  # Even though the "length" property is lazily resolved, it acts similar to
  # a normal property load, so we can treat this operation like any other
  # property read.
  alias_set: custom

# Load the function name. Bails for bound functions when the bound function
# name prefix isn't present or functions with a resolved "name" property.
- name: FunctionName
  operands:
    function: Object
  result_type: String
  guard: true
  congruent_to: if_operands_equal
  # Even though the "name" property is lazily resolved, it acts similar to
  # a normal property load, so we can treat this operation like any other
  # property read.
  alias_set: custom

- name: GetNextEntryForIterator
  gen_boilerplate: false

# Read the byte length of an array buffer as IntPtr.
- name: ArrayBufferByteLength
  operands:
    object: Object
  result_type: IntPtr
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Read the length of an array buffer view.
- name: ArrayBufferViewLength
  operands:
    object: Object
  result_type: IntPtr
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  compute_range: custom

- name: ArrayBufferViewByteOffset
  operands:
    object: Object
  result_type: IntPtr
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  compute_range: custom

# Read the length of an array buffer view.
- name: ArrayBufferViewElements
  operands:
    object: Object
  result_type: Elements
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  clone: true

# Implements the TypedArrayByteOffset intrinsic for resizable typed arrays,
# which calls TypedArrayObject::byteOffsetMaybeOutOfBounds().
- name: ResizableTypedArrayByteOffsetMaybeOutOfBounds
  operands:
    object: Object
  result_type: IntPtr
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom
  compute_range: custom

# Read the length of a resizable typed array.
- name: ResizableTypedArrayLength
  operands:
    object: Object
  arguments:
    requiresMemoryBarrier: MemoryBarrierRequirement
  result_type: IntPtr
  # Not removable or movable when a barrier is needed.
  guard: true
  movable: false
  congruent_to: custom
  alias_set: custom
  compute_range: custom

# Read the byteLength of a resizable dataview.
- name: ResizableDataViewByteLength
  operands:
    object: Object
  arguments:
    requiresMemoryBarrier: MemoryBarrierRequirement
  result_type: IntPtr
  # Not removable or movable when a barrier is needed.
  guard: true
  movable: false
  congruent_to: custom
  alias_set: custom
  compute_range: custom

# Read the byte length of a growable shared array buffer as IntPtr.
- name: GrowableSharedArrayBufferByteLength
  operands:
    object: Object
  result_type: IntPtr
  guard: true
  movable: false
  alias_set: custom

# Return the element size of a typed array.
- name: TypedArrayElementSize
  operands:
    object: Object
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  # Class is immutable. See also MHasClass.
  alias_set: none
  compute_range: custom

# Guard an ArrayBufferView has an attached ArrayBuffer.
- name: GuardHasAttachedArrayBuffer
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Guard a resizable typed array is in-bounds.
- name: GuardResizableArrayBufferViewInBounds
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Guard a resizable typed array is in-bounds or detached.
- name: GuardResizableArrayBufferViewInBoundsOrDetached
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GuardNumberToIntPtrIndex
  gen_boilerplate: false

- name: KeepAliveObject
  operands:
    object: Object
  result_type: None
  guard: true

- name: DebugEnterGCUnsafeRegion
  result_type: None
  guard: true
  alias_set: none

- name: DebugLeaveGCUnsafeRegion
  result_type: None
  guard: true
  alias_set: none

- name: Not
  gen_boilerplate: false

- name: BoundsCheck
  gen_boilerplate: false

- name: BoundsCheckLower
  gen_boilerplate: false

- name: SpectreMaskIndex
  gen_boilerplate: false

- name: LoadElement
  gen_boilerplate: false

- name: LoadElementAndUnbox
  gen_boilerplate: false

- name: LoadElementHole
  gen_boilerplate: false

- name: StoreElement
  gen_boilerplate: false

- name: StoreHoleValueElement
  gen_boilerplate: false

- name: StoreElementHole
  gen_boilerplate: false

- name: ArrayPopShift
  gen_boilerplate: false

# Array.prototype.push on a dense array. Returns the new array length.
- name: ArrayPush
  operands:
    object: Object
    value: Value
  result_type: Int32
  alias_set: custom
  compute_range: custom
  clone: true

# Array.prototype.slice on a dense array.
- name: ArraySlice
  operands:
    object: Object
    begin: Int32
    end: Int32
  arguments:
    templateObj: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  possibly_calls: true

# Array.prototype.slice on an arguments object.
- name: ArgumentsSlice
  operands:
    object: Object
    begin: Int32
    end: Int32
  arguments:
    templateObj: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  possibly_calls: true

# Array.prototype.slice on an arguments object.
- name: FrameArgumentsSlice
  operands:
    begin: Int32
    count: Int32
  arguments:
    templateObj: JSObject*
    initialHeap: gc::Heap
  result_type: Object
  alias_set: none
  possibly_calls: true

# Array.prototype.slice on an inlined arguments object.
- name: InlineArgumentsSlice
  gen_boilerplate: false

- name: NormalizeSliceTerm
  operands:
    value: Int32
    length: Int32
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none
  folds_to: custom

# MArrayJoin doesn't override |getAliasSet()|, because Array.prototype.join
# might coerce the elements of the Array to strings. This coercion might
# cause the evaluation of JavaScript code.
- name: ArrayJoin
  operands:
    array: Object
    sep: String
  result_type: String
  possibly_calls: true
  folds_to: custom
  # MArrayJoin doesn't override |getAliasSet()|, because Array.prototype.join
  # might coerce the elements of the Array to strings. This coercion might
  # cause the evaluation of JavaScript code.

# Object.prototype.keys. Used to elide it when possible.
- name: ObjectKeys
  operands:
    object: Object
  result_type: Object

  # We can recover Object.keys on bailout as long as the object is not escaped
  # or that the object is not mutated by any aliased calls in-between the
  # instruction and the recovered location, as the recovered keys array might be
  # different.
  can_recover: custom

# Used to fold Object.keys(obj).length into a single operation.
#
# This should not be used with a Proxy, as proxies can have a user-defined
# `ownKeys` function which can have arbitrary outputs.
#
# This MIR node is created by folding an MObjectKeys with an MArrayLength, as
# part of MArrayLength::foldsTo.
- name: ObjectKeysLength
  operands:
    object: Object
  result_type: Int32
  movable: false
  congruent_to: if_operands_equal
  alias_set: custom
  clone: true

- name: LoadUnboxedScalar
  gen_boilerplate: false

- name: LoadDataViewElement
  gen_boilerplate: false

- name: LoadTypedArrayElementHole
  gen_boilerplate: false

- name: StoreUnboxedScalar
  gen_boilerplate: false

- name: StoreDataViewElement
  gen_boilerplate: false

- name: StoreTypedArrayElementHole
  gen_boilerplate: false

- name: EffectiveAddress
  gen_boilerplate: false

- name: ClampToUint8
  gen_boilerplate: false

- name: LoadFixedSlot
  gen_boilerplate: false

- name: LoadFixedSlotAndUnbox
  gen_boilerplate: false

- name: LoadDynamicSlotAndUnbox
  gen_boilerplate: false

- name: StoreFixedSlot
  gen_boilerplate: false

- name: GetPropertyCache
  gen_boilerplate: false

- name: HomeObjectSuperBase
  operands:
    homeObject: Object
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GetPropSuperCache
  gen_boilerplate: false

- name: BindNameCache
  operands:
    envChain: Object
  result_type: Object

- name: CallBindVar
  operands:
    environmentChain: Object
  result_type: Object
  movable: true
  congruent_to: custom
  alias_set: none

- name: GuardShape
  operands:
    object: Object
  arguments:
    shape: Shape*
  result_type: Object
  guard: true
  movable: true
  congruent_to: custom
  alias_set: custom
  might_alias: custom

- name: GuardFuse
  arguments:
    fuseIndex: RealmFuses::FuseIndex
  result_type: None
  guard: true
  movable: true
  congruent_to: custom
  alias_set: custom

- name: GuardMultipleShapes
  operands:
    object: Object
    shapeList: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GuardProto
  gen_boilerplate: false

- name: GuardNullProto
  gen_boilerplate: false

# Guard the object is a native object.
- name: GuardIsNativeObject
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardGlobalGeneration
  arguments:
   expected: uint32_t
   generationAddr: const void*
  result_type: None
  guard: true
  movable: true
  alias_set: custom
  congruent_to: custom

- name: GuardIsProxy
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardIsNotDOMProxy
  operands:
    proxy: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardIsNotProxy
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: ProxyGet
  operands:
    proxy: Object
  arguments:
    id: jsid
  result_type: Value
  possibly_calls: true

- name: ProxyGetByValue
  operands:
    proxy: Object
    idVal: Value
  result_type: Value
  possibly_calls: true

- name: ProxyHasProp
  operands:
    proxy: Object
    idVal: Value
  arguments:
    hasOwn: bool
  result_type: Boolean
  possibly_calls: true

- name: ProxySet
  operands:
    proxy: Object
    rhs: Value
  arguments:
    id: jsid
    strict: bool
  possibly_calls: true

- name: ProxySetByValue
  operands:
    proxy: Object
    idVal: Value
    rhs: Value
  arguments:
    strict: bool
  possibly_calls: true

- name: CallSetArrayLength
  operands:
    obj: Object
    rhs: Value
  arguments:
    strict: bool
  possibly_calls: true

- name: MegamorphicLoadSlot
  operands:
    object: Object
  arguments:
    name: PropertyKey
  result_type: Value
  # Bails when non-native or accessor properties are encountered, so we can't
  # DCE this instruction.
  guard: true
  possibly_calls: true
  congruent_to: custom
  alias_set: custom

- name: MegamorphicLoadSlotPermissive
  operands:
    object: Object
  arguments:
    name: PropertyKey
  result_type: Value
  guard: true
  possibly_calls: true

- name: MegamorphicLoadSlotByValue
  operands:
    object: Object
    idVal: Value
  result_type: Value
  # Bails when non-native or accessor properties are encountered, so we can't
  # DCE this instruction.
  guard: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: custom
  possibly_calls: true

- name: MegamorphicLoadSlotByValuePermissive
  operands:
    object: Object
    idVal: Value
  result_type: Value
  guard: true
  folds_to: custom
  possibly_calls: true

- name: MegamorphicStoreSlot
  operands:
    object: Object
    rhs: Value
  arguments:
    name: PropertyKey
    strict: bool
  possibly_calls: true

- name: MegamorphicHasProp
  operands:
    object: Object
    idVal: Value
  arguments:
    hasOwn: bool
  result_type: Boolean
  # Bails when non-native or accessor properties are encountered, so we can't
  # DCE this instruction.
  guard: true
  congruent_to: custom
  alias_set: custom
  possibly_calls: true

- name: SmallObjectVariableKeyHasProp
  operands:
    idStr: String
  arguments:
    shape: Shape*
  congruent_to: custom
  result_type: Boolean
  alias_set: custom

- name: GuardIsNotArrayBufferMaybeShared
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardIsTypedArray
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardIsFixedLengthTypedArray
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardIsResizableTypedArray
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: GuardHasProxyHandler
  operands:
    object: Object
  arguments:
    handler: const void*
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

# Loads a specific JSObject* that was originally nursery-allocated.
# See also WarpObjectField.
- name: NurseryObject
  arguments:
    # Index in the Vector of objects stored in the WarpSnapshot.
    nurseryIndex: uint32_t
  result_type: Object
  movable: true
  congruent_to: custom
  alias_set: none

- name: GuardValue
  gen_boilerplate: false

- name: GuardNullOrUndefined
  operands:
    value: Value
  result_type: Value
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardIsNotObject
  operands:
    value: Value
  result_type: Value
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardFunctionFlags
  gen_boilerplate: false

- name: GuardFunctionIsNonBuiltinCtor
  operands:
    function: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GuardFunctionKind
  operands:
    function: Object
  arguments:
    expected: FunctionFlags::FunctionKind
    bailOnEquality: bool
  result_type: Object
  guard: true
  movable: true
  congruent_to: custom
  alias_set: custom

- name: GuardFunctionScript
  operands:
    function: Object
  arguments:
    expected: BaseScript*
    nargs: uint16_t
    flags: FunctionFlags
  result_type: Object
  guard: true
  movable: true
  folds_to: custom
  congruent_to: custom
  # A JSFunction's BaseScript pointer is immutable. Relazification of
  # self-hosted functions is an exception to this, but we don't use this
  # guard for self-hosted functions.
  alias_set: custom

- name: GuardObjectIdentity
  gen_boilerplate: false

- name: GuardSpecificFunction
  gen_boilerplate: false

- name: GuardSpecificAtom
  operands:
    str: String
  arguments:
    atom: JSAtom*
  result_type: String
  guard: true
  movable: true
  congruent_to: custom
  folds_to: custom
  alias_set: none

- name: GuardSpecificSymbol
  gen_boilerplate: false

- name: GuardSpecificInt32
  operands:
    num: Int32
  arguments:
    expected: int32_t
  result_type: Int32
  guard: true
  movable: true
  folds_to: custom
  alias_set: none

- name: GuardStringToIndex
  operands:
    string: String
  result_type: Int32
  # Mark as guard because this instruction must not be eliminated. For
  # example, if the string is not an index the operation could change from a
  # typed array load to a getter call.
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardStringToInt32
  operands:
    string: String
  result_type: Int32
  # Mark as guard to prevent the issue described in MGuardStringToIndex's
  # constructor.
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardStringToDouble
  operands:
    string: String
  result_type: Double
  # Mark as guard to prevent the issue described in MGuardStringToIndex's
  # constructor.
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardNoDenseElements
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  alias_set: custom

- name: GuardTagNotEqual
  gen_boilerplate: false

- name: LoadDynamicSlot
  gen_boilerplate: false

# Inline call to access a function's environment (scope chain).
- name: FunctionEnvironment
  operands:
    function: Object
  result_type: Object
  movable: true
  folds_to: custom
  # A function's environment is fixed.
  alias_set: none

# Allocate a new BlockLexicalEnvironmentObject.
- name: NewLexicalEnvironmentObject
  operands:
    templateObj: Object
  result_type: Object
  alias_set: none

# Allocate a new ClassBodyEnvironmentObject.
- name: NewClassBodyEnvironmentObject
  operands:
    templateObj: Object
  result_type: Object
  alias_set: none

- name: NewVarEnvironmentObject
  operands:
    templateObj: Object
  result_type: Object
  alias_set: none

- name: HomeObject
  operands:
    function: Object
  result_type: Object
  movable: true
  # A function's [[HomeObject]] is fixed.
  alias_set: none

- name: AddAndStoreSlot
  gen_boilerplate: false

- name: AllocateAndStoreSlot
  operands:
    object: Object
    value: Value
  arguments:
    slotOffset: uint32_t
    shape: Shape*
    numNewSlots: uint32_t
  possibly_calls: true
  alias_set: custom

- name: AddSlotAndCallAddPropHook
  operands:
    object: Object
    value: Value
  arguments:
    shape: Shape*
  possibly_calls: true

- name: StoreDynamicSlot
  gen_boilerplate: false

- name: GetNameCache
  operands:
    envObj: Object
  result_type: Value

- name: CallGetIntrinsicValue
  arguments:
    name: PropertyName*
  result_type: Value
  possibly_calls: true

- name: DeleteProperty
  operands:
    value: Value
  arguments:
    name: PropertyName*
    strict: bool
  result_type: Boolean

- name: DeleteElement
  operands:
    value: Value
    index: Value
  arguments:
    strict: bool
  result_type: Boolean

- name: SetPropertyCache
  gen_boilerplate: false

- name: MegamorphicSetElement
  gen_boilerplate: false

- name: SetDOMProperty
  gen_boilerplate: false

- name: GetDOMProperty
  gen_boilerplate: false

- name: GetDOMMember
  gen_boilerplate: false

- name: ObjectToIterator
  gen_boilerplate: false

- name: ValueToIterator
  operands:
    value: Value
  result_type: Object

- name: IteratorHasIndices
  operands:
    object: Object
    iterator: Object
  result_type: Boolean
  alias_set: custom

- name: LoadSlotByIteratorIndex
  operands:
    object: Object
    iterator: Object # TODO: add MIRType::NativeIterator?
  result_type: Value
  alias_set: custom

- name: StoreSlotByIteratorIndex
  operands:
    object: Object
    iterator: Object
    value: Value
  alias_set: custom

# Load the private value expando from a DOM proxy. The target is stored in the
# proxy object's private slot.
# This is either an UndefinedValue (no expando), ObjectValue (the expando
# object), or PrivateValue(ExpandoAndGeneration*).
- name: LoadDOMExpandoValue
  operands:
    proxy: Object
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: LoadDOMExpandoValueGuardGeneration
  gen_boilerplate: false

- name: LoadDOMExpandoValueIgnoreGeneration
  operands:
    proxy: Object
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Takes an expando Value as input, then guards it's either UndefinedValue or
# an object with the expected shape.
- name: GuardDOMExpandoMissingOrGuardShape
  operands:
    expando: Value
  arguments:
    shape: Shape*
  result_type: Value
  guard: true
  movable: true
  congruent_to: custom
  alias_set: custom

- name: StringLength
  operands:
    string: String
  result_type: Int32
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  # The string |length| property is immutable, so there is no
  # implicit dependency.
  alias_set: none
  compute_range: custom
  can_recover: true
  clone: true

- name: Floor
  gen_boilerplate: false

- name: Ceil
  gen_boilerplate: false

- name: Round
  gen_boilerplate: false

- name: Trunc
  gen_boilerplate: false

- name: NearbyInt
  gen_boilerplate: false

- name: GetIteratorCache
  gen_boilerplate: false

- name: OptimizeSpreadCallCache
  operands:
    value: Value
  result_type: Value

- name: IteratorMore
  operands:
    iterator: Object
  result_type: Value

- name: IsNoIter
  operands:
    def: Object
  result_type: Boolean
  type_policy: none
  movable : true
  alias_set: none

- name: IteratorEnd
  operands:
    iterator: Object

- name: CloseIterCache
  operands:
    iter: Object
  arguments:
    completionKind: uint8_t
  possibly_calls: true

- name: OptimizeGetIteratorCache
  operands:
    value: Value
  result_type: Boolean

- name: InCache
  gen_boilerplate: false

- name: InArray
  gen_boilerplate: false

- name: GuardElementNotHole
  gen_boilerplate: false

- name: NewPrivateName
  arguments:
    name: JSAtom*
  result_type: Symbol
  possibly_calls: true

- name: CheckPrivateFieldCache
  gen_boilerplate: false

- name: HasOwnCache
  gen_boilerplate: false

- name: InstanceOf
  gen_boilerplate: false

# Implementation for instanceof operator with unknown rhs.
- name: InstanceOfCache
  operands:
    obj: Value
    proto: Object
  result_type: Boolean

- name: ArgumentsLength
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  # Arguments |length| cannot be mutated by Ion Code.
  alias_set: none
  compute_range: custom
  can_recover: true

# This MIR instruction is used to get an argument from the actual arguments.
- name: GetFrameArgument
  operands:
    index: Int32
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  # This instruction is never aliased, because ops like JSOp::SetArg don't
  # write to the argument frames. We create an arguments object in that case.
  alias_set: none

# This MIR instruction is used to get an argument from the actual arguments.
# Returns undefined if |index| is larger-or-equals to |length|. Bails out if
# |index| is negative.
- name: GetFrameArgumentHole
  operands:
    index: Int32
    length: Int32
  result_type: Value
  guard: true
  movable: true
  congruent_to: if_operands_equal
  # This instruction is never aliased, because ops like JSOp::SetArg don't
  # write to the argument frames. We create an arguments object in that case.
  alias_set: none

- name: NewTarget
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: Rest
  operands:
    numActuals: Int32
  arguments:
    numFormals: unsigned
    shape: Shape*
  result_type: Object
  possibly_calls: true
  alias_set: none
  can_recover: true

- name: PostWriteBarrier
  gen_boilerplate: false

- name: PostWriteElementBarrier
  gen_boilerplate: false

- name: AssertCanElidePostWriteBarrier
  operands:
    object: Object
    value: Value
  result_type: None
  guard: true
  alias_set: none

- name: NewNamedLambdaObject
  arguments:
    templateObj: NamedLambdaObject*
  result_type: Object
  alias_set: none

- name: NewCallObject
  gen_boilerplate: false

- name: NewStringObject
  gen_boilerplate: false

- name: IsCallable
  gen_boilerplate: false

- name: IsConstructor
  operands:
    object: Object
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: IsCrossRealmArrayConstructor
  operands:
    object: Object
  result_type: Boolean
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

- name: IsObject
  operands:
    object: Value
  result_type: Boolean
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none

- name: IsNullOrUndefined
  operands:
    value: Value
  result_type: Boolean
  movable: true
  folds_to: custom
  congruent_to: if_operands_equal
  alias_set: none
  type_policy: none
  can_consume_float32: true

- name: HasClass
  gen_boilerplate: false

- name: GuardToClass
  gen_boilerplate: false

- name: GuardToEitherClass
  gen_boilerplate: false

- name: GuardToFunction
  gen_boilerplate: false

- name: IsArray
  gen_boilerplate: false

- name: IsTypedArray
  gen_boilerplate: false

- name: ObjectClassToString
  operands:
    object: Object
  result_type: String
  guard: true
  movable: true
  congruent_to: if_operands_equal
  possibly_calls: true
  # Tests @@toStringTag is neither present on this object nor on any object
  # of the prototype chain.
  alias_set: custom

- name: CheckReturn
  operands:
    returnValue: Value
    thisValue: Value
  result_type: Value
  guard: true
  folds_to: custom
  alias_set: custom

- name: CheckThis
  operands:
    thisValue: Value
  result_type: Value
  guard: true
  folds_to: custom
  alias_set: custom

- name: AsyncResolve
  operands:
    generator: Object
    value: Value
  result_type: Object

- name: AsyncReject
  operands:
    generator: Object
    reason: Value
    stack: Value
  result_type: Object

# Returns from this function to the previous caller; this looks like a regular
# Unary instruction and is used to lie to the MIR generator about suspending
# ops like Yield/Await, which are emitted like returns, but MIR-Build like
# regular instructions.
- name: GeneratorReturn
  operands:
    input: Value
  guard: true
  alias_set: none

- name: AsyncAwait
  operands:
    value: Value
    generator: Object
  result_type: Object

- name: CheckThisReinit
  operands:
    thisValue: Value
  result_type: Value
  guard: true
  folds_to: custom
  alias_set: custom

- name: Generator
  gen_boilerplate: false

- name: CanSkipAwait
  operands:
    value: Value
  result_type: Boolean

- name: MaybeExtractAwaitValue
  gen_boilerplate: false

- name: IncrementWarmUpCounter
  arguments:
    script: JSScript*
  alias_set: none

- name: AtomicIsLockFree
  gen_boilerplate: false

- name: AtomicPause
  guard: true
  movable: false
  alias_set: none
  generate_lir: true

- name: CompareExchangeTypedArrayElement
  gen_boilerplate: false

- name: AtomicExchangeTypedArrayElement
  gen_boilerplate: false

- name: AtomicTypedArrayElementBinop
  gen_boilerplate: false

- name: Debugger
  gen_boilerplate: false

- name: CheckIsObj
  operands:
    value: Value
  arguments:
    checkKind: uint8_t
  result_type: Object
  guard: true
  folds_to: custom
  alias_set: custom

- name: CheckObjCoercible
  operands:
    checkValue: Value
  result_type: Value
  guard: true
  folds_to: custom
  # Throws on null or undefined.
  alias_set: custom

- name: CheckClassHeritage
  operands:
    heritage: Value
  result_type: Value
  guard: true

- name: DebugCheckSelfHosted
  operands:
    checkValue: Value
  result_type: Value
  guard: true

- name: IsPackedArray
  operands:
    object: Object
  result_type: Boolean
  movable: true
  alias_set: custom

- name: GuardArrayIsPacked
  operands:
    array: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GetPrototypeOf
  operands:
    target: Object
  result_type: Value
  # May throw if target is a proxy.
  guard: true

- name: ObjectWithProto
  operands:
    prototype: Value
  result_type: Object
  # May throw if prototype is neither an object nor null.
  guard: true
  possibly_calls: true

- name: ObjectStaticProto
  gen_boilerplate: false

# This is basically just a limited case of Constant, for objects which are
# the prototype of another object and will be used for a GuardShape. It
# includes a reference to the receiver object so we can eliminate redundant
# shape guards.
- name: ConstantProto
  gen_boilerplate: false

- name: BuiltinObject
  arguments:
    builtinObjectKind: BuiltinObjectKind
  result_type: Object
  possibly_calls: true

- name: SuperFunction
  operands:
    callee: Object
  result_type: Value
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: InitHomeObject
  operands:
    function: Object
    homeObject: Value
  result_type: Object
  alias_set: custom

# Return true if the object is definitely a TypedArray constructor, but not
# necessarily from the currently active realm. Return false if the object is
# not a TypedArray constructor or if it's a wrapper.
- name: IsTypedArrayConstructor
  operands:
    object: Object
  result_type: Boolean
  alias_set: none

# Load the JSValueTag on all platforms except ARM64. See the comments in
# MacroAssembler-arm64.h for the |cmpTag(Register, ImmTag)| method for why
# ARM64 doesn't use the raw JSValueTag, but instead a modified tag value. That
# modified tag value can't be directly compared against JSValueTag constants.
- name: LoadValueTag
  operands:
    value: Value
  result_type: Int32
  movable: true
  congruent_to: if_operands_equal
  alias_set: none

# Load the target object from a proxy wrapper. The target is stored in the
# proxy object's private slot. This operation is fallible if the proxy can
# be revoked.
- name: LoadWrapperTarget
  operands:
    object: Object
  arguments:
    fallible: bool
  result_type: Object
  movable: true
  congruent_to: custom
  # Can't use |AliasSet::None| because the target changes on navigation.
  # TODO: Investigate using a narrower or a custom alias set.
  alias_set: custom

# Guard the accessor shape is present on the object or its prototype chain.
- name: GuardHasGetterSetter
  operands:
    object: Object
  arguments:
    propId: jsid
    getterSetter: GetterSetter*
  result_type: Object
  guard: true
  movable: true
  possibly_calls: true
  congruent_to: custom
  alias_set: custom

- name: GuardIsExtensible
  operands:
    object: Object
  result_type: Object
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

- name: GuardInt32IsNonNegative
  operands:
    index: Int32
  result_type: Int32
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

- name: GuardInt32Range
  operands:
    input: Int32
  arguments:
    minimum: int32_t
    maximum: int32_t
  result_type: Int32
  guard: true
  movable: true
  congruent_to: if_operands_equal
  folds_to: custom
  alias_set: none

# Guard the input index is either greater than the dense initialized length of
# an object, or a hole element.
- name: GuardIndexIsNotDenseElement
  operands:
    object: Object
    index: Int32
  result_type: Int32
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Guard an array object's length can be updated successfully when adding an
# element at the input index.
- name: GuardIndexIsValidUpdateOrAdd
  operands:
    object: Object
    index: Int32
  result_type: Int32
  guard: true
  movable: true
  congruent_to: if_operands_equal
  alias_set: custom

# Add or update a sparse element of an ArrayObject or PlainObject. It's allowed
# for the sparse element to be already present on the object. It may also be an
# accessor property, so this instruction is always marked as effectful.
- name: CallAddOrUpdateSparseElement
  operands:
    object: Object
    index: Int32
    value: Value
  arguments:
    strict: bool
  possibly_calls: true

# Get a sparse element from an ArrayObject or PlainObject, possibly by calling
# an accessor property.
- name: CallGetSparseElement
  operands:
    object: Object
    index: Int32
  result_type: Value
  possibly_calls: true

- name: CallNativeGetElement
  operands:
    object: Object
    index: Int32
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ]