summaryrefslogtreecommitdiffstats
path: root/js/src/jit/MIROps.yaml
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/MIROps.yaml')
-rw-r--r--js/src/jit/MIROps.yaml3064
1 files changed, 3064 insertions, 0 deletions
diff --git a/js/src/jit/MIROps.yaml b/js/src/jit/MIROps.yaml
new file mode 100644
index 0000000000..fac9918429
--- /dev/null
+++ b/js/src/jit/MIROps.yaml
@@ -0,0 +1,3064 @@
+# 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
+#
+
+# 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: 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:
+ ins: 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: 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
+ clone: true
+
+- name: SameValue
+ operands:
+ left: Value
+ right: Value
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+ 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
+
+# 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
+
+# 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
+
+# Store a JS Value that can't be represented as an AnyRef pointer into an
+# object that holds the value (opaquely) as such a pointer.
+- name: WasmBoxValue
+ operands:
+ def: Value
+ result_type: RefOrNull
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: WasmAnyRefFromJSObject
+ operands:
+ def: Object
+ type_policy: none
+ result_type: RefOrNull
+ 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: 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: 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: Int32ToStringWithBase
+ operands:
+ input: Int32
+ base: Int32
+ result_type: String
+ movable: true
+ congruent_to: if_operands_equal
+ 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: 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: 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 also supports out-of-bounds access.
+- name: CharCodeAtMaybeOutOfBounds
+ operands:
+ string: String
+ index: Int32
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ # Strings are immutable, so there is no implicit dependency.
+ alias_set: none
+
+# Like CharCodeAtMaybeOutOfBounds, this operation also supports out-of-bounds access.
+- name: CharAtMaybeOutOfBounds
+ 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: FromCharCode
+ operands:
+ code: Int32
+ result_type: String
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+ can_recover: true
+ clone: true
+
+- name: FromCodePoint
+ operands:
+ codePoint: Int32
+ result_type: String
+ guard: true
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+ clone: 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: 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: 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:
+ envChain: Object
+ arguments:
+ name: PropertyName*
+ result_type: Value
+ possibly_calls: true
+
+- 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 value is null
+- name: WasmTrapIfNull
+ operands:
+ value: RefOrNull
+ arguments:
+ trap: wasm::Trap
+ bytecodeOffset: wasm::BytecodeOffset
+ 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
+ can_recover: true
+
+- name: RegExpSearcher
+ operands:
+ regexp: Object
+ string: String
+ lastIndex: Int32
+ result_type: Int32
+ possibly_calls: true
+ can_recover: true
+
+- name: RegExpExecMatch
+ operands:
+ regexp: Object
+ string: String
+ result_type: Value
+ possibly_calls: true
+ can_recover: false
+
+- name: RegExpExecTest
+ operands:
+ regexp: Object
+ string: String
+ result_type: Boolean
+ possibly_calls: true
+ can_recover: false
+
+- 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
+ 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
+ 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
+ # By default no, unless built as a recovered instruction.
+ can_recover: 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
+
+# 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
+
+- 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.
+
+- 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: 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: 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: 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: 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
+
+# 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: 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
+
+- name: HasClass
+ gen_boilerplate: false
+
+- name: GuardToClass
+ 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
+ valueOrReason: Value
+ arguments:
+ resolveKind: AsyncFunctionResolveKind
+ 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: 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: none
+
+- 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.
+- name: LoadWrapperTarget
+ operands:
+ object: Object
+ result_type: Object
+ movable: true
+ congruent_to: if_operands_equal
+ # 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
+ result_type: Value
+ possibly_calls: true
+
+- name: CallNativeGetElementSuper
+ operands:
+ object: Object
+ index: Int32
+ receiver: Value
+ result_type: Value
+ possibly_calls: true
+
+# Test if a native object has an own element (sparse or dense) at an index.
+- name: CallObjectHasSparseElement
+ operands:
+ object: Object
+ index: Int32
+ result_type: Boolean
+ guard: true
+ congruent_to: if_operands_equal
+ possibly_calls: true
+ alias_set: custom
+
+- name: BigIntAsIntN
+ operands:
+ bits: Int32
+ input: BigInt
+ result_type: BigInt
+ movable: true
+ congruent_to: if_operands_equal
+ possibly_calls: true
+ alias_set: none
+ can_recover: true
+ clone: true
+
+- name: BigIntAsUintN
+ operands:
+ bits: Int32
+ input: BigInt
+ result_type: BigInt
+ movable: true
+ congruent_to: if_operands_equal
+ possibly_calls: true
+ alias_set: none
+ can_recover: true
+ clone: true
+
+- name: GuardNonGCThing
+ operands:
+ input: Value
+ result_type: Value
+ guard: true
+ movable: true
+ congruent_to: if_operands_equal
+ folds_to: custom
+ alias_set: none
+
+- name: ToHashableNonGCThing
+ operands:
+ input: Value
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: ToHashableString
+ operands:
+ input: String
+ result_type: String
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+ possibly_calls: true
+
+- name: ToHashableValue
+ operands:
+ input: Value
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+ possibly_calls: true
+
+- name: HashNonGCThing
+ operands:
+ input: Value
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: HashString
+ operands:
+ input: String
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: HashSymbol
+ operands:
+ input: Symbol
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: HashBigInt
+ operands:
+ input: BigInt
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: none
+
+- name: HashObject
+ operands:
+ set: Object
+ input: Value
+ result_type: Int32
+ # In contrast to the previous hash operations, we can't move this
+ # instruction, because the hashcode is computed from the object's address,
+ # which can change when the object is moved by the GC.
+ movable: false
+ alias_set: none
+
+- name: HashValue
+ operands:
+ set: Object
+ input: Value
+ result_type: Int32
+ movable: false
+ alias_set: none
+
+- name: SetObjectHasNonBigInt
+ operands:
+ set: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: SetObjectHasBigInt
+ operands:
+ set: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: SetObjectHasValue
+ operands:
+ set: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: SetObjectHasValueVMCall
+ operands:
+ set: Object
+ value: Value
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+ possibly_calls: true
+
+- name: SetObjectSize
+ operands:
+ set: Object
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectHasNonBigInt
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectHasBigInt
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectHasValue
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectHasValueVMCall
+ operands:
+ map: Object
+ value: Value
+ result_type: Boolean
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+ possibly_calls: true
+
+- name: MapObjectGetNonBigInt
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectGetBigInt
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectGetValue
+ operands:
+ map: Object
+ value: Value
+ hash: Int32
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: MapObjectGetValueVMCall
+ operands:
+ map: Object
+ value: Value
+ result_type: Value
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+ possibly_calls: true
+
+- name: MapObjectSize
+ operands:
+ map: Object
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ alias_set: custom
+
+- name: WasmNeg
+ gen_boilerplate: false
+
+- name: WasmBinaryBitwise
+ gen_boilerplate: false
+
+- name: WasmLoadInstance
+ gen_boilerplate: false
+
+- name: WasmStoreInstance
+ gen_boilerplate: false
+
+- name: WasmHeapBase
+ gen_boilerplate: false
+
+- name: WasmBoundsCheck
+ gen_boilerplate: false
+
+- name: WasmExtendU32Index
+ operands:
+ input: Int32
+ result_type: Int64
+ movable: true
+ congruent_to: if_operands_equal
+ folds_to: custom
+ type_policy: none
+ alias_set: none
+
+- name: WasmWrapU32Index
+ operands:
+ input: Int64
+ result_type: Int32
+ movable: true
+ congruent_to: if_operands_equal
+ folds_to: custom
+ type_policy: none
+ alias_set: none
+
+- name: WasmAddOffset
+ gen_boilerplate: false
+
+- name: WasmAlignmentCheck
+ gen_boilerplate: false
+
+- name: WasmLoad
+ gen_boilerplate: false
+
+- name: WasmStore
+ gen_boilerplate: false
+
+- name: AsmJSLoadHeap
+ gen_boilerplate: false
+
+- name: AsmJSStoreHeap
+ gen_boilerplate: false
+
+- name: WasmFence
+ guard: true
+ alias_set: none
+ clone: true
+
+- name: WasmCompareExchangeHeap
+ gen_boilerplate: false
+
+- name: WasmAtomicExchangeHeap
+ gen_boilerplate: false
+
+- name: WasmAtomicBinopHeap
+ gen_boilerplate: false
+
+- name: WasmLoadInstanceDataField
+ gen_boilerplate: false
+
+- name: WasmLoadGlobalCell
+ gen_boilerplate: false
+
+- name: WasmLoadTableElement
+ gen_boilerplate: false
+
+- name: WasmStoreInstanceDataField
+ gen_boilerplate: false
+
+- name: WasmStoreGlobalCell
+ gen_boilerplate: false
+
+- name: WasmStoreStackResult
+ gen_boilerplate: false
+
+- name: WasmDerivedPointer
+ gen_boilerplate: false
+
+- name: WasmDerivedIndexPointer
+ gen_boilerplate: false
+
+- name: WasmStoreRef
+ gen_boilerplate: false
+
+- name: WasmPostWriteBarrier
+ gen_boilerplate: false
+
+- name: WasmParameter
+ gen_boilerplate: false
+
+- name: WasmReturn
+ gen_boilerplate: false
+
+- name: WasmReturnVoid
+ gen_boilerplate: false
+
+- name: WasmStackArg
+ gen_boilerplate: false
+
+- name: WasmRegisterResult
+ gen_boilerplate: false
+
+- name: WasmFloatRegisterResult
+ gen_boilerplate: false
+
+- name: WasmRegister64Result
+ gen_boilerplate: false
+
+- name: WasmStackResultArea
+ gen_boilerplate: false
+
+- name: WasmStackResult
+ gen_boilerplate: false
+
+- name: WasmCallCatchable
+ gen_boilerplate: false
+
+- name: WasmCallUncatchable
+ gen_boilerplate: false
+
+- name: WasmCallLandingPrePad
+ gen_boilerplate: false
+
+- name: WasmSelect
+ gen_boilerplate: false
+
+- name: WasmReinterpret
+ gen_boilerplate: false
+
+- name: Rotate
+ gen_boilerplate: false
+
+- name: WasmBinarySimd128
+ gen_boilerplate: false
+
+- name: WasmBinarySimd128WithConstant
+ gen_boilerplate: false
+
+# (v128, i32) -> v128 effect-free shift operations.
+- name: WasmShiftSimd128
+ operands:
+ lhs: Simd128
+ rhs: Int32
+ arguments:
+ simdOp: wasm::SimdOp
+ type_policy: none
+ result_type: Simd128
+ movable: true
+ congruent_to: custom
+ alias_set: none
+ clone: true
+
+# (v128, v128, mask) -> v128 effect-free operation.
+- name: WasmShuffleSimd128
+ operands:
+ lhs: Simd128
+ rhs: Simd128
+ arguments:
+ shuffle: SimdShuffle
+ type_policy: none
+ result_type: Simd128
+ movable: true
+ congruent_to: custom
+ alias_set: none
+ clone: true
+
+- name: WasmReplaceLaneSimd128
+ gen_boilerplate: false
+
+- name: WasmUnarySimd128
+ operands:
+ src: Simd128
+ arguments:
+ simdOp: wasm::SimdOp
+ type_policy: none
+ result_type: Simd128
+ movable: true
+ congruent_to: custom
+ alias_set: none
+ clone: true
+
+- name: WasmTernarySimd128
+ gen_boilerplate: false
+
+- name: WasmScalarToSimd128
+ gen_boilerplate: false
+
+- name: WasmReduceSimd128
+ gen_boilerplate: false
+
+- name: WasmLoadLaneSimd128
+ gen_boilerplate: false
+
+- name: WasmStoreLaneSimd128
+ gen_boilerplate: false
+
+- name: UnreachableResult
+ gen_boilerplate: false
+
+- name: IonToWasmCall
+ gen_boilerplate: false
+
+- name: WasmLoadField
+ gen_boilerplate: false
+
+- name: WasmLoadFieldKA
+ gen_boilerplate: false
+
+- name: WasmStoreFieldKA
+ gen_boilerplate: false
+
+- name: WasmStoreFieldRefKA
+ gen_boilerplate: false
+
+- name: WasmGcObjectIsSubtypeOfConcrete
+ gen_boilerplate: false
+
+- name: WasmGcObjectIsSubtypeOfAbstract
+ gen_boilerplate: false
+
+#ifdef FUZZING_JS_FUZZILLI
+- name: FuzzilliHash
+ gen_boilerplate: false
+
+- name: FuzzilliHashStore
+ gen_boilerplate: false
+#endif